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/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
|