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