taskjuggler 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/reports/GanttChart.rb
CHANGED
|
@@ -198,9 +198,9 @@ class TaskJuggler
|
|
|
198
198
|
end
|
|
199
199
|
|
|
200
200
|
# This is a noop function.
|
|
201
|
-
def to_csv
|
|
201
|
+
def to_csv(csv, startColumn)
|
|
202
202
|
# Can't put a Gantt chart into a CSV file.
|
|
203
|
-
|
|
203
|
+
0
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
# Utility function that convers a date to the corresponding X-position in
|
|
@@ -240,16 +240,30 @@ class TaskJuggler
|
|
|
240
240
|
@height = line.y + line.height if line.y + line.height > @height
|
|
241
241
|
end
|
|
242
242
|
|
|
243
|
+
# To layout the dependency lines, we use a GanttRouter. We only provide
|
|
244
|
+
# the start and end coordinates of each line and it will do the layout
|
|
245
|
+
# and routing.
|
|
243
246
|
@router = GanttRouter.new(@width, @height)
|
|
244
247
|
|
|
248
|
+
# We don't want horizontal lines to cross the task bars. So we block
|
|
249
|
+
# these chart zones. Milestones should not be crossed in any direction.
|
|
245
250
|
@lines.each do |line|
|
|
246
251
|
line.addBlockedZones(@router)
|
|
247
252
|
end
|
|
248
253
|
|
|
254
|
+
# Also protect the current date line from other vertical lines.
|
|
249
255
|
@router.addZone(@header.nowLineX - 1, 0, 3, @height - 1, false, true)
|
|
250
256
|
|
|
257
|
+
# Generate the dependency arrows for all visible tasks.
|
|
251
258
|
@tasks.each do |task, lines|
|
|
252
|
-
|
|
259
|
+
generateDepLines(task, lines)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Make sure we have exactly one arrow head for each line end point even
|
|
263
|
+
# if the point is used by multiple lines.
|
|
264
|
+
@depArrows.each do |line|
|
|
265
|
+
endPoint = line.last
|
|
266
|
+
@arrowHeads << endPoint unless @arrowHeads.include?(endPoint)
|
|
253
267
|
end
|
|
254
268
|
end
|
|
255
269
|
|
|
@@ -257,18 +271,18 @@ class TaskJuggler
|
|
|
257
271
|
# for a specific _task_. _lines_ is a list of GanttLines that the tasks are
|
|
258
272
|
# displayed on. Reports with multiple scenarios have multiple lines per
|
|
259
273
|
# task.
|
|
260
|
-
def
|
|
274
|
+
def generateDepLines(task, lines)
|
|
261
275
|
# Since we need the line and the index we use an index iterator.
|
|
262
276
|
lines.length.times do |lineIndex|
|
|
263
277
|
line = lines[lineIndex]
|
|
264
278
|
scenarioIdx = line.query.scenarioIdx
|
|
265
279
|
|
|
266
280
|
# Generate the dependencies on the start of the task.
|
|
267
|
-
|
|
281
|
+
generateTaskDepLines('startsuccs', task, scenarioIdx, lineIndex,
|
|
268
282
|
*line.getTask.startDepLineStart)
|
|
269
283
|
|
|
270
284
|
# Generate the dependencies on the end of the task.
|
|
271
|
-
|
|
285
|
+
generateTaskDepLines('endsuccs', task, scenarioIdx, lineIndex,
|
|
272
286
|
*line.getTask.endDepLineStart)
|
|
273
287
|
end
|
|
274
288
|
end
|
|
@@ -278,11 +292,9 @@ class TaskJuggler
|
|
|
278
292
|
# and _startY_ are the graphic coordinates for the begin of the arrow
|
|
279
293
|
# line. _task_ references the Task in question and _scenarioIdx_ the
|
|
280
294
|
# scenario. _lineIndex_ specifies the line number in the chart.
|
|
281
|
-
def
|
|
282
|
-
#
|
|
283
|
-
# each entry: The x and y coordinates for start and end points
|
|
284
|
-
# sinus value of the angle between a vertical and the line specified by
|
|
285
|
-
# the points and the length of the line.
|
|
295
|
+
def generateTaskDepLines(kind, task, scenarioIdx, lineIndex, startX, startY)
|
|
296
|
+
# This is an Array that holds 4 values for
|
|
297
|
+
# each entry: The x and y coordinates for start and end points.
|
|
286
298
|
touples = []
|
|
287
299
|
task[kind, scenarioIdx].each do |t, onEnd|
|
|
288
300
|
# Skip inherited dependencies and tasks that are not included in the
|
|
@@ -294,37 +306,9 @@ class TaskJuggler
|
|
|
294
306
|
end
|
|
295
307
|
endX, endY = @tasks[t][lineIndex].getTask.send(
|
|
296
308
|
onEnd ? :endDepLineEnd : :startDepLineEnd)
|
|
297
|
-
|
|
298
|
-
# originate from the same position, we sort the arrows by the
|
|
299
|
-
# smallest angle between the vertical line through the task end
|
|
300
|
-
# and the line between the start and end of the arrow.
|
|
301
|
-
oppLeg = endX - startX
|
|
302
|
-
adjLeg = (startY - endY).abs
|
|
303
|
-
hypothenuse = Math.sqrt(adjLeg ** 2 + oppLeg ** 2)
|
|
304
|
-
# We can now calculate the sinus values of the angle between the
|
|
305
|
-
# vertical and a line through the coordinates.
|
|
306
|
-
touples << [ startX, startY, endX, endY,
|
|
307
|
-
(oppLeg / hypothenuse), hypothenuse ]
|
|
308
|
-
end
|
|
309
|
-
# We sort the arrows from small to a large angle. In case the angle is
|
|
310
|
-
# identical, we use the length of the line as second criteria.
|
|
311
|
-
touples.sort! { |t1, t2| t1[4] == t2[4] ? t1[5] <=> t2[5] :
|
|
312
|
-
t1[4] <=> t2[4] }
|
|
313
|
-
touples.each do |t|
|
|
314
|
-
routeArrow(*t[0, 4])
|
|
315
|
-
end
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# Route the dependency lines from the start to the end point.
|
|
319
|
-
def routeArrow(startX, startY, endX, endY)
|
|
320
|
-
@depArrows << @router.route([startX, startY], [endX, endY])
|
|
321
|
-
|
|
322
|
-
# It's enough to have only a single arrow drawn at the end point even if
|
|
323
|
-
# it's the destination of multiple lines.
|
|
324
|
-
@arrowHeads.each do |x, y|
|
|
325
|
-
return if x == endX && y == endY
|
|
309
|
+
touples << [ startX, startY, endX, endY ]
|
|
326
310
|
end
|
|
327
|
-
@
|
|
311
|
+
@depArrows += @router.routeLines(touples) unless touples.empty?()
|
|
328
312
|
end
|
|
329
313
|
|
|
330
314
|
end
|
data/lib/reports/GanttRouter.rb
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
# published by the Free Software Foundation.
|
|
11
11
|
#
|
|
12
12
|
|
|
13
|
+
require 'reports/CollisionDetector'
|
|
14
|
+
|
|
13
15
|
class TaskJuggler
|
|
14
16
|
|
|
15
17
|
# The GanttRouter is used by the GanttChart to route the dependency lines from
|
|
@@ -17,11 +19,15 @@ class TaskJuggler
|
|
|
17
19
|
# width and height. The graphical elements of the Gantt chart can be
|
|
18
20
|
# registered as don't-cross-zones. These zones block the either horizontal or
|
|
19
21
|
# vertical lines (or both) from crossing the zone. Zones can be registered by
|
|
20
|
-
# calling addZone(). The route() method returns routed path from
|
|
21
|
-
# point.
|
|
22
|
+
# calling addZone(). The route() method returns routed path from
|
|
23
|
+
# start to end point.
|
|
22
24
|
class GanttRouter
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
# Minimum distance between the starting point and the first turning point.
|
|
27
|
+
MinStartGap = 5
|
|
28
|
+
# Minimum distance between the last turning point and the tip of the
|
|
29
|
+
# arrow.
|
|
30
|
+
MinEndGap = 10
|
|
25
31
|
|
|
26
32
|
# Create a GanttRouter object. _width_ and _height_ describe the size of the
|
|
27
33
|
# rectangular area this router is operating on.
|
|
@@ -29,77 +35,86 @@ class TaskJuggler
|
|
|
29
35
|
@width = width.to_i
|
|
30
36
|
@height = height.to_i
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
# stored separately from vertical blocks. Blocked segments for a
|
|
34
|
-
# particular x coordinate are stored in @vLines, for y coordinates in
|
|
35
|
-
# @hLines. Each entry is an Array of [ start, end ] values that describe
|
|
36
|
-
# the blocked segments of that particular line. Start and end point are
|
|
37
|
-
# part of the segment. A listed segment will not be overwritten during
|
|
38
|
-
# routing.
|
|
39
|
-
@hLines = Array.new(@height) { |i| i = [] }
|
|
40
|
-
@vLines = Array.new(@width) { |i| i = [] }
|
|
38
|
+
@detector = CollisionDetector.new(@width, @height)
|
|
41
39
|
end
|
|
42
40
|
|
|
43
|
-
# This function registers an area as don't-cross-zone. The rectangular zone
|
|
44
|
-
# is described by _x_, _y_, _w_ and _h_. If _horiz_ is true, the zone will
|
|
45
|
-
# be blocked for horizontal lines, if _vert_ is true the zone will be
|
|
46
|
-
# blocked for vertical lines.
|
|
47
41
|
def addZone(x, y, w, h, horiz, vert)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
y = clip(y.to_i, @height - 1)
|
|
51
|
-
w = clip(w.to_i, @width - x)
|
|
52
|
-
h = clip(h.to_i, @height - y)
|
|
42
|
+
@detector.addBlockedZone(x, y, w, h, horiz, vert)
|
|
43
|
+
end
|
|
53
44
|
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
def routeLines(fromToPoints)
|
|
46
|
+
# We first convert the fromToPoints list into a more readable list of
|
|
47
|
+
# Hash objects.
|
|
48
|
+
routes = []
|
|
49
|
+
fromToPoints.each do |touple|
|
|
50
|
+
routes << {
|
|
51
|
+
:startX => touple[0],
|
|
52
|
+
:startY => touple[1],
|
|
53
|
+
:endX => touple[2],
|
|
54
|
+
:endY => touple[3],
|
|
55
|
+
:id => touple[4]
|
|
56
|
+
}
|
|
57
|
+
end
|
|
56
58
|
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
# To make sure that we minimize the crossings of arrows that
|
|
60
|
+
# originate from the same position, we sort the arrows by the
|
|
61
|
+
# smallest angle between the vertical line through the task end
|
|
62
|
+
# and the line between the start and end of the arrow.
|
|
63
|
+
routes.each do |r|
|
|
64
|
+
adjLeg = (r[:endX] - MinEndGap) - (r[:startX] + MinStartGap)
|
|
65
|
+
oppLeg = (r[:startY] - r[:endY]).abs
|
|
66
|
+
r[:distance] = Math.sqrt(adjLeg ** 2 + oppLeg ** 2)
|
|
67
|
+
# We can now calculate the sinus values of the angle between the
|
|
68
|
+
# vertical and a line through the coordinates.
|
|
69
|
+
sinus = oppLeg.abs / r[:distance]
|
|
70
|
+
r[:angle] = (adjLeg < 0 ? Math::PI / 2 + Math.asin(Math::PI/2 - sinus) :
|
|
71
|
+
Math.asin(sinus)) / (Math::PI / (2 * 90))
|
|
63
72
|
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
# We sort the arrows from small to a large angle. In case the angle is
|
|
74
|
+
# identical, we use the length of the line as second criteria.
|
|
75
|
+
routes.sort! { |r1, r2| (r1[:angle] / 5).to_i == (r2[:angle] / 5).to_i ?
|
|
76
|
+
-(r1[:distance] <=> r2[:distance]) :
|
|
77
|
+
-(r1[:angle] <=> r2[:angle]) }
|
|
78
|
+
|
|
79
|
+
# Now that the routes are in proper order, we can actually lay the
|
|
80
|
+
# routes.
|
|
81
|
+
routePoints = []
|
|
82
|
+
routes.each do |r|
|
|
83
|
+
routePoints << route(r[:startX], r[:startY], r[:endX], r[:endY])
|
|
68
84
|
end
|
|
85
|
+
routePoints
|
|
69
86
|
end
|
|
70
87
|
|
|
71
88
|
# Find a non-blocked route from the _startPoint_ [ x, y ] to the
|
|
72
89
|
# _endPoint_ [ x, y ]. The route always starts from the start point towards
|
|
73
90
|
# the right side of the chart and reaches the end point from the left side
|
|
74
91
|
# of the chart. All lines are always strictly horizontal or vertical. There
|
|
75
|
-
# are no diagonal lines.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
startGap =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
endGap
|
|
83
|
-
|
|
84
|
-
if endPoint[0] - startPoint[0] > startGap + endGap + 2
|
|
92
|
+
# are no diagonal lines. The result is an Array of [ x, y ] points that
|
|
93
|
+
# include the _startPoint_ as first and _endPoint_ as last element.
|
|
94
|
+
def route(startX, startY, endX, endY)
|
|
95
|
+
points = [ [ startX, startY ] ]
|
|
96
|
+
startGap = MinStartGap
|
|
97
|
+
endGap = MinEndGap
|
|
98
|
+
|
|
99
|
+
if endX - startX > startGap + endGap + 2
|
|
85
100
|
# If the horizontal distance between start and end point is large enough
|
|
86
101
|
# we can try a direct route.
|
|
87
102
|
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
103
|
+
# xSeg
|
|
104
|
+
# |startGap|
|
|
105
|
+
# startX/endX X--------1
|
|
106
|
+
# |
|
|
107
|
+
# |
|
|
108
|
+
# 2------X endX/endY
|
|
109
|
+
# |endGap|
|
|
95
110
|
#
|
|
96
|
-
xSeg = placeLine([
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
addLineTo(points, xSeg,
|
|
101
|
-
addLineTo(points, xSeg,
|
|
102
|
-
addLineTo(points,
|
|
111
|
+
xSeg = placeLine([ startY + (startY < endY ? 1 : -1), endY ],
|
|
112
|
+
false, startX + startGap, 1)
|
|
113
|
+
if xSeg && xSeg < endX - endGap
|
|
114
|
+
# The simple version works. Add the lines.
|
|
115
|
+
addLineTo(points, xSeg, startY) # Point 1
|
|
116
|
+
addLineTo(points, xSeg, endY) # Point 2
|
|
117
|
+
addLineTo(points, endX, endY)
|
|
103
118
|
return points
|
|
104
119
|
end
|
|
105
120
|
end
|
|
@@ -107,40 +122,39 @@ class TaskJuggler
|
|
|
107
122
|
# If the simple approach above fails, the try a more complex routing
|
|
108
123
|
# strategy.
|
|
109
124
|
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
125
|
+
# x1
|
|
126
|
+
# |startGap|
|
|
127
|
+
# startX/startY X--------1 yLS
|
|
128
|
+
# |
|
|
129
|
+
# 3---------------2 ySeg
|
|
130
|
+
# |
|
|
131
|
+
# 4------X endX/endY
|
|
132
|
+
# |endGap|
|
|
133
|
+
# x2
|
|
119
134
|
|
|
120
135
|
# Place horizontal segue. We don't know the width yet, so we have to
|
|
121
136
|
# assume full width. That's acceptable for horizontal lines.
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
deltaY = startY < endY ? 1 : -1
|
|
138
|
+
ySeg = placeLine([ 0, @width - 1 ], true, startY + 2 * deltaY, deltaY)
|
|
124
139
|
raise "Routing failed" unless ySeg
|
|
125
140
|
|
|
126
141
|
# Place 1st vertical
|
|
127
|
-
x1 = placeLine([
|
|
128
|
-
ySeg ], false, startPoint[0] + startGap, 1)
|
|
142
|
+
x1 = placeLine([ startY + deltaY, ySeg ], false, startX + startGap, 1)
|
|
129
143
|
raise "Routing failed" unless x1
|
|
130
144
|
|
|
131
145
|
# Place 2nd vertical
|
|
132
|
-
x2 = placeLine([ ySeg,
|
|
146
|
+
x2 = placeLine([ ySeg + deltaY, endY ], false, endX - endGap, -1)
|
|
133
147
|
raise "Routing failed" unless x2
|
|
134
148
|
|
|
135
149
|
# Now add the points 1 - 4 to the list and mark the zones around them. For
|
|
136
150
|
# vertical lines, we only mark vertical zones and vice versa.
|
|
137
|
-
addLineTo(points, x1,
|
|
151
|
+
addLineTo(points, x1, startY) # Point 1
|
|
138
152
|
if x1 != x2
|
|
139
153
|
addLineTo(points, x1, ySeg) # Point 2
|
|
140
154
|
addLineTo(points, x2, ySeg) # Point 3
|
|
141
155
|
end
|
|
142
|
-
addLineTo(points, x2,
|
|
143
|
-
addLineTo(points,
|
|
156
|
+
addLineTo(points, x2, endY) # Point 4
|
|
157
|
+
addLineTo(points, endX, endY)
|
|
144
158
|
|
|
145
159
|
points
|
|
146
160
|
end
|
|
@@ -148,138 +162,11 @@ class TaskJuggler
|
|
|
148
162
|
# This function is only intended for debugging purposes. It marks either the
|
|
149
163
|
# vertical or horizontal zones in the chart.
|
|
150
164
|
def to_html
|
|
151
|
-
|
|
152
|
-
# Change this to determine what zones you want to see.
|
|
153
|
-
if true
|
|
154
|
-
# Show vertical blocks
|
|
155
|
-
x = 0
|
|
156
|
-
@vLines.each do |line|
|
|
157
|
-
line.each do |segment|
|
|
158
|
-
html << lineToHTML(x, segment[0], x, segment[1], 'white')
|
|
159
|
-
end
|
|
160
|
-
x += 1
|
|
161
|
-
end
|
|
162
|
-
else
|
|
163
|
-
# Show horizontal blocks
|
|
164
|
-
y = 0
|
|
165
|
-
@hLines.each do |line|
|
|
166
|
-
line.each do |segment|
|
|
167
|
-
html << lineToHTML(segment[0], y, segment[1], y, 'white')
|
|
168
|
-
end
|
|
169
|
-
y += 1
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
html
|
|
165
|
+
@detector.to_html
|
|
173
166
|
end
|
|
174
167
|
|
|
175
168
|
private
|
|
176
169
|
|
|
177
|
-
# Simple utility function to limit _v_ between 0 and _max_.
|
|
178
|
-
def clip(v, max)
|
|
179
|
-
v = 0 if v < 0
|
|
180
|
-
v = max if v > max
|
|
181
|
-
v
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
# This function makes sure that the rectangle described by _x_, _y_, _w_ and
|
|
185
|
-
# _h_ is properly justfified. If the width or height are negative, _x_ and
|
|
186
|
-
# _y_ are adjusted to describe the same rectangle with all positive
|
|
187
|
-
# coordinates.
|
|
188
|
-
def justify(x, y, w, h)
|
|
189
|
-
if w < 0
|
|
190
|
-
w = -w
|
|
191
|
-
x = x - w + 1
|
|
192
|
-
end
|
|
193
|
-
if h < 0
|
|
194
|
-
h = -h
|
|
195
|
-
y = y - h + 1
|
|
196
|
-
end
|
|
197
|
-
# Return the potentially adjusted rectangle coordinates.
|
|
198
|
-
return x, y, w, h
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
# This function adds a new segment to the line. In case the new segment
|
|
202
|
-
# overlaps with or directly attaches to existing segments, these segments
|
|
203
|
-
# are merged into a single segment.
|
|
204
|
-
def addSegment(line, newSegment)
|
|
205
|
-
# Search for overlaping or directly attaching segments in the list.
|
|
206
|
-
i = 0
|
|
207
|
-
while (i < line.length)
|
|
208
|
-
segment = line[i]
|
|
209
|
-
if mergeable?(newSegment, segment)
|
|
210
|
-
# Merge exiting segment into new one
|
|
211
|
-
merge(newSegment, segment)
|
|
212
|
-
# Remove the old one from the list and restart with the newly created
|
|
213
|
-
# one at the same position.
|
|
214
|
-
line.delete_at(i)
|
|
215
|
-
next
|
|
216
|
-
elsif segment[0] > newSegment[1]
|
|
217
|
-
# Segments are stored in ascending order. If the next segment starts
|
|
218
|
-
# with a larger value, we insert the new segment before the larger
|
|
219
|
-
# one.
|
|
220
|
-
line.insert(i, newSegment)
|
|
221
|
-
return
|
|
222
|
-
end
|
|
223
|
-
i += 1
|
|
224
|
-
end
|
|
225
|
-
# Append new segment
|
|
226
|
-
line << newSegment
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
# Return true if the two segments described by _s1_ and _s2_ overlap each
|
|
230
|
-
# other. A segment is a [ start, end ] Array. The two points are part of the
|
|
231
|
-
# segment.
|
|
232
|
-
def overlaps?(s1, s2)
|
|
233
|
-
(s1[0] <= s2[0] && s2[0] <= s1[1]) ||
|
|
234
|
-
(s2[0] <= s1[0] && s1[0] <= s2[1])
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# Return true if the two segments described by _s1_ and _s2_ overlap each
|
|
238
|
-
# other or are directly attached to each other.
|
|
239
|
-
def mergeable?(s1, s2)
|
|
240
|
-
overlaps?(s1, s2) ||
|
|
241
|
-
(s1[1] + 1 == s2[0]) ||
|
|
242
|
-
(s2[1] + 1 == s1[0])
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
# Merge the two segments described by _dst_ and _src_ into _dst_.
|
|
246
|
-
def merge(dst, seg)
|
|
247
|
-
dst[0] = seg[0] if seg[0] < dst[0]
|
|
248
|
-
dst[1] = seg[1] if seg[1] > dst[1]
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
# Find out if any of the segments in _line_ overlap with the _probeSegment_.
|
|
252
|
-
# If so, return true, false otherwise.
|
|
253
|
-
def collision?(line, probeSegment)
|
|
254
|
-
# For complex charts, the segment lists can be rather long. We use a
|
|
255
|
-
# binary search to be fairly efficient.
|
|
256
|
-
l = 0
|
|
257
|
-
u = line.length - 1
|
|
258
|
-
while l <= u
|
|
259
|
-
# Look at the element in the middle between l and u.
|
|
260
|
-
p = l + ((u - l) / 2).to_i
|
|
261
|
-
return true if overlaps?(line[p], probeSegment)
|
|
262
|
-
|
|
263
|
-
if probeSegment[0] > line[p][1]
|
|
264
|
-
# The potential target is above p. Adjust lower bound.
|
|
265
|
-
l = p + 1
|
|
266
|
-
else
|
|
267
|
-
# The potential target is below p. Adjust upper bound.
|
|
268
|
-
u = p - 1
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
# TODO: This code uses a simple linear search to double check the above
|
|
272
|
-
# binary search. It can be removed once we know the above code always
|
|
273
|
-
# works properly.
|
|
274
|
-
line.each do |segment|
|
|
275
|
-
if overlaps?(probeSegment, segment)
|
|
276
|
-
raise "Binary search failed to find collision"
|
|
277
|
-
end
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
false
|
|
281
|
-
end
|
|
282
|
-
|
|
283
170
|
# This function is at the heart of the routing algorithm. It tries to find a
|
|
284
171
|
# place for the line described by _segment_ without overlapping with the
|
|
285
172
|
# defined zones. _horizontal_ determines whether the line is running
|
|
@@ -297,10 +184,9 @@ class TaskJuggler
|
|
|
297
184
|
|
|
298
185
|
# Make sure that the segment coordinates are in ascending order.
|
|
299
186
|
segment.sort!
|
|
300
|
-
lines = horizontal ? @hLines : @vLines
|
|
301
187
|
# TODO: Remove this check once the code becomes stable.
|
|
302
188
|
#checkLines(lines)
|
|
303
|
-
while collision?(
|
|
189
|
+
while @detector.collision?(pos, segment, horizontal)
|
|
304
190
|
pos += delta
|
|
305
191
|
# Check if we have exceded the chart area towards top/left.
|
|
306
192
|
if delta < 0
|
|
@@ -312,7 +198,6 @@ class TaskJuggler
|
|
|
312
198
|
break if pos >= (horizontal ? @height : @width)
|
|
313
199
|
end
|
|
314
200
|
end
|
|
315
|
-
doubleCheckLine(horizontal ? @hLines : @vLines, pos, segment)
|
|
316
201
|
pos
|
|
317
202
|
end
|
|
318
203
|
|
|
@@ -339,38 +224,24 @@ class TaskJuggler
|
|
|
339
224
|
end
|
|
340
225
|
end
|
|
341
226
|
|
|
342
|
-
# This
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
raise "Invalid segment [#{segment[0]}, #{segment[1]}]"
|
|
351
|
-
end
|
|
352
|
-
if v
|
|
353
|
-
raise "Segment sequence error" if v >= segment[0]
|
|
354
|
-
end
|
|
355
|
-
v = segment[1]
|
|
356
|
-
end
|
|
227
|
+
# This function makes sure that the rectangle described by _x_, _y_, _w_
|
|
228
|
+
# and _h_ is properly justfified. If the width or height are negative, _x_
|
|
229
|
+
# and _y_ are adjusted to describe the same rectangle with all positive
|
|
230
|
+
# coordinates.
|
|
231
|
+
def justify(x, y, w, h)
|
|
232
|
+
if w < 0
|
|
233
|
+
w = -w
|
|
234
|
+
x = x - w + 1
|
|
357
235
|
end
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
# the placed line at _pos_ and [ _lineSegment_[0], _lineSegment_[1] ]
|
|
362
|
-
# overlaps with a segment of _lines_.
|
|
363
|
-
def doubleCheckLine(lines, pos, lineSegment)
|
|
364
|
-
return if pos < 0 || lines[pos].nil?
|
|
365
|
-
lines[pos].each do |segment|
|
|
366
|
-
if overlaps?(lineSegment, segment)
|
|
367
|
-
raise "Internal router failure for #{lines == @vLines ? 'v' : 'h'}" +
|
|
368
|
-
"Line #{pos}: [#{lineSegment.join(', ')}] overlaps with " +
|
|
369
|
-
"[#{segment.join(', ')}]."
|
|
370
|
-
end
|
|
236
|
+
if h < 0
|
|
237
|
+
h = -h
|
|
238
|
+
y = y - h + 1
|
|
371
239
|
end
|
|
240
|
+
# Return the potentially adjusted rectangle coordinates.
|
|
241
|
+
return x, y, w, h
|
|
372
242
|
end
|
|
373
243
|
|
|
244
|
+
|
|
374
245
|
end
|
|
375
246
|
|
|
376
247
|
end
|