taskjuggler 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +119 -0
- data/benchmarks/allocatedSlots.tjp +1602 -0
- data/benchmarks/booking.tjp +40 -30
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/css/tjmanual.css +0 -0
- data/{test/TestSuite/Scheduler/Correct → benchmarks}/css/tjreport.css +1 -0
- data/benchmarks/gantt.tjp +57 -0
- data/benchmarks/htmltaskreport.tjp +26 -1
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/details.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-green.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-red.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-yellow.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resource.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resourcegroup.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/task.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/taskgroup.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-down.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-flat.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-up.png +0 -0
- data/benchmarks/profile.clt +36082 -0
- data/benchmarks/profile.html +58182 -0
- data/benchmarks/runbench.rb +6 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/scripts/wz_tooltip.js +0 -0
- data/doc/AppConfig.html +85 -37
- data/doc/Arguments.html +11 -1
- data/doc/CHANGELOG.html +131 -2
- data/doc/COPYING.html +11 -1
- data/doc/Object.html +12 -3
- data/doc/README.html +11 -1
- data/doc/RuntimeConfig.html +11 -1
- data/doc/String.html +11 -1
- data/doc/StringIO.html +11 -1
- data/doc/TaskJuggler.html +250 -219
- data/doc/TaskJuggler/Account.html +11 -1
- data/doc/TaskJuggler/AccountAttribute.html +11 -1
- data/doc/TaskJuggler/AccountScenario.html +11 -1
- data/doc/TaskJuggler/Allocation.html +11 -1
- data/doc/TaskJuggler/AllocationAttribute.html +11 -1
- data/doc/TaskJuggler/AttributeBase.html +11 -1
- data/doc/TaskJuggler/AttributeDefinition.html +11 -1
- data/doc/TaskJuggler/BatchProcessor.html +11 -1
- data/doc/TaskJuggler/Booking.html +11 -1
- data/doc/TaskJuggler/BookingListAttribute.html +11 -1
- data/doc/TaskJuggler/BooleanAttribute.html +11 -1
- data/doc/TaskJuggler/CSVFile.html +12 -2
- data/doc/TaskJuggler/CellSettingPattern.html +11 -1
- data/doc/TaskJuggler/CellSettingPatternList.html +11 -1
- data/doc/TaskJuggler/Charge.html +11 -1
- data/doc/TaskJuggler/ChargeListAttribute.html +11 -1
- data/doc/TaskJuggler/ChargeSet.html +11 -1
- data/doc/TaskJuggler/ChargeSetListAttribute.html +11 -1
- data/doc/TaskJuggler/CollisionDetector.html +1063 -0
- data/doc/TaskJuggler/ColumnListAttribute.html +11 -1
- data/doc/TaskJuggler/ColumnTable.html +11 -1
- data/doc/TaskJuggler/Daemon.html +11 -1
- data/doc/TaskJuggler/{OnShiftCache.html → DataCache.html} +127 -139
- data/doc/TaskJuggler/DataCacheEntry.html +711 -0
- data/doc/TaskJuggler/DateAttribute.html +11 -1
- data/doc/TaskJuggler/DefinitionListAttribute.html +11 -1
- data/doc/TaskJuggler/DependencyListAttribute.html +11 -1
- data/doc/TaskJuggler/DurationAttribute.html +16 -5
- data/doc/TaskJuggler/FileList.html +11 -1
- data/doc/TaskJuggler/FileRecord.html +11 -1
- data/doc/TaskJuggler/FixnumAttribute.html +19 -9
- data/doc/TaskJuggler/FlagListAttribute.html +29 -19
- data/doc/TaskJuggler/FloatAttribute.html +23 -13
- data/doc/TaskJuggler/FormatListAttribute.html +19 -9
- data/doc/TaskJuggler/GanttChart.html +94 -133
- data/doc/TaskJuggler/GanttContainer.html +11 -1
- data/doc/TaskJuggler/GanttHeader.html +11 -1
- data/doc/TaskJuggler/GanttHeaderScaleItem.html +11 -1
- data/doc/TaskJuggler/GanttLine.html +11 -1
- data/doc/TaskJuggler/GanttLoadStack.html +11 -1
- data/doc/TaskJuggler/GanttMilestone.html +11 -1
- data/doc/TaskJuggler/GanttRouter.html +247 -596
- data/doc/TaskJuggler/GanttTaskBar.html +11 -1
- data/doc/TaskJuggler/HTMLDocument.html +11 -1
- data/doc/TaskJuggler/HTMLGraphics.html +11 -1
- data/doc/TaskJuggler/Interval.html +11 -1
- data/doc/TaskJuggler/IntervalListAttribute.html +33 -23
- data/doc/TaskJuggler/JobInfo.html +11 -1
- data/doc/TaskJuggler/Journal.html +11 -1
- data/doc/TaskJuggler/JournalEntry.html +11 -1
- data/doc/TaskJuggler/JournalEntryList.html +11 -1
- data/doc/TaskJuggler/KeywordArray.html +11 -1
- data/doc/TaskJuggler/KeywordDocumentation.html +16 -6
- data/doc/TaskJuggler/Limits.html +11 -1
- data/doc/TaskJuggler/Limits/Limit.html +11 -1
- data/doc/TaskJuggler/LimitsAttribute.html +24 -14
- data/doc/TaskJuggler/ListAttributeBase.html +11 -1
- data/doc/TaskJuggler/Log.html +11 -1
- data/doc/TaskJuggler/LogFile.html +11 -1
- data/doc/TaskJuggler/LogicalAttribute.html +11 -1
- data/doc/TaskJuggler/LogicalExpression.html +11 -1
- data/doc/TaskJuggler/LogicalExpressionAttribute.html +19 -9
- data/doc/TaskJuggler/LogicalFlag.html +11 -1
- data/doc/TaskJuggler/LogicalFunction.html +11 -1
- data/doc/TaskJuggler/LogicalOperation.html +11 -1
- data/doc/TaskJuggler/Macro.html +11 -1
- data/doc/TaskJuggler/MacroTable.html +11 -1
- data/doc/TaskJuggler/ManagerResponsibilities.html +11 -1
- data/doc/TaskJuggler/ManagerStatusRecord.html +11 -1
- data/doc/TaskJuggler/Message.html +11 -1
- data/doc/TaskJuggler/MessageHandler.html +11 -1
- data/doc/TaskJuggler/Navigator.html +12 -2
- data/doc/TaskJuggler/NavigatorElement.html +11 -1
- data/doc/TaskJuggler/NikuProject.html +11 -1
- data/doc/TaskJuggler/NikuReport.html +11 -1
- data/doc/TaskJuggler/NikuResource.html +11 -1
- data/doc/TaskJuggler/NodeListAttribute.html +17 -7
- data/doc/TaskJuggler/PlaceHolderCell.html +722 -0
- data/doc/TaskJuggler/ProcessIntercom.html +11 -1
- data/doc/TaskJuggler/ProcessIntercomIface.html +11 -1
- data/doc/TaskJuggler/Project.html +587 -500
- data/doc/TaskJuggler/ProjectBroker.html +11 -1
- data/doc/TaskJuggler/ProjectBrokerIface.html +11 -1
- data/doc/TaskJuggler/ProjectFileParser.html +205 -192
- data/doc/TaskJuggler/ProjectFileScanner.html +230 -207
- data/doc/TaskJuggler/ProjectRecord.html +11 -1
- data/doc/TaskJuggler/ProjectServer.html +11 -1
- data/doc/TaskJuggler/ProjectServerIface.html +11 -1
- data/doc/TaskJuggler/PropertyAttribute.html +19 -9
- data/doc/TaskJuggler/PropertyList.html +95 -83
- data/doc/TaskJuggler/PropertySet.html +11 -1
- data/doc/TaskJuggler/PropertyTreeNode.html +11 -1
- data/doc/TaskJuggler/Query.html +234 -232
- data/doc/TaskJuggler/RTFHandlers.html +11 -1
- data/doc/TaskJuggler/RTFNavigator.html +11 -1
- data/doc/TaskJuggler/RTFQuery.html +11 -1
- data/doc/TaskJuggler/RTFReport.html +11 -1
- data/doc/TaskJuggler/RTFReportLink.html +11 -1
- data/doc/TaskJuggler/RTFWithQuerySupport.html +11 -1
- data/doc/TaskJuggler/RealFormat.html +12 -2
- data/doc/TaskJuggler/RealFormatAttribute.html +15 -5
- data/doc/TaskJuggler/ReferenceAttribute.html +38 -28
- data/doc/TaskJuggler/Report.html +96 -113
- data/doc/TaskJuggler/ReportBase.html +161 -152
- data/doc/TaskJuggler/ReportContext.html +11 -1
- data/doc/TaskJuggler/ReportServer.html +59 -48
- data/doc/TaskJuggler/ReportServerIface.html +51 -41
- data/doc/TaskJuggler/ReportServerRecord.html +11 -1
- data/doc/TaskJuggler/ReportServlet.html +11 -1
- data/doc/TaskJuggler/ReportTable.html +46 -25
- data/doc/TaskJuggler/ReportTableCell.html +296 -275
- data/doc/TaskJuggler/ReportTableColumn.html +14 -4
- data/doc/TaskJuggler/ReportTableLegend.html +11 -1
- data/doc/TaskJuggler/ReportTableLine.html +19 -7
- data/doc/TaskJuggler/Resource.html +12 -2
- data/doc/TaskJuggler/ResourceListAttribute.html +40 -30
- data/doc/TaskJuggler/ResourceListRE.html +11 -1
- data/doc/TaskJuggler/ResourceScenario.html +708 -565
- data/doc/TaskJuggler/RichText.html +54 -36
- data/doc/TaskJuggler/RichTextAttribute.html +31 -21
- data/doc/TaskJuggler/RichTextDocument.html +11 -1
- data/doc/TaskJuggler/RichTextElement.html +11 -1
- data/doc/TaskJuggler/RichTextFunctionExample.html +11 -1
- data/doc/TaskJuggler/RichTextFunctionHandler.html +11 -1
- data/doc/TaskJuggler/RichTextImage.html +11 -1
- data/doc/TaskJuggler/RichTextIntermediate.html +81 -71
- data/doc/TaskJuggler/RichTextParser.html +88 -33
- data/doc/TaskJuggler/RichTextScanner.html +45 -35
- data/doc/TaskJuggler/RichTextSnip.html +11 -1
- data/doc/TaskJuggler/RichTextSyntaxRules.html +436 -389
- data/doc/TaskJuggler/Scenario.html +11 -1
- data/doc/TaskJuggler/ScenarioData.html +11 -1
- data/doc/TaskJuggler/ScenarioListAttribute.html +23 -13
- data/doc/TaskJuggler/Scoreboard.html +92 -73
- data/doc/TaskJuggler/SheetHandlerBase.html +11 -1
- data/doc/TaskJuggler/SheetReceiver.html +11 -1
- data/doc/TaskJuggler/SheetSender.html +11 -1
- data/doc/TaskJuggler/Shift.html +11 -1
- data/doc/TaskJuggler/ShiftAssignment.html +11 -1
- data/doc/TaskJuggler/ShiftAssignments.html +11 -1
- data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +24 -14
- data/doc/TaskJuggler/ShiftScenario.html +11 -1
- data/doc/TaskJuggler/SimpleQueryExpander.html +11 -1
- data/doc/TaskJuggler/SortListAttribute.html +21 -11
- data/doc/TaskJuggler/SourceFileInfo.html +11 -1
- data/doc/TaskJuggler/StatusSheetReceiver.html +11 -1
- data/doc/TaskJuggler/StatusSheetReport.html +11 -1
- data/doc/TaskJuggler/StatusSheetSender.html +112 -11
- data/doc/TaskJuggler/StringAttribute.html +23 -13
- data/doc/TaskJuggler/SymbolAttribute.html +19 -9
- data/doc/TaskJuggler/SyntaxReference.html +80 -71
- data/doc/TaskJuggler/TOCEntry.html +11 -1
- data/doc/TaskJuggler/TSResourceRecord.html +11 -1
- data/doc/TaskJuggler/TSTaskRecord.html +11 -1
- data/doc/TaskJuggler/TableColumnDefinition.html +11 -1
- data/doc/TaskJuggler/TableOfContents.html +11 -1
- data/doc/TaskJuggler/TableReport.html +422 -411
- data/doc/TaskJuggler/Task.html +11 -1
- data/doc/TaskJuggler/TaskDependency.html +11 -1
- data/doc/TaskJuggler/TaskListAttribute.html +33 -23
- data/doc/TaskJuggler/TaskListRE.html +11 -1
- data/doc/TaskJuggler/TaskScenario.html +2007 -1919
- data/doc/TaskJuggler/TextFormatter.html +11 -1
- data/doc/TaskJuggler/TextParser.html +421 -612
- data/doc/TaskJuggler/TextParser/Pattern.html +410 -211
- data/doc/TaskJuggler/TextParser/Rule.html +224 -152
- data/doc/TaskJuggler/TextParser/StackElement.html +190 -28
- data/doc/TaskJuggler/TextParser/State.html +989 -0
- data/doc/TaskJuggler/TextParser/StateTransition.html +782 -0
- data/doc/TaskJuggler/TextParser/TextParserResultArray.html +25 -14
- data/doc/TaskJuggler/TextParser/TokenDoc.html +11 -1
- data/doc/TaskJuggler/TextReport.html +11 -1
- data/doc/TaskJuggler/TextScanner.html +285 -273
- data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +17 -7
- data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +24 -14
- data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +11 -1
- data/doc/TaskJuggler/TextScanner/StreamHandle.html +64 -52
- data/doc/TaskJuggler/TimeSheet.html +11 -1
- data/doc/TaskJuggler/TimeSheetReceiver.html +11 -1
- data/doc/TaskJuggler/TimeSheetRecord.html +11 -1
- data/doc/TaskJuggler/TimeSheetReport.html +11 -1
- data/doc/TaskJuggler/TimeSheetSender.html +11 -1
- data/doc/TaskJuggler/TimeSheetSummary.html +11 -1
- data/doc/TaskJuggler/TimeSheets.html +11 -1
- data/doc/TaskJuggler/Tj3AppBase.html +11 -1
- data/doc/TaskJuggler/Tj3Client.html +11 -1
- data/doc/TaskJuggler/Tj3Daemon.html +11 -1
- data/doc/TaskJuggler/Tj3SheetAppBase.html +11 -1
- data/doc/TaskJuggler/Tj3SsReceiver.html +11 -1
- data/doc/TaskJuggler/Tj3SsSender.html +11 -1
- data/doc/TaskJuggler/Tj3TsReceiver.html +11 -1
- data/doc/TaskJuggler/Tj3TsSender.html +11 -1
- data/doc/TaskJuggler/Tj3TsSummary.html +11 -1
- data/doc/TaskJuggler/TjException.html +11 -1
- data/doc/TaskJuggler/TjTime.html +474 -324
- data/doc/TaskJuggler/TjpExample.html +11 -1
- data/doc/TaskJuggler/TjpExportRE.html +11 -1
- data/doc/TaskJuggler/TjpSyntaxRules.html +3731 -3662
- data/doc/TaskJuggler/URLParameter.html +11 -1
- data/doc/TaskJuggler/UserManual.html +11 -1
- data/doc/TaskJuggler/VimSyntax.html +11 -1
- data/doc/TaskJuggler/WebServer.html +11 -1
- data/doc/TaskJuggler/WorkingHours.html +295 -221
- data/doc/TaskJuggler/WorkingHoursAttribute.html +11 -1
- data/doc/TaskJuggler/XMLBlob.html +11 -1
- data/doc/TaskJuggler/XMLComment.html +11 -1
- data/doc/TaskJuggler/XMLDocument.html +11 -1
- data/doc/TaskJuggler/XMLElement.html +11 -1
- data/doc/TaskJuggler/XMLNamedText.html +11 -1
- data/doc/TaskJuggler/XMLText.html +11 -1
- data/doc/index.html +694 -624
- data/doc/lib/AppConfig_rb.html +1 -1
- data/doc/lib/Attributes_rb.html +1 -1
- data/doc/lib/Booking_rb.html +1 -1
- data/doc/lib/DataCache_rb.html +69 -0
- data/doc/lib/KeywordDocumentation_rb.html +1 -1
- data/doc/lib/ProjectFileParser_rb.html +1 -1
- data/doc/lib/ProjectFileScanner_rb.html +1 -1
- data/doc/lib/Project_rb.html +1 -1
- data/doc/lib/PropertyList_rb.html +1 -1
- data/doc/lib/Query_rb.html +1 -1
- data/doc/lib/RealFormat_rb.html +1 -1
- data/doc/lib/ResourceScenario_rb.html +1 -1
- data/doc/lib/Resource_rb.html +1 -1
- data/doc/lib/RichTextParser_rb.html +1 -1
- data/doc/lib/RichTextScanner_rb.html +1 -1
- data/doc/lib/RichTextSyntaxRules_rb.html +1 -1
- data/doc/lib/RichText_rb.html +1 -1
- data/doc/lib/Scoreboard_rb.html +1 -1
- data/doc/lib/StatusSheetSender_rb.html +1 -1
- data/doc/lib/SyntaxReference_rb.html +1 -1
- data/doc/lib/TaskJuggler_rb.html +1 -1
- data/doc/lib/TaskScenario_rb.html +3 -1
- data/doc/lib/TextParser/Pattern_rb.html +3 -1
- data/doc/lib/TextParser/Rule_rb.html +3 -1
- data/doc/lib/TextParser/StackElement_rb.html +3 -1
- data/doc/lib/TextParser/State_rb.html +65 -0
- data/doc/lib/TextParser_rb.html +1 -1
- data/doc/lib/TextScanner_rb.html +1 -1
- data/doc/lib/Tj3Config_rb.html +1 -1
- data/doc/lib/TjTime_rb.html +1 -1
- data/doc/lib/TjpSyntaxRules_rb.html +1 -1
- data/doc/lib/WorkingHours_rb.html +3 -1
- data/doc/lib/daemon/ReportServer_rb.html +1 -1
- data/doc/lib/reports/CSVFile_rb.html +1 -1
- data/doc/lib/reports/CollisionDetector_rb.html +67 -0
- data/doc/lib/reports/GanttChart_rb.html +1 -1
- data/doc/lib/reports/GanttRouter_rb.html +3 -1
- data/doc/lib/reports/Navigator_rb.html +1 -1
- data/doc/lib/reports/ReportBase_rb.html +1 -1
- data/doc/lib/reports/ReportTableCell_rb.html +1 -1
- data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
- data/doc/lib/reports/ReportTableLine_rb.html +1 -1
- data/doc/lib/reports/ReportTable_rb.html +1 -1
- data/doc/lib/reports/Report_rb.html +1 -1
- data/doc/lib/reports/TableReport_rb.html +1 -1
- data/doc/lib/taskjuggler3_rb.html +1 -1
- data/examples/tutorial.tjp +1 -2
- data/lib/AppConfig.rb +10 -4
- data/lib/Attributes.rb +4 -4
- data/lib/DataCache.rb +124 -0
- data/lib/KeywordDocumentation.rb +5 -5
- data/lib/Project.rb +54 -10
- data/lib/ProjectFileParser.rb +10 -9
- data/lib/ProjectFileScanner.rb +38 -25
- data/lib/PropertyList.rb +6 -4
- data/lib/Query.rb +0 -8
- data/lib/RealFormat.rb +1 -1
- data/lib/Resource.rb +1 -1
- data/lib/ResourceScenario.rb +96 -31
- data/lib/RichText.rb +17 -5
- data/lib/RichTextParser.rb +22 -9
- data/lib/RichTextScanner.rb +34 -34
- data/lib/RichTextSyntaxRules.rb +41 -36
- data/lib/Scoreboard.rb +16 -7
- data/lib/StatusSheetSender.rb +63 -0
- data/lib/SyntaxReference.rb +9 -10
- data/lib/TaskJuggler.rb +28 -4
- data/lib/TaskScenario.rb +66 -19
- data/lib/TextParser.rb +219 -384
- data/lib/TextParser/Pattern.rb +168 -49
- data/lib/TextParser/Rule.rb +33 -17
- data/lib/TextParser/StackElement.rb +42 -2
- data/lib/TextParser/State.rb +175 -0
- data/lib/TextScanner.rb +19 -15
- data/lib/Tj3Config.rb +1 -1
- data/lib/TjTime.rb +111 -3
- data/lib/TjpSyntaxRules.rb +122 -66
- data/lib/WorkingHours.rb +91 -186
- data/lib/daemon/ReportServer.rb +3 -2
- data/lib/reports/CSVFile.rb +1 -1
- data/lib/reports/CollisionDetector.rb +177 -0
- data/lib/reports/GanttChart.rb +25 -41
- data/lib/reports/GanttRouter.rb +104 -233
- data/lib/reports/Navigator.rb +1 -1
- data/lib/reports/Report.rb +9 -33
- data/lib/reports/ReportBase.rb +0 -1
- data/lib/reports/ReportTable.rb +19 -8
- data/lib/reports/ReportTableCell.rb +61 -25
- data/lib/reports/ReportTableColumn.rb +2 -2
- data/lib/reports/ReportTableLine.rb +4 -2
- data/lib/reports/TableReport.rb +1 -0
- data/lib/taskjuggler3.rb +0 -1
- data/manual/Installation +7 -3
- data/manual/Intro +12 -10
- data/manual/The_TaskJuggler_Syntax +4 -4
- data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/genrefs +1 -1
- data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -4
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -22
- data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +32 -24
- data/test/TestSuite/CSV-Reports/weekly-Reference.csv +13 -0
- data/test/TestSuite/CSV-Reports/weekly.tjp +9 -0
- data/test/TestSuite/HTML-Reports/css/tjreport.css +7 -2
- data/test/TestSuite/HTML-Reports/depArrows.html +839 -830
- data/test/TestSuite/HTML-Reports/depArrows.tjp +12 -12
- data/test/TestSuite/HTML-Reports/profile.html +37581 -0
- data/test/TestSuite/ReportGenerator/Errors/no_report_defined.tjp +7 -0
- data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.tjp +1 -1
- data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/missing-reports +2 -0
- data/test/TestSuite/StatusSheets/run +2 -0
- data/test/TestSuite/Syntax/Correct/Booking.tjp +13 -5
- data/test/TestSuite/Syntax/Correct/ResourceRoot.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/RollupResource.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/include_before_project.tjp +2 -0
- data/test/TestSuite/Syntax/Errors/no_reduce.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/unsupported_token.tjp +1 -1
- data/test/TestSuite/TimeSheets/run +1 -1
- data/test/test_CSV-Reports.rb +2 -4
- data/test/test_CollisionDetector.rb +85 -0
- data/test/test_Project.rb +2 -2
- data/test/test_ProjectFileScanner.rb +73 -31
- data/test/test_Query.rb +2 -2
- data/test/test_ReportGenerator.rb +1 -1
- data/test/test_RichText.rb +4 -4
- data/test/test_WorkingHours.rb +150 -11
- metadata +75 -67
- data/test/TestSuite/ReportGenerator/Errors/css/tjreport.css +0 -407
- data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.html +0 -26
- data/test/TestSuite/Scheduler/Correct/Allocate.html +0 -3210
- data/test/TestSuite/Scheduler/Correct/Container.html +0 -349
- data/test/TestSuite/Scheduler/Correct/Limits.html +0 -4964
- data/test/TestSuite/Scheduler/Correct/Shift.html +0 -1719
- data/test/TestSuite/Scheduler/Correct/Shift2.html +0 -476
- data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +0 -66
- data/test/TestSuite/Scheduler/Correct/icons/details.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/resource.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/task.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-down.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-flat.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-up.png +0 -0
- data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/Scheduler/Errors/css/tjmanual.css +0 -66
- data/test/TestSuite/Scheduler/Errors/css/tjreport.css +0 -407
- data/test/TestSuite/Scheduler/Errors/icons/details.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/flag-green.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/flag-red.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/resource.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/task.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/taskgroup.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/trend-down.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/trend-flat.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/trend-up.png +0 -0
- data/test/TestSuite/Scheduler/Errors/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/StatusSheets/resrep.tji +0 -7
- data/test/TestSuite/StatusSheets/tj3d.log +0 -312
- data/test/TestSuite/Syntax/Correct/Managers.html +0 -263
- data/test/TestSuite/TimeSheets/acceptable_intervals +0 -1
- data/test/TestSuite/TimeSheets/statussheets.log +0 -1
data/lib/WorkingHours.rb
CHANGED
@@ -11,140 +11,31 @@
|
|
11
11
|
#
|
12
12
|
|
13
13
|
require 'Interval'
|
14
|
+
require 'Scoreboard'
|
14
15
|
|
15
16
|
class TaskJuggler
|
16
17
|
|
17
|
-
# This cache class is used to speedup accesses to the frequently used
|
18
|
-
# WorkingHours::onShift? function. It saves the result the first time the
|
19
|
-
# function is called for a particular date and working hour set and returns
|
20
|
-
# it on subsequent calls again. Each partucular set of working hours needs
|
21
|
-
# its separate cache. The OnShiftCache object is shared amongst all
|
22
|
-
# WorkingHours objects so that WorkingHours objects with identical working
|
23
|
-
# hours can share the cache.
|
24
|
-
class OnShiftCache
|
25
|
-
|
26
|
-
# Create the OnShiftCache object. There should be only one for the
|
27
|
-
# application.
|
28
|
-
def initialize
|
29
|
-
@caches = []
|
30
|
-
@workingHoursTable = []
|
31
|
-
# The cache is an array with entries for each date. To minimize the
|
32
|
-
# necessary storage space, we need to guess the smallest used date
|
33
|
-
# (which gets index 0 then) and the smallest distance between dates.
|
34
|
-
@minDate = nil
|
35
|
-
# We assume a timing resolution of 1 hour (the TaskJuggler default)
|
36
|
-
# first.
|
37
|
-
@minDateDelta = 60 * 60
|
38
|
-
end
|
39
|
-
|
40
|
-
# Register the WorkingHours object with the caches. The function will
|
41
|
-
# return the actual cache used for this particular set of working hours.
|
42
|
-
# The WorkingHours object may not change its working hours after this
|
43
|
-
# call. The returned cache reference is used as a handle for subsequent
|
44
|
-
# OnShiftCache::set and OnShiftCache::get calls.
|
45
|
-
def register(wh)
|
46
|
-
# Search the list of already registered caches for an identical set of
|
47
|
-
# WorkingHours. In case one is found, return the reference to this
|
48
|
-
# cache.
|
49
|
-
@workingHoursTable.length.times do |i|
|
50
|
-
if @workingHoursTable[i] == wh
|
51
|
-
return @caches[i]
|
52
|
-
end
|
53
|
-
end
|
54
|
-
# If this is a new set of WorkingHours we create a new cache for it.
|
55
|
-
@workingHoursTable << WorkingHours.new(wh)
|
56
|
-
@caches << []
|
57
|
-
@caches.last
|
58
|
-
end
|
59
|
-
|
60
|
-
# Set the +value+ for a given +cache+ and +date+.
|
61
|
-
def set(cache, date, value)
|
62
|
-
cache[dateToIndex(date)] = value
|
63
|
-
end
|
64
|
-
|
65
|
-
# Get the value for a given +cache+ and +date+.
|
66
|
-
def get(cache, date)
|
67
|
-
cache[dateToIndex(date)]
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
# When the @minDate or @minDateDelta values need to be changed, we have to
|
73
|
-
# clear all the caches again.
|
74
|
-
def resetCaches
|
75
|
-
@caches.each { |c| c.clear }
|
76
|
-
end
|
77
|
-
|
78
|
-
# Convert a TjTime +date+ to an index in the cache Array. To optimize the
|
79
|
-
# size of the cache, we have to guess the smallest used date and the
|
80
|
-
# regular distance between the date values. If we have to correct these
|
81
|
-
# guessed values, we have to clear the caches.
|
82
|
-
def dateToIndex(date)
|
83
|
-
if @minDate.nil? || date < @minDate
|
84
|
-
@minDate = date
|
85
|
-
resetCaches
|
86
|
-
end
|
87
|
-
startDate = date - @minDate
|
88
|
-
div, mod = startDate.divmod(@minDateDelta)
|
89
|
-
if mod != 0
|
90
|
-
resetCaches
|
91
|
-
# We have to guess the timingresolution of the project here. Possible
|
92
|
-
# values are 5, 10, 15, 20, 30 or 60 minutes.
|
93
|
-
case @minDateDelta / 60
|
94
|
-
when 60
|
95
|
-
@minDateDelta = 30
|
96
|
-
when 30
|
97
|
-
@minDateDelta = 20
|
98
|
-
when 20
|
99
|
-
@minDateDelta = 15
|
100
|
-
when 15
|
101
|
-
@minDateDelta = 10
|
102
|
-
when 10
|
103
|
-
@minDateDelta = 5
|
104
|
-
else
|
105
|
-
raise "Illegal timing resolution!"
|
106
|
-
end
|
107
|
-
@minDateDelta *= 60
|
108
|
-
div = startDate / @minDateDelta
|
109
|
-
end
|
110
|
-
|
111
|
-
div
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
18
|
# Class to store the working hours for each day of the week. The working hours
|
117
19
|
# are stored as Arrays of Fixnum intervals for each day of the week. A day off
|
118
20
|
# is modelled as empty Array for that week day. The start end end times of
|
119
21
|
# each working period are stored as seconds after midnight.
|
120
22
|
class WorkingHours
|
121
23
|
|
122
|
-
attr_reader :days
|
123
|
-
|
124
|
-
|
125
|
-
# All WorkingHours objects share the same cache to speedup the onShift?
|
126
|
-
# method.
|
127
|
-
@@onShiftCache = OnShiftCache.new
|
24
|
+
attr_reader :days, :startDate, :endDate, :slotDuration, :timezone,
|
25
|
+
:scoreboard
|
128
26
|
|
129
27
|
# Create a new WorkingHours object. The method accepts a reference to an
|
130
28
|
# existing WorkingHours object in +wh+. When it's present, the new object
|
131
|
-
# will be a deep copy of the given object.
|
132
|
-
|
29
|
+
# will be a deep copy of the given object. The Scoreboard object is _not_
|
30
|
+
# deep copied. It will be copied on write.
|
31
|
+
def initialize(arg1 = nil, startDate = nil, endDate = nil)
|
133
32
|
# One entry for every day of the week. Sunday === 0.
|
134
33
|
@days = Array.new(7, [])
|
135
|
-
@
|
34
|
+
@scoreboard = nil
|
136
35
|
|
137
|
-
if
|
138
|
-
# Create a
|
139
|
-
|
140
|
-
# Set the default working hours. Monday to Friday 9am - 12pm, 1pm - 6pm.
|
141
|
-
# Saturday and Sunday are days off.
|
142
|
-
1.upto(5) do |day|
|
143
|
-
@days[day] = [ [ 9 * 60 * 60, 12 * 60 * 60 ],
|
144
|
-
[ 13 * 60 * 60, 18 * 60 * 60 ] ]
|
145
|
-
end
|
146
|
-
else
|
147
|
-
# Copy the values from the given object.
|
36
|
+
if arg1.is_a?(WorkingHours)
|
37
|
+
# Create a copy of the passed WorkingHours object.
|
38
|
+
wh = arg1
|
148
39
|
@timezone = wh.timezone
|
149
40
|
7.times do |day|
|
150
41
|
hours = []
|
@@ -153,13 +44,37 @@ class TaskJuggler
|
|
153
44
|
end
|
154
45
|
setWorkingHours(day, hours)
|
155
46
|
end
|
47
|
+
@startDate = wh.startDate
|
48
|
+
@endDate = wh.endDate
|
49
|
+
@slotDuration = wh.slotDuration
|
50
|
+
@scoreboard = wh.scoreboard
|
51
|
+
else
|
52
|
+
slotDuration = arg1
|
53
|
+
if arg1.nil? || startDate.nil? || endDate.nil?
|
54
|
+
raise "You must supply values for slotDuration, start and end dates"
|
55
|
+
end
|
56
|
+
@startDate = startDate
|
57
|
+
@endDate = endDate
|
58
|
+
@slotDuration = slotDuration
|
59
|
+
|
60
|
+
# Create a new object with default working hours.
|
61
|
+
@timezone = nil
|
62
|
+
# Set the default working hours. Monday to Friday 9am - 12pm, 1pm - 6pm.
|
63
|
+
# Saturday and Sunday are days off.
|
64
|
+
1.upto(5) do |day|
|
65
|
+
@days[day] = [ [ 9 * 60 * 60, 12 * 60 * 60 ],
|
66
|
+
[ 13 * 60 * 60, 18 * 60 * 60 ] ]
|
67
|
+
end
|
156
68
|
end
|
157
69
|
end
|
158
70
|
|
159
71
|
# Return true of the given WorkingHours object +wh+ is identical to this
|
160
72
|
# object.
|
161
73
|
def ==(wh)
|
162
|
-
return false if wh.nil? || @timezone != wh.timezone
|
74
|
+
return false if wh.nil? || @timezone != wh.timezone ||
|
75
|
+
@startDate != wh.startDate ||
|
76
|
+
@endDate != wh.endDate ||
|
77
|
+
@slotDuration != wh.slotDuration
|
163
78
|
|
164
79
|
7.times do |d|
|
165
80
|
return false if @days[d].length != wh.days[d].length
|
@@ -178,10 +93,8 @@ class TaskJuggler
|
|
178
93
|
# specifies the time of day as minutes after midnight. The first value is
|
179
94
|
# the start time of the interval, the second the end time.
|
180
95
|
def setWorkingHours(dayOfWeek, intervals)
|
181
|
-
|
182
|
-
|
183
|
-
'called.'
|
184
|
-
end
|
96
|
+
# Changing the working hours requires the score board to be regenerated.
|
97
|
+
@scoreboard = nil
|
185
98
|
|
186
99
|
# Legal values range from 0 Sunday to 6 Saturday.
|
187
100
|
if dayOfWeek < 0 || dayOfWeek > 6
|
@@ -199,6 +112,13 @@ class TaskJuggler
|
|
199
112
|
@days[dayOfWeek] = intervals
|
200
113
|
end
|
201
114
|
|
115
|
+
# Set the time zone _zone_ for the working hours. This will reset the
|
116
|
+
# @scoreboard.
|
117
|
+
def timezone=(zone)
|
118
|
+
@scoreboard = nil
|
119
|
+
@timezone = zone
|
120
|
+
end
|
121
|
+
|
202
122
|
# Return the working hour intervals for a given day of the week.
|
203
123
|
# +dayOfWeek+ must 0 for Sunday, 1 for Monday and so on. The result is an
|
204
124
|
# Array that contains Arrays of 2 Fixnums.
|
@@ -208,64 +128,24 @@ class TaskJuggler
|
|
208
128
|
|
209
129
|
# Return true if _date_ is within the defined working hours.
|
210
130
|
def onShift?(date)
|
211
|
-
|
212
|
-
|
213
|
-
# If we have the result cached already, return it.
|
214
|
-
unless (os = @@onShiftCache.get(@cache, date)).nil?
|
215
|
-
return os
|
216
|
-
end
|
217
|
-
|
218
|
-
# The date is in UTC. The weekday needs to be calculated according to the
|
219
|
-
# timezone of the project.
|
220
|
-
projectDate = toLocaltime(date)
|
221
|
-
dow = projectDate.wday
|
222
|
-
|
223
|
-
# The working hours need to be put into the proper time zone.
|
224
|
-
localDate = toLocaltime(date, @timezone)
|
225
|
-
secondsOfDay = localDate.secondsOfDay
|
226
|
-
|
227
|
-
@days[dow].each do |iv|
|
228
|
-
# Check the working hours of that day if they overlap with +date+.
|
229
|
-
if iv[0] <= secondsOfDay && secondsOfDay < iv[1]
|
230
|
-
# Store the result in the cache.
|
231
|
-
@@onShiftCache.set(@cache, date, true)
|
232
|
-
return true
|
233
|
-
end
|
234
|
-
end
|
131
|
+
initScoreboard unless @scoreboard
|
235
132
|
|
236
|
-
|
237
|
-
@@onShiftCache.set(@cache, date, false)
|
238
|
-
false
|
133
|
+
@scoreboard.get(date)
|
239
134
|
end
|
240
135
|
|
241
|
-
#
|
242
|
-
# ShiftAssignment.
|
136
|
+
# Return true only if all slots in the _interval_ are offhour slots.
|
243
137
|
def timeOff?(interval)
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
60 * 60 * 24;
|
252
|
-
@days[dow].each do |iv|
|
253
|
-
return false if (dayStart <= iv[0] && iv[0] < dayEnd) ||
|
254
|
-
(iv[0] <= dayStart && dayStart < iv[1])
|
255
|
-
end
|
256
|
-
end
|
257
|
-
t = t.sameTimeNextDay
|
138
|
+
initScoreboard unless @scoreboard
|
139
|
+
|
140
|
+
startIdx = @scoreboard.dateToIdx(interval.start, true)
|
141
|
+
endIdx = @scoreboard.dateToIdx(interval.end, true)
|
142
|
+
|
143
|
+
startIdx.upto(endIdx - 1) do |i|
|
144
|
+
return false if @scoreboard[i]
|
258
145
|
end
|
259
146
|
true
|
260
147
|
end
|
261
148
|
|
262
|
-
# Probably should be put into ShiftAssignment as well.
|
263
|
-
def dayOff?(date)
|
264
|
-
projectDate = toLocaltime(date)
|
265
|
-
dow = projectDate.wday
|
266
|
-
@days[dow].empty?
|
267
|
-
end
|
268
|
-
|
269
149
|
# Returns the time interval settings for each day in a human readable form.
|
270
150
|
def to_s
|
271
151
|
dayNames = %w( Sun Mon Tue Wed Thu Fri Sat )
|
@@ -295,26 +175,51 @@ class TaskJuggler
|
|
295
175
|
|
296
176
|
private
|
297
177
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
178
|
+
def initScoreboard
|
179
|
+
# The scoreboard is an Array of True/False values. It spans a certain
|
180
|
+
# time period with one entry per time slot.
|
181
|
+
@scoreboard = Scoreboard.new(@startDate, @endDate, @slotDuration, false)
|
182
|
+
|
302
183
|
oldTimezone = nil
|
303
184
|
# Set environment variable TZ to appropriate time zone
|
304
185
|
if @timezone
|
305
|
-
oldTimezone = ENV['
|
306
|
-
ENV['
|
186
|
+
oldTimezone = ENV['TZ']
|
187
|
+
ENV['TZ'] = @timezone
|
307
188
|
end
|
308
189
|
|
309
|
-
|
310
|
-
|
190
|
+
date = @startDate
|
191
|
+
@scoreboard.collect! do |slot|
|
192
|
+
localDate = date.dup
|
193
|
+
localDate.localtime
|
194
|
+
|
195
|
+
# The date is in UTC. The weekday needs to be calculated according to
|
196
|
+
# the local timezone.
|
197
|
+
weekday = localDate.wday
|
198
|
+
secondsOfDay = localDate.secondsOfDay
|
199
|
+
|
200
|
+
result = false
|
201
|
+
@days[weekday].each do |iv|
|
202
|
+
# Check the working hours of that day if they overlap with +date+.
|
203
|
+
if iv[0] <= secondsOfDay && secondsOfDay < iv[1]
|
204
|
+
# The time slot is a working slot.
|
205
|
+
result = true
|
206
|
+
break
|
207
|
+
end
|
208
|
+
end
|
209
|
+
# Calculate date of next scoreboard slot
|
210
|
+
date += @slotDuration
|
311
211
|
|
312
|
-
|
313
|
-
if oldTimezone
|
314
|
-
ENV['tz'] = oldTimezone
|
212
|
+
result
|
315
213
|
end
|
316
214
|
|
317
|
-
|
215
|
+
# Restore environment
|
216
|
+
if @timezone
|
217
|
+
if oldTimezone
|
218
|
+
ENV['TZ'] = oldTimezone
|
219
|
+
else
|
220
|
+
ENV.delete('TZ')
|
221
|
+
end
|
222
|
+
end
|
318
223
|
end
|
319
224
|
|
320
225
|
end
|
data/lib/daemon/ReportServer.rb
CHANGED
@@ -98,7 +98,7 @@ class TaskJuggler
|
|
98
98
|
|
99
99
|
def addFile(file)
|
100
100
|
begin
|
101
|
-
@tj.parseFile(file,
|
101
|
+
@tj.parseFile(file, :properties)
|
102
102
|
rescue TjException
|
103
103
|
return false
|
104
104
|
end
|
@@ -108,8 +108,9 @@ class TaskJuggler
|
|
108
108
|
|
109
109
|
def generateReport(id, regExpMode, dynamicAttributes)
|
110
110
|
@log.info("Generating report #{id}")
|
111
|
+
startTime = Time.now
|
111
112
|
if (ok = @tj.generateReport(id, regExpMode, dynamicAttributes))
|
112
|
-
@log.
|
113
|
+
@log.info("Report #{id} generated in #{Time.now - startTime} seconds")
|
113
114
|
else
|
114
115
|
@log.error("Report generation of #{id} failed")
|
115
116
|
end
|
data/lib/reports/CSVFile.rb
CHANGED
@@ -0,0 +1,177 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = CollisionDetector.rb -- The TaskJuggler III Project Management Software
|
5
|
+
#
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
7
|
+
#
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
9
|
+
# it under the terms of version 2 of the GNU General Public License as
|
10
|
+
# published by the Free Software Foundation.
|
11
|
+
#
|
12
|
+
|
13
|
+
require 'reports/HTMLGraphics'
|
14
|
+
|
15
|
+
class TaskJuggler
|
16
|
+
|
17
|
+
class CollisionDetector
|
18
|
+
|
19
|
+
include HTMLGraphics
|
20
|
+
|
21
|
+
def initialize(width, height)
|
22
|
+
@width = width
|
23
|
+
@height = height
|
24
|
+
|
25
|
+
# The zones are stored as Arrays of line segments. Horizontal blocks are
|
26
|
+
# stored separately from vertical blocks. Blocked segments for a
|
27
|
+
# particular x coordinate are stored in @vLines, for y coordinates in
|
28
|
+
# @hLines. Each entry is an Array of [ start, end ] values that describe
|
29
|
+
# the blocked segments of that particular line. Start and end point are
|
30
|
+
# part of the segment. A listed segment will not be overwritten during
|
31
|
+
# routing.
|
32
|
+
@hLines = Array.new(@height) { |i| i = [] }
|
33
|
+
@vLines = Array.new(@width) { |i| i = [] }
|
34
|
+
end
|
35
|
+
|
36
|
+
# This function registers an area as don't-cross-zone. The rectangular zone
|
37
|
+
# is described by _x_, _y_, _w_ and _h_. If _horiz_ is true, the zone will
|
38
|
+
# be blocked for horizontal lines, if _vert_ is true the zone will be
|
39
|
+
# blocked for vertical lines.
|
40
|
+
def addBlockedZone(x, y, w, h, horiz, vert)
|
41
|
+
# Clip the input rectangle to fit within the handled area of this router.
|
42
|
+
x = clip(x.to_i, @width - 1)
|
43
|
+
y = clip(y.to_i, @height - 1)
|
44
|
+
w = clip(w.to_i, @width - x)
|
45
|
+
h = clip(h.to_i, @height - y)
|
46
|
+
|
47
|
+
# We can ignore empty zones.
|
48
|
+
return if w == 0 || h == 0
|
49
|
+
|
50
|
+
# Break the rectangle into line segments and add them to the appropriate
|
51
|
+
# line Arrays.
|
52
|
+
if horiz
|
53
|
+
y.upto(y + h - 1) do |i|
|
54
|
+
addSegment(@hLines[i], [ x, x + w - 1 ])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
if vert
|
58
|
+
x.upto(x + w - 1) do |i|
|
59
|
+
addSegment(@vLines[i], [ y, y + h - 1 ])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Find out if there is a block at line _pos_ for the start/end coordinates
|
65
|
+
# given by _segment_. If _horizontal_ is true, we are looking for a
|
66
|
+
# horizontal block, otherwise a vertical.
|
67
|
+
def collision?(pos, segment, horizontal)
|
68
|
+
line = (horizontal ? @hLines : @vLines)[pos]
|
69
|
+
|
70
|
+
# For complex charts, the segment lists can be rather long. We use a
|
71
|
+
# binary search to be fairly efficient.
|
72
|
+
l = 0
|
73
|
+
u = line.length - 1
|
74
|
+
while l <= u
|
75
|
+
# Look at the element in the middle between l and u.
|
76
|
+
p = l + ((u - l) / 2).to_i
|
77
|
+
return true if overlaps?(line[p], segment)
|
78
|
+
|
79
|
+
if segment[0] > line[p][1]
|
80
|
+
# The potential target is above p. Adjust lower bound.
|
81
|
+
l = p + 1
|
82
|
+
else
|
83
|
+
# The potential target is below p. Adjust upper bound.
|
84
|
+
u = p - 1
|
85
|
+
end
|
86
|
+
end
|
87
|
+
false
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_html
|
91
|
+
html = []
|
92
|
+
# Change this to determine what zones you want to see.
|
93
|
+
if true
|
94
|
+
# Show vertical blocks
|
95
|
+
x = 0
|
96
|
+
@vLines.each do |line|
|
97
|
+
line.each do |segment|
|
98
|
+
html << lineToHTML(x, segment[0], x, segment[1], 'white')
|
99
|
+
end
|
100
|
+
x += 1
|
101
|
+
end
|
102
|
+
else
|
103
|
+
# Show horizontal blocks
|
104
|
+
y = 0
|
105
|
+
@hLines.each do |line|
|
106
|
+
line.each do |segment|
|
107
|
+
html << lineToHTML(segment[0], y, segment[1], y, 'white')
|
108
|
+
end
|
109
|
+
y += 1
|
110
|
+
end
|
111
|
+
end
|
112
|
+
html
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
# Simple utility function to limit _v_ between 0 and _max_.
|
118
|
+
def clip(v, max)
|
119
|
+
v = 0 if v < 0
|
120
|
+
v = max if v > max
|
121
|
+
v
|
122
|
+
end
|
123
|
+
|
124
|
+
# This function adds a new segment to the line. In case the new segment
|
125
|
+
# overlaps with or directly attaches to existing segments, these segments
|
126
|
+
# are merged into a single segment.
|
127
|
+
def addSegment(line, newSegment)
|
128
|
+
# Search for overlaping or directly attaching segments in the list.
|
129
|
+
i = 0
|
130
|
+
while (i < line.length)
|
131
|
+
segment = line[i]
|
132
|
+
if mergeable?(newSegment, segment)
|
133
|
+
# Merge exiting segment into new one
|
134
|
+
merge(newSegment, segment)
|
135
|
+
# Remove the old one from the list and restart with the newly created
|
136
|
+
# one at the same position.
|
137
|
+
line.delete_at(i)
|
138
|
+
next
|
139
|
+
elsif segment[0] > newSegment[1]
|
140
|
+
# Segments are stored in ascending order. If the next segment starts
|
141
|
+
# with a larger value, we insert the new segment before the larger
|
142
|
+
# one.
|
143
|
+
line.insert(i, newSegment)
|
144
|
+
return
|
145
|
+
end
|
146
|
+
i += 1
|
147
|
+
end
|
148
|
+
# Append new segment
|
149
|
+
line << newSegment
|
150
|
+
end
|
151
|
+
|
152
|
+
# Return true if the two segments described by _s1_ and _s2_ overlap each
|
153
|
+
# other. A segment is a [ start, end ] Array. The two points are part of the
|
154
|
+
# segment.
|
155
|
+
def overlaps?(s1, s2)
|
156
|
+
(s1[0] <= s2[0] && s2[0] <= s1[1]) ||
|
157
|
+
(s2[0] <= s1[0] && s1[0] <= s2[1])
|
158
|
+
end
|
159
|
+
|
160
|
+
# Return true if the two segments described by _s1_ and _s2_ overlap each
|
161
|
+
# other or are directly attached to each other.
|
162
|
+
def mergeable?(s1, s2)
|
163
|
+
overlaps?(s1, s2) ||
|
164
|
+
(s1[1] + 1 == s2[0]) ||
|
165
|
+
(s2[1] + 1 == s1[0])
|
166
|
+
end
|
167
|
+
|
168
|
+
# Merge the two segments described by _dst_ and _src_ into _dst_.
|
169
|
+
def merge(dst, seg)
|
170
|
+
dst[0] = seg[0] if seg[0] < dst[0]
|
171
|
+
dst[1] = seg[1] if seg[1] > dst[1]
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|