taskjuggler 0.0.2
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/COPYING +280 -0
- data/README +31 -0
- data/Rakefile +20 -0
- data/benchmarks/UTF-8-Strings.rb +58 -0
- data/benchmarks/allocate.tjp +30 -0
- data/benchmarks/booking.tjp +62 -0
- data/benchmarks/depends.tjp +112 -0
- data/benchmarks/htmltaskreport.tjp +45 -0
- data/benchmarks/runbench.rb +24 -0
- data/bin/tj3 +3 -0
- data/bin/tj3man +3 -0
- data/doc/classes/AppConfig.html +808 -0
- data/doc/classes/Arguments.html +226 -0
- data/doc/classes/String.html +395 -0
- data/doc/classes/TaskJuggler.html +1358 -0
- data/doc/classes/TaskJuggler/Account.html +257 -0
- data/doc/classes/TaskJuggler/AccountScenario.html +218 -0
- data/doc/classes/TaskJuggler/Allocation.html +419 -0
- data/doc/classes/TaskJuggler/AllocationAttribute.html +291 -0
- data/doc/classes/TaskJuggler/AttributeBase.html +608 -0
- data/doc/classes/TaskJuggler/AttributeDefinition.html +259 -0
- data/doc/classes/TaskJuggler/Booking.html +307 -0
- data/doc/classes/TaskJuggler/BookingListAttribute.html +263 -0
- data/doc/classes/TaskJuggler/BooleanAttribute.html +261 -0
- data/doc/classes/TaskJuggler/CSVFile.html +325 -0
- data/doc/classes/TaskJuggler/Charge.html +279 -0
- data/doc/classes/TaskJuggler/ChargeListAttribute.html +229 -0
- data/doc/classes/TaskJuggler/ChargeSet.html +440 -0
- data/doc/classes/TaskJuggler/ChargeSetListAttribute.html +276 -0
- data/doc/classes/TaskJuggler/ColumnTable.html +260 -0
- data/doc/classes/TaskJuggler/DateAttribute.html +194 -0
- data/doc/classes/TaskJuggler/DependencyListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/DurationAttribute.html +229 -0
- data/doc/classes/TaskJuggler/FixnumAttribute.html +194 -0
- data/doc/classes/TaskJuggler/FlagListAttribute.html +263 -0
- data/doc/classes/TaskJuggler/FloatAttribute.html +229 -0
- data/doc/classes/TaskJuggler/GanttChart.html +667 -0
- data/doc/classes/TaskJuggler/GanttContainer.html +441 -0
- data/doc/classes/TaskJuggler/GanttHeader.html +280 -0
- data/doc/classes/TaskJuggler/GanttHeaderScaleItem.html +245 -0
- data/doc/classes/TaskJuggler/GanttLine.html +398 -0
- data/doc/classes/TaskJuggler/GanttLoadStack.html +327 -0
- data/doc/classes/TaskJuggler/GanttMilestone.html +415 -0
- data/doc/classes/TaskJuggler/GanttRouter.html +425 -0
- data/doc/classes/TaskJuggler/GanttTaskBar.html +429 -0
- data/doc/classes/TaskJuggler/HTMLDocument.html +240 -0
- data/doc/classes/TaskJuggler/HTMLGraphics.html +231 -0
- data/doc/classes/TaskJuggler/Interval.html +552 -0
- data/doc/classes/TaskJuggler/IntervalListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/KeywordDocumentation.html +796 -0
- data/doc/classes/TaskJuggler/Limits.html +416 -0
- data/doc/classes/TaskJuggler/Limits/Limit.html +381 -0
- data/doc/classes/TaskJuggler/LimitsAttribute.html +261 -0
- data/doc/classes/TaskJuggler/Log.html +613 -0
- data/doc/classes/TaskJuggler/LogicalAttribute.html +226 -0
- data/doc/classes/TaskJuggler/LogicalExpression.html +251 -0
- data/doc/classes/TaskJuggler/LogicalFlag.html +229 -0
- data/doc/classes/TaskJuggler/LogicalFunction.html +324 -0
- data/doc/classes/TaskJuggler/LogicalOperation.html +299 -0
- data/doc/classes/TaskJuggler/Macro.html +194 -0
- data/doc/classes/TaskJuggler/MacroParser.html +360 -0
- data/doc/classes/TaskJuggler/MacroTable.html +366 -0
- data/doc/classes/TaskJuggler/Message.html +281 -0
- data/doc/classes/TaskJuggler/MessageHandler.html +215 -0
- data/doc/classes/TaskJuggler/Project.html +1606 -0
- data/doc/classes/TaskJuggler/ProjectFileParser.html +412 -0
- data/doc/classes/TaskJuggler/PropertyList.html +597 -0
- data/doc/classes/TaskJuggler/PropertySet.html +1200 -0
- data/doc/classes/TaskJuggler/PropertyTreeNode.html +1449 -0
- data/doc/classes/TaskJuggler/Query.html +600 -0
- data/doc/classes/TaskJuggler/RealFormat.html +252 -0
- data/doc/classes/TaskJuggler/ReferenceAttribute.html +194 -0
- data/doc/classes/TaskJuggler/Report.html +528 -0
- data/doc/classes/TaskJuggler/ReportElement.html +1070 -0
- data/doc/classes/TaskJuggler/ReportTable.html +497 -0
- data/doc/classes/TaskJuggler/ReportTableCell.html +518 -0
- data/doc/classes/TaskJuggler/ReportTableColumn.html +364 -0
- data/doc/classes/TaskJuggler/ReportTableElement.html +644 -0
- data/doc/classes/TaskJuggler/ReportTableLegend.html +343 -0
- data/doc/classes/TaskJuggler/ReportTableLine.html +431 -0
- data/doc/classes/TaskJuggler/Resource.html +211 -0
- data/doc/classes/TaskJuggler/ResourceListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/ResourceListRE.html +249 -0
- data/doc/classes/TaskJuggler/ResourceScenario.html +1137 -0
- data/doc/classes/TaskJuggler/RichText.html +537 -0
- data/doc/classes/TaskJuggler/RichTextAttribute.html +229 -0
- data/doc/classes/TaskJuggler/RichTextDocument.html +418 -0
- data/doc/classes/TaskJuggler/RichTextElement.html +829 -0
- data/doc/classes/TaskJuggler/RichTextException.html +212 -0
- data/doc/classes/TaskJuggler/RichTextParser.html +317 -0
- data/doc/classes/TaskJuggler/RichTextProtocolExample.html +303 -0
- data/doc/classes/TaskJuggler/RichTextProtocolHandler.html +194 -0
- data/doc/classes/TaskJuggler/RichTextScanner.html +561 -0
- data/doc/classes/TaskJuggler/RichTextSnip.html +364 -0
- data/doc/classes/TaskJuggler/RichTextSyntaxRules.html +883 -0
- data/doc/classes/TaskJuggler/Scenario.html +163 -0
- data/doc/classes/TaskJuggler/ScenarioData.html +354 -0
- data/doc/classes/TaskJuggler/Scoreboard.html +638 -0
- data/doc/classes/TaskJuggler/Shift.html +255 -0
- data/doc/classes/TaskJuggler/ShiftAssignment.html +488 -0
- data/doc/classes/TaskJuggler/ShiftAssignments.html +715 -0
- data/doc/classes/TaskJuggler/ShiftAssignmentsAttribute.html +261 -0
- data/doc/classes/TaskJuggler/ShiftScenario.html +282 -0
- data/doc/classes/TaskJuggler/SourceFileInfo.html +247 -0
- data/doc/classes/TaskJuggler/StringAttribute.html +229 -0
- data/doc/classes/TaskJuggler/SymbolAttribute.html +194 -0
- data/doc/classes/TaskJuggler/SyntaxReference.html +516 -0
- data/doc/classes/TaskJuggler/TOCEntry.html +242 -0
- data/doc/classes/TaskJuggler/TableColumnDefinition.html +273 -0
- data/doc/classes/TaskJuggler/TableOfContents.html +256 -0
- data/doc/classes/TaskJuggler/Task.html +203 -0
- data/doc/classes/TaskJuggler/TaskDependency.html +251 -0
- data/doc/classes/TaskJuggler/TaskListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/TaskListRE.html +250 -0
- data/doc/classes/TaskJuggler/TaskScenario.html +2206 -0
- data/doc/classes/TaskJuggler/TextParser.html +670 -0
- data/doc/classes/TaskJuggler/TextParser/Pattern.html +923 -0
- data/doc/classes/TaskJuggler/TextParser/Rule.html +779 -0
- data/doc/classes/TaskJuggler/TextParser/StackElement.html +267 -0
- data/doc/classes/TaskJuggler/TextParser/TextParserResultArray.html +212 -0
- data/doc/classes/TaskJuggler/TextParser/TokenDoc.html +221 -0
- data/doc/classes/TaskJuggler/TextScanner.html +708 -0
- data/doc/classes/TaskJuggler/TextScanner/BufferStreamHandle.html +355 -0
- data/doc/classes/TaskJuggler/TextScanner/FileStreamHandle.html +341 -0
- data/doc/classes/TaskJuggler/TextScanner/StreamHandle.html +260 -0
- data/doc/classes/TaskJuggler/TjException.html +185 -0
- data/doc/classes/TaskJuggler/TjTime.html +1845 -0
- data/doc/classes/TaskJuggler/TjpExample.html +310 -0
- data/doc/classes/TaskJuggler/TjpExportRE.html +329 -0
- data/doc/classes/TaskJuggler/TjpSyntaxRules.html +8928 -0
- data/doc/classes/TaskJuggler/UserManual.html +606 -0
- data/doc/classes/TaskJuggler/WorkingHours.html +582 -0
- data/doc/classes/TaskJuggler/WorkingHoursAttribute.html +284 -0
- data/doc/classes/TaskJuggler/XMLBlob.html +207 -0
- data/doc/classes/TaskJuggler/XMLComment.html +206 -0
- data/doc/classes/TaskJuggler/XMLDocument.html +293 -0
- data/doc/classes/TaskJuggler/XMLElement.html +341 -0
- data/doc/classes/TaskJuggler/XMLNamedText.html +174 -0
- data/doc/classes/TaskJuggler/XMLText.html +221 -0
- data/doc/files/COPYING.html +448 -0
- data/doc/files/README.html +134 -0
- data/doc/files/lib/AccountScenario_rb.html +116 -0
- data/doc/files/lib/Account_rb.html +118 -0
- data/doc/files/lib/Allocation_rb.html +118 -0
- data/doc/files/lib/AppConfig_rb.html +116 -0
- data/doc/files/lib/AttributeBase_rb.html +106 -0
- data/doc/files/lib/AttributeDefinition_rb.html +106 -0
- data/doc/files/lib/Attributes_rb.html +130 -0
- data/doc/files/lib/Booking_rb.html +106 -0
- data/doc/files/lib/ChargeSet_rb.html +116 -0
- data/doc/files/lib/Charge_rb.html +116 -0
- data/doc/files/lib/HTMLDocument_rb.html +116 -0
- data/doc/files/lib/Interval_rb.html +116 -0
- data/doc/files/lib/KeywordDocumentation_rb.html +122 -0
- data/doc/files/lib/Limits_rb.html +116 -0
- data/doc/files/lib/Log_rb.html +116 -0
- data/doc/files/lib/LogicalExpression_rb.html +122 -0
- data/doc/files/lib/LogicalFlag_rb.html +116 -0
- data/doc/files/lib/LogicalFunction_rb.html +116 -0
- data/doc/files/lib/LogicalOperation_rb.html +116 -0
- data/doc/files/lib/MacroParser_rb.html +118 -0
- data/doc/files/lib/MacroTable_rb.html +122 -0
- data/doc/files/lib/MessageHandler_rb.html +106 -0
- data/doc/files/lib/Message_rb.html +116 -0
- data/doc/files/lib/ProjectFileParser_rb.html +122 -0
- data/doc/files/lib/Project_rb.html +148 -0
- data/doc/files/lib/PropertyList_rb.html +106 -0
- data/doc/files/lib/PropertySet_rb.html +118 -0
- data/doc/files/lib/PropertyTreeNode_rb.html +106 -0
- data/doc/files/lib/Query_rb.html +116 -0
- data/doc/files/lib/RealFormat_rb.html +106 -0
- data/doc/files/lib/ResourceScenario_rb.html +116 -0
- data/doc/files/lib/Resource_rb.html +118 -0
- data/doc/files/lib/RichTextDocument_rb.html +120 -0
- data/doc/files/lib/RichTextElement_rb.html +120 -0
- data/doc/files/lib/RichTextParser_rb.html +120 -0
- data/doc/files/lib/RichTextProtocolExample_rb.html +120 -0
- data/doc/files/lib/RichTextProtocolHandler_rb.html +106 -0
- data/doc/files/lib/RichTextScanner_rb.html +116 -0
- data/doc/files/lib/RichTextSnip_rb.html +118 -0
- data/doc/files/lib/RichTextSyntaxRules_rb.html +106 -0
- data/doc/files/lib/RichText_rb.html +118 -0
- data/doc/files/lib/ScenarioData_rb.html +118 -0
- data/doc/files/lib/Scenario_rb.html +116 -0
- data/doc/files/lib/Scoreboard_rb.html +106 -0
- data/doc/files/lib/ShiftAssignments_rb.html +116 -0
- data/doc/files/lib/ShiftScenario_rb.html +116 -0
- data/doc/files/lib/Shift_rb.html +118 -0
- data/doc/files/lib/SourceFileInfo_rb.html +106 -0
- data/doc/files/lib/SyntaxReference_rb.html +122 -0
- data/doc/files/lib/TOCEntry_rb.html +118 -0
- data/doc/files/lib/TableColumnDefinition_rb.html +106 -0
- data/doc/files/lib/TableOfContents_rb.html +118 -0
- data/doc/files/lib/TaskDependency_rb.html +106 -0
- data/doc/files/lib/TaskJuggler_rb.html +120 -0
- data/doc/files/lib/TaskScenario_rb.html +116 -0
- data/doc/files/lib/Task_rb.html +118 -0
- data/doc/files/lib/TextParser/Pattern_rb.html +116 -0
- data/doc/files/lib/TextParser/Rule_rb.html +106 -0
- data/doc/files/lib/TextParser/StackElement_rb.html +106 -0
- data/doc/files/lib/TextParser/TokenDoc_rb.html +106 -0
- data/doc/files/lib/TextParser_rb.html +124 -0
- data/doc/files/lib/TextScanner_rb.html +128 -0
- data/doc/files/lib/Tj3Config_rb.html +118 -0
- data/doc/files/lib/TjException_rb.html +106 -0
- data/doc/files/lib/TjTime_rb.html +118 -0
- data/doc/files/lib/TjpExample_rb.html +116 -0
- data/doc/files/lib/TjpSyntaxRules_rb.html +106 -0
- data/doc/files/lib/UTF8String_rb.html +132 -0
- data/doc/files/lib/UserManual_rb.html +124 -0
- data/doc/files/lib/WorkingHours_rb.html +116 -0
- data/doc/files/lib/XMLDocument_rb.html +116 -0
- data/doc/files/lib/XMLElement_rb.html +116 -0
- data/doc/files/lib/reports/CSVFile_rb.html +116 -0
- data/doc/files/lib/reports/ColumnTable_rb.html +116 -0
- data/doc/files/lib/reports/GanttChart_rb.html +122 -0
- data/doc/files/lib/reports/GanttContainer_rb.html +116 -0
- data/doc/files/lib/reports/GanttHeaderScaleItem_rb.html +106 -0
- data/doc/files/lib/reports/GanttHeader_rb.html +116 -0
- data/doc/files/lib/reports/GanttLine_rb.html +126 -0
- data/doc/files/lib/reports/GanttLoadStack_rb.html +116 -0
- data/doc/files/lib/reports/GanttMilestone_rb.html +116 -0
- data/doc/files/lib/reports/GanttRouter_rb.html +106 -0
- data/doc/files/lib/reports/GanttTaskBar_rb.html +116 -0
- data/doc/files/lib/reports/HTMLGraphics_rb.html +106 -0
- data/doc/files/lib/reports/ReportElement_rb.html +118 -0
- data/doc/files/lib/reports/ReportTableCell_rb.html +106 -0
- data/doc/files/lib/reports/ReportTableColumn_rb.html +106 -0
- data/doc/files/lib/reports/ReportTableElement_rb.html +122 -0
- data/doc/files/lib/reports/ReportTableLegend_rb.html +106 -0
- data/doc/files/lib/reports/ReportTableLine_rb.html +116 -0
- data/doc/files/lib/reports/ReportTable_rb.html +118 -0
- data/doc/files/lib/reports/Report_rb.html +126 -0
- data/doc/files/lib/reports/ResourceListRE_rb.html +122 -0
- data/doc/files/lib/reports/TaskListRE_rb.html +122 -0
- data/doc/files/lib/reports/TjpExportRE_rb.html +116 -0
- data/doc/files/lib/taskjuggler3_rb.html +276 -0
- data/doc/files/lib/tj3man_rb.html +189 -0
- data/doc/fr_class_index.html +285 -0
- data/doc/fr_file_index.html +223 -0
- data/doc/fr_method_index.html +1953 -0
- data/doc/index.html +21 -0
- data/doc/rdoc-style.css +299 -0
- data/examples/tutorial.tjp +361 -0
- data/gem_spec.rb +30 -0
- data/lib/Account.rb +50 -0
- data/lib/AccountScenario.rb +39 -0
- data/lib/Allocation.rb +102 -0
- data/lib/AppConfig.rb +134 -0
- data/lib/AttributeBase.rb +131 -0
- data/lib/AttributeDefinition.rb +47 -0
- data/lib/Attributes.rb +478 -0
- data/lib/BatchProcessor.rb +209 -0
- data/lib/Booking.rb +59 -0
- data/lib/Charge.rb +71 -0
- data/lib/ChargeSet.rb +126 -0
- data/lib/HTMLDocument.rb +59 -0
- data/lib/Interval.rb +127 -0
- data/lib/KeywordDocumentation.rb +560 -0
- data/lib/Limits.rb +219 -0
- data/lib/Log.rb +160 -0
- data/lib/LogicalExpression.rb +71 -0
- data/lib/LogicalFlag.rb +34 -0
- data/lib/LogicalFunction.rb +102 -0
- data/lib/LogicalOperation.rb +118 -0
- data/lib/MacroParser.rb +77 -0
- data/lib/MacroTable.rb +84 -0
- data/lib/Message.rb +56 -0
- data/lib/MessageHandler.rb +34 -0
- data/lib/Project.rb +662 -0
- data/lib/ProjectFileParser.rb +333 -0
- data/lib/PropertyList.rb +181 -0
- data/lib/PropertySet.rb +304 -0
- data/lib/PropertyTreeNode.rb +461 -0
- data/lib/Query.rb +227 -0
- data/lib/RealFormat.rb +73 -0
- data/lib/Resource.rb +42 -0
- data/lib/ResourceScenario.rb +511 -0
- data/lib/RichText.rb +147 -0
- data/lib/RichTextDocument.rb +139 -0
- data/lib/RichTextElement.rb +391 -0
- data/lib/RichTextParser.rb +66 -0
- data/lib/RichTextProtocolExample.rb +65 -0
- data/lib/RichTextProtocolHandler.rb +35 -0
- data/lib/RichTextScanner.rb +390 -0
- data/lib/RichTextSnip.rb +104 -0
- data/lib/RichTextSyntaxRules.rb +265 -0
- data/lib/Scenario.rb +27 -0
- data/lib/ScenarioData.rb +65 -0
- data/lib/Scoreboard.rb +141 -0
- data/lib/Shift.rb +48 -0
- data/lib/ShiftAssignments.rb +291 -0
- data/lib/ShiftScenario.rb +46 -0
- data/lib/SourceFileInfo.rb +37 -0
- data/lib/SyntaxReference.rb +284 -0
- data/lib/TOCEntry.rb +76 -0
- data/lib/TableColumnDefinition.rb +54 -0
- data/lib/TableOfContents.rb +46 -0
- data/lib/Task.rb +37 -0
- data/lib/TaskDependency.rb +39 -0
- data/lib/TaskJuggler.rb +84 -0
- data/lib/TaskScenario.rb +1622 -0
- data/lib/TextParser.rb +416 -0
- data/lib/TextParser/Pattern.rb +263 -0
- data/lib/TextParser/Rule.rb +171 -0
- data/lib/TextParser/StackElement.rb +45 -0
- data/lib/TextParser/TokenDoc.rb +38 -0
- data/lib/TextScanner.rb +682 -0
- data/lib/Tj3Config.rb +27 -0
- data/lib/TjException.rb +27 -0
- data/lib/TjTime.rb +395 -0
- data/lib/TjpExample.rb +119 -0
- data/lib/TjpSyntaxRules.rb +4022 -0
- data/lib/UTF8String.rb +100 -0
- data/lib/UserManual.rb +282 -0
- data/lib/WorkingHours.rb +323 -0
- data/lib/XMLDocument.rb +54 -0
- data/lib/XMLElement.rb +175 -0
- data/lib/reports/CSVFile.rb +146 -0
- data/lib/reports/ColumnTable.rb +66 -0
- data/lib/reports/GanttChart.rb +308 -0
- data/lib/reports/GanttContainer.rb +107 -0
- data/lib/reports/GanttHeader.rb +141 -0
- data/lib/reports/GanttHeaderScaleItem.rb +42 -0
- data/lib/reports/GanttLine.rb +329 -0
- data/lib/reports/GanttLoadStack.rb +113 -0
- data/lib/reports/GanttMilestone.rb +80 -0
- data/lib/reports/GanttRouter.rb +375 -0
- data/lib/reports/GanttTaskBar.rb +95 -0
- data/lib/reports/HTMLGraphics.rb +65 -0
- data/lib/reports/Report.rb +344 -0
- data/lib/reports/ReportElement.rb +427 -0
- data/lib/reports/ReportTable.rb +144 -0
- data/lib/reports/ReportTableCell.rb +142 -0
- data/lib/reports/ReportTableColumn.rb +82 -0
- data/lib/reports/ReportTableElement.rb +852 -0
- data/lib/reports/ReportTableLegend.rb +167 -0
- data/lib/reports/ReportTableLine.rb +87 -0
- data/lib/reports/ResourceListRE.rb +72 -0
- data/lib/reports/TaskListRE.rb +73 -0
- data/lib/reports/TjpExportRE.rb +394 -0
- data/lib/taskjuggler3.rb +106 -0
- data/lib/tj3man.rb +88 -0
- data/manual/Day_To_Day_Juggling +168 -0
- data/manual/Getting_Started +61 -0
- data/manual/How_To_Contribute +185 -0
- data/manual/Installation +68 -0
- data/manual/Intro +102 -0
- data/manual/Reporting_Bugs +26 -0
- data/manual/Rich_Text_Attributes +90 -0
- data/manual/TaskJuggler_2x_Migration +40 -0
- data/manual/Tutorial +579 -0
- data/manual/fdl +450 -0
- data/prj_cfg.rb +43 -0
- data/setup.rb +1585 -0
- data/tasks/csts.rake +72 -0
- data/tasks/gem.rake +14 -0
- data/tasks/manual.rake +10 -0
- data/tasks/missing.rake +21 -0
- data/tasks/rcov.rake +14 -0
- data/tasks/rdoc.rake +17 -0
- data/tasks/rexml_fix.rb +16 -0
- data/tasks/rexml_fix_19.rb +49 -0
- data/tasks/show.rake +21 -0
- data/tasks/stats.rake +25 -0
- data/tasks/test.rake +11 -0
- data/test/MessageChecker.rb +53 -0
- data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/celltext.tjp +7 -0
- data/test/TestSuite/CSV-Reports/genrefs +6 -0
- data/test/TestSuite/CSV-Reports/project-1.tji +57 -0
- data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -0
- data/test/TestSuite/CSV-Reports/resourcereport.tjp +10 -0
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -0
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks.tjp +11 -0
- data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortByTree.tjp +8 -0
- data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortBy_duration.down.tjp +10 -0
- data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortBy_effort.up.tjp +10 -0
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down.tjp +10 -0
- data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/taskreport.tjp +10 -0
- data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +24 -0
- data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +11 -0
- data/test/TestSuite/Scheduler/Correct/Allocate.tjp +86 -0
- data/test/TestSuite/Scheduler/Correct/AutomaticMilestones.tjp +63 -0
- data/test/TestSuite/Scheduler/Correct/Booking.tjp +161 -0
- data/test/TestSuite/Scheduler/Correct/Depends.tjp +50 -0
- data/test/TestSuite/Scheduler/Correct/Duration.tjp +34 -0
- data/test/TestSuite/Scheduler/Correct/InheritStartEnd.tjp +129 -0
- data/test/TestSuite/Scheduler/Correct/Limits.tjp +81 -0
- data/test/TestSuite/Scheduler/Correct/MultipleMandatories.tjp +43 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-1.tjp +28 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-2.tjp +33 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-3.tjp +33 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-4.tjp +34 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-5.tjp +62 -0
- data/test/TestSuite/Scheduler/Correct/Precedes.tjp +50 -0
- data/test/TestSuite/Scheduler/Correct/Shift.tjp +102 -0
- data/test/TestSuite/Scheduler/Errors/account_no_leaf.tjp +13 -0
- data/test/TestSuite/Scheduler/Errors/booking_conflict.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/booking_no_duty.tjp +9 -0
- data/test/TestSuite/Scheduler/Errors/booking_on_vacation.tjp +9 -0
- data/test/TestSuite/Scheduler/Errors/container_booking.tjp +14 -0
- data/test/TestSuite/Scheduler/Errors/container_duration.tjp +11 -0
- data/test/TestSuite/Scheduler/Errors/effort_no_allocations.tjp +7 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_1.tjp +19 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_10.tjp +36 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_11.tjp +27 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_12.tjp +20 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_13.tjp +27 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_14.tjp +26 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_2.tjp +24 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_3.tjp +18 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_4.tjp +36 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_5.tjp +37 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_6.tjp +35 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_7.tjp +46 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_8.tjp +51 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_9.tjp +20 -0
- data/test/TestSuite/Scheduler/Errors/maxend.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/maxstart.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/milestone_booking.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/milestone_duration.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/milestone_start_end.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/minend.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/minstart.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/multiple_durations.tjp +11 -0
- data/test/TestSuite/Scheduler/Errors/no_tasks.tjp +6 -0
- data/test/TestSuite/Scheduler/Errors/not_scheduled.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_child.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_multi.tjp +13 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_parent.tjp +11 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_self.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_unknown.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/task_overspecified_1.tjp +9 -0
- data/test/TestSuite/Scheduler/Errors/task_overspecified_2.tjp +14 -0
- data/test/TestSuite/Scheduler/Errors/task_overspecified_3.tjp +14 -0
- data/test/TestSuite/Scheduler/Errors/task_underspecified_1.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/task_underspecified_2.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/task_underspecified_3.tjp +9 -0
- data/test/TestSuite/Syntax/Correct/Account.tjp +53 -0
- data/test/TestSuite/Syntax/Correct/Allocate-1.tjp +24 -0
- data/test/TestSuite/Syntax/Correct/Alternative.tjp +13 -0
- data/test/TestSuite/Syntax/Correct/AutoMacros.tjp +14 -0
- data/test/TestSuite/Syntax/Correct/Booking.tjp +26 -0
- data/test/TestSuite/Syntax/Correct/Caption.tjp +33 -0
- data/test/TestSuite/Syntax/Correct/Celltext.tjp +28 -0
- data/test/TestSuite/Syntax/Correct/Comments.tjp +29 -0
- data/test/TestSuite/Syntax/Correct/Complete.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/CompletedWork.tji +20 -0
- data/test/TestSuite/Syntax/Correct/CriticalPath.tjp +31 -0
- data/test/TestSuite/Syntax/Correct/Currencyformat.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/CustomAttributes.tjp +14 -0
- data/test/TestSuite/Syntax/Correct/Depends1.tjp +22 -0
- data/test/TestSuite/Syntax/Correct/Durations.tjp +29 -0
- data/test/TestSuite/Syntax/Correct/Efficiency.tjp +19 -0
- data/test/TestSuite/Syntax/Correct/Export.tjp +40 -0
- data/test/TestSuite/Syntax/Correct/Flags.tjp +32 -0
- data/test/TestSuite/Syntax/Correct/Freeze.tjp +28 -0
- data/test/TestSuite/Syntax/Correct/Gap.tjp +15 -0
- data/test/TestSuite/Syntax/Correct/HtmlTaskReport.tjp +33 -0
- data/test/TestSuite/Syntax/Correct/Limits-1.tjp +71 -0
- data/test/TestSuite/Syntax/Correct/LoadUnits.tjp +31 -0
- data/test/TestSuite/Syntax/Correct/Macro-1.tjp +19 -0
- data/test/TestSuite/Syntax/Correct/Mandatory.tjp +17 -0
- data/test/TestSuite/Syntax/Correct/Milestone.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/MinMax.tjp +17 -0
- data/test/TestSuite/Syntax/Correct/Numberformat.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/Period.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/Persistent.tjp +11 -0
- data/test/TestSuite/Syntax/Correct/Precedes1.tjp +17 -0
- data/test/TestSuite/Syntax/Correct/Priority.tjp +30 -0
- data/test/TestSuite/Syntax/Correct/Project.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/ProjectIDs.tjp +23 -0
- data/test/TestSuite/Syntax/Correct/RawHTML.tjp +29 -0
- data/test/TestSuite/Syntax/Correct/Reports.tjp +54 -0
- data/test/TestSuite/Syntax/Correct/Resource.tjp +20 -0
- data/test/TestSuite/Syntax/Correct/Responsible.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/Scenario.tjp +15 -0
- data/test/TestSuite/Syntax/Correct/Scheduling.tjp +26 -0
- data/test/TestSuite/Syntax/Correct/Select.tjp +27 -0
- data/test/TestSuite/Syntax/Correct/Shift.tjp +55 -0
- data/test/TestSuite/Syntax/Correct/Simple.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/String.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/Supplement.tjp +24 -0
- data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +34 -0
- data/test/TestSuite/Syntax/Correct/TimeFrame.tjp +19 -0
- data/test/TestSuite/Syntax/Correct/Timezone.tjp +8 -0
- data/test/TestSuite/Syntax/Correct/Vacation.tjp +33 -0
- data/test/TestSuite/Syntax/Correct/csvtest +16 -0
- data/test/TestSuite/Syntax/Correct/manual2example.rb +24 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +485 -0
- data/test/TestSuite/Syntax/Errors/bad_include.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/booking_group.tjp +14 -0
- data/test/TestSuite/Syntax/Errors/booking_milestone.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/booking_no_leaf.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/chargeset.tjp +14 -0
- data/test/TestSuite/Syntax/Errors/chargeset_master.tjp +15 -0
- data/test/TestSuite/Syntax/Errors/container_attribute.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/cost_acct_no_top.tjp +24 -0
- data/test/TestSuite/Syntax/Errors/cost_rev_same.tjp +24 -0
- data/test/TestSuite/Syntax/Errors/date_in_range.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/effort_zero.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/empty.tjp +1 -0
- data/test/TestSuite/Syntax/Errors/export_bad_extn.tjp +9 -0
- data/test/TestSuite/Syntax/Errors/extend_id_cap.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/interval_end_in_range.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/interval_start_in_range.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/leaf_resource_id_expected.tjp +12 -0
- data/test/TestSuite/Syntax/Errors/misaligned_date.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/no_csv_suffix.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/no_html_suffix.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/operand_attribute.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/operand_unkn_flag.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/operand_unkn_scen.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/overtime_range.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/purge_no_list.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/purge_unknown_id.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/report_end.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/report_redifinition.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/report_start.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/resource_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/resource_id_expected.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/rev_acct_no_top.tjp +24 -0
- data/test/TestSuite/Syntax/Errors/scenario_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/shift_assignment_overlap.tjp +15 -0
- data/test/TestSuite/Syntax/Errors/shift_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/shift_id_expected.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/sloppy_range.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/sort_direction.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sort_unknown_scen.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sorting_crit_exptd1.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sorting_crit_exptd2.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sorting_wbs.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/start_before_end1.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/start_before_end2.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/task_complete.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/task_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/task_priority.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/task_without_chargeset.tjp +9 -0
- data/test/TestSuite/Syntax/Errors/time_interval.tjp +12 -0
- data/test/TestSuite/Syntax/Errors/too_many_bangs.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/undecl_flag.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/unknown_projectid.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/unknown_scenario_id.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/unknown_scenario_idx.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/unknown_task.tjp +10 -0
- data/test/all.rb +31 -0
- data/test/test_BatchProcessor.rb +54 -0
- data/test/test_CSV-Reports.rb +101 -0
- data/test/test_Limits.rb +104 -0
- data/test/test_LogicalExpression.rb +110 -0
- data/test/test_MacroTable.rb +51 -0
- data/test/test_Project.rb +57 -0
- data/test/test_PropertySet.rb +71 -0
- data/test/test_Query.rb +83 -0
- data/test/test_RealFormat.rb +83 -0
- data/test/test_RichText.rb +869 -0
- data/test/test_Scheduler.rb +42 -0
- data/test/test_ShiftAssignments.rb +77 -0
- data/test/test_Syntax.rb +41 -0
- data/test/test_TextScanner.rb +95 -0
- data/test/test_TjTime.rb +114 -0
- data/test/test_TjpExample.rb +169 -0
- data/test/test_UTF8String.rb +84 -0
- data/test/test_WorkingHours.rb +56 -0
- metadata +649 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = GanttLoadStack.rb -- The TaskJuggler III Project Management Software
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009 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
|
+
# The GanttLoadStack is a simple stack diagram that shows the relative shares
|
|
18
|
+
# of the values. The stack is always normed to the line height.
|
|
19
|
+
class GanttLoadStack
|
|
20
|
+
|
|
21
|
+
include HTMLGraphics
|
|
22
|
+
|
|
23
|
+
# Create a GanttLoadStack object based on the following information: _line_
|
|
24
|
+
# is a reference to the GanttLine. _x_ is the left edge in chart coordinates
|
|
25
|
+
# and _w_ is the stack width. _values_ are the values to be displayed and
|
|
26
|
+
# _categories_ determines the color for each of the values.
|
|
27
|
+
def initialize(line, x, w, values, categories)
|
|
28
|
+
@line = line
|
|
29
|
+
@lineHeight = line.height
|
|
30
|
+
@x = x
|
|
31
|
+
@y = @line.y
|
|
32
|
+
@w = w
|
|
33
|
+
@drawFrame = false
|
|
34
|
+
if values.length != categories.length
|
|
35
|
+
raise "Values and categories must have the same number of entries!"
|
|
36
|
+
end
|
|
37
|
+
@categories = categories
|
|
38
|
+
i = 0
|
|
39
|
+
@categories.each do |cat|
|
|
40
|
+
if cat.nil? && values[i] > 0
|
|
41
|
+
@drawFrame = true
|
|
42
|
+
break
|
|
43
|
+
end
|
|
44
|
+
i += 1
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Convert the values to chart Y coordinates and store them in yLevels.
|
|
48
|
+
sum = 0
|
|
49
|
+
values.each { |v| sum += v }
|
|
50
|
+
# If the sum is 0, all yLevels values must be 0 as well.
|
|
51
|
+
if sum == 0
|
|
52
|
+
@yLevels = nil
|
|
53
|
+
@drawFrame = true
|
|
54
|
+
else
|
|
55
|
+
@yLevels = []
|
|
56
|
+
values.each do |v|
|
|
57
|
+
# We leave 1 pixel to the top and bottom of the line and need 1 pixel
|
|
58
|
+
# for the frame.
|
|
59
|
+
@yLevels << (@lineHeight - 4) * v / sum
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def addBlockedZones(router)
|
|
65
|
+
# Horizontal block
|
|
66
|
+
router.addZone(@x - 2, @y, @w + 4, @lineHeight, true, false)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Convert the abstact representation of the GanttLoadStack into HTML
|
|
70
|
+
# elements.
|
|
71
|
+
def to_html
|
|
72
|
+
# Draw nothing if all values are 0.
|
|
73
|
+
return nil unless @yLevels
|
|
74
|
+
|
|
75
|
+
html = []
|
|
76
|
+
# Draw a background rectable to create a frame. In case the frame is not
|
|
77
|
+
# fully filled by the stack, we need to draw a real frame to keep the
|
|
78
|
+
# background.
|
|
79
|
+
if @drawFrame
|
|
80
|
+
# Top frame line
|
|
81
|
+
html << @line.lineToHTML(@x, 1, @x + @w - 1, 1, 'loadstackframe')
|
|
82
|
+
# Bottom frame line
|
|
83
|
+
html << @line.lineToHTML(@x, @lineHeight - 2, @x + @w - 1,
|
|
84
|
+
@lineHeight - 2, 'loadstackframe')
|
|
85
|
+
# Left frame line
|
|
86
|
+
html << @line.lineToHTML(@x, 1, @x, @lineHeight - 2, 'loadstackframe')
|
|
87
|
+
# Right frame line
|
|
88
|
+
html << @line.lineToHTML(@x + @w - 1, 1, @x + @w - 1, @lineHeight - 2,
|
|
89
|
+
'loadstackframe')
|
|
90
|
+
else
|
|
91
|
+
html << @line.rectToHTML(@x, 1, @w, @lineHeight - 2,
|
|
92
|
+
'loadstackframe')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
yPos = 2
|
|
96
|
+
# Than draw the slighly narrower bars as a pile ontop of it.
|
|
97
|
+
(@yLevels.length - 1).downto(0) do |i|
|
|
98
|
+
next if @yLevels[i] <= 0
|
|
99
|
+
if @categories[i]
|
|
100
|
+
html << @line.rectToHTML(@x + 1, yPos.to_i, @w - 2,
|
|
101
|
+
(yPos + @yLevels[i]).to_i - yPos.to_i,
|
|
102
|
+
@categories[i])
|
|
103
|
+
end
|
|
104
|
+
yPos += @yLevels[i]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
html
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = GanttMilestone.rb -- The TaskJuggler III Project Management Software
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009 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
|
+
# The GanttMilestone represents a milestone task.
|
|
18
|
+
class GanttMilestone
|
|
19
|
+
|
|
20
|
+
include HTMLGraphics
|
|
21
|
+
|
|
22
|
+
# The size of the milestone symbol measured from the center to the tips.
|
|
23
|
+
@@size = 6
|
|
24
|
+
|
|
25
|
+
# Create a GanttMilestone object based on the following information: _task_
|
|
26
|
+
# is a reference to the Task to be displayed. _lineHeight_ is the height of
|
|
27
|
+
# the line this milestone is shown in. _x_ and _y_ are the coordinates of
|
|
28
|
+
# the center of the milestone in the GanttChart.
|
|
29
|
+
def initialize(task, lineHeight, x, y)
|
|
30
|
+
@task = task
|
|
31
|
+
@lineHeight = lineHeight
|
|
32
|
+
@x = x
|
|
33
|
+
@y = y
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Return the point [ x, y ] where task start dependency lines should start
|
|
37
|
+
# from.
|
|
38
|
+
def startDepLineStart
|
|
39
|
+
[ @x + @@size, @y + @lineHeight / 2 ]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Return the point [ x, y ] where task start dependency lines should end at.
|
|
43
|
+
def startDepLineEnd
|
|
44
|
+
[ @x - @@size, @y + @lineHeight / 2 ]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Return the point [ x, y ] where task end dependency lines should start
|
|
48
|
+
# from.
|
|
49
|
+
def endDepLineStart
|
|
50
|
+
[ @x + @@size , @y + @lineHeight / 2 ]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Return the point [ x, y ] where task end dependency lines should end at.
|
|
54
|
+
def endDepLineEnd
|
|
55
|
+
[ @x + @@size, @y + @lineHeight / 2 ]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def addBlockedZones(router)
|
|
59
|
+
router.addZone(@x - @@size - 2, @y + (@lineHeight / 2) - @@size - 2,
|
|
60
|
+
2 * @@size + 5, 2 * @@size + 5, true, true)
|
|
61
|
+
# Block for arrowhead.
|
|
62
|
+
router.addZone(@x - @@size - 9, @y + (@lineHeight / 2) - 7, 10, 15,
|
|
63
|
+
true, true)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Convert the abstact representation of the GanttMilestone into HTML
|
|
67
|
+
# elements.
|
|
68
|
+
def to_html
|
|
69
|
+
html = []
|
|
70
|
+
(@@size + 1).times do |i|
|
|
71
|
+
html << rectToHTML(@x - (@@size - 1) + i, (@lineHeight / 2) - i,
|
|
72
|
+
2 * (@@size - i) + 1, 2 * i + 1, 'milestone')
|
|
73
|
+
end
|
|
74
|
+
html
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = GanttRouter.rb -- The TaskJuggler III Project Management Software
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009 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
|
+
class TaskJuggler
|
|
14
|
+
|
|
15
|
+
# The GanttRouter is used by the GanttChart to route the dependency lines from
|
|
16
|
+
# the start to the end point. The chart is a rectangular area with a certain
|
|
17
|
+
# width and height. The graphical elements of the Gantt chart can be
|
|
18
|
+
# registered as don't-cross-zones. These zones block the either horizontal or
|
|
19
|
+
# vertical lines (or both) from crossing the zone. Zones can be registered by
|
|
20
|
+
# calling addZone(). The route() method returns routed path from start to end
|
|
21
|
+
# point.
|
|
22
|
+
class GanttRouter
|
|
23
|
+
|
|
24
|
+
include HTMLGraphics
|
|
25
|
+
|
|
26
|
+
# Create a GanttRouter object. _width_ and _height_ describe the size of the
|
|
27
|
+
# rectangular area this router is operating on.
|
|
28
|
+
def initialize(width, height)
|
|
29
|
+
@width = width.to_i
|
|
30
|
+
@height = height.to_i
|
|
31
|
+
|
|
32
|
+
# The zones are stored as Arrays of line segments. Horizontal blocks are
|
|
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 = [] }
|
|
41
|
+
end
|
|
42
|
+
|
|
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
|
+
def addZone(x, y, w, h, horiz, vert)
|
|
48
|
+
# Clip the input rectangle to fit within the handled area of this router.
|
|
49
|
+
x = clip(x.to_i, @width - 1)
|
|
50
|
+
y = clip(y.to_i, @height - 1)
|
|
51
|
+
w = clip(w.to_i, @width - x)
|
|
52
|
+
h = clip(h.to_i, @height - y)
|
|
53
|
+
|
|
54
|
+
# We can ignore empty zones.
|
|
55
|
+
return if w == 0 || h == 0
|
|
56
|
+
|
|
57
|
+
# Break the rectangle into line segments and add them to the appropriate
|
|
58
|
+
# line Arrays.
|
|
59
|
+
if horiz
|
|
60
|
+
y.upto(y + h - 1) do |i|
|
|
61
|
+
addSegment(@hLines[i], [ x, x + w - 1 ])
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
if vert
|
|
65
|
+
x.upto(x + w - 1) do |i|
|
|
66
|
+
addSegment(@vLines[i], [ y, y + h - 1 ])
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Find a non-blocked route from the _startPoint_ [ x, y ] to the
|
|
72
|
+
# _endPoint_ [ x, y ]. The route always starts from the start point towards
|
|
73
|
+
# the right side of the chart and reaches the end point from the left side
|
|
74
|
+
# of the chart. All lines are always strictly horizontal or vertical. There
|
|
75
|
+
# are no diagonal lines.
|
|
76
|
+
def route(startPoint, endPoint)
|
|
77
|
+
points = [ startPoint ]
|
|
78
|
+
# Minimum distance between the starting point and the first turning point.
|
|
79
|
+
startGap = 5
|
|
80
|
+
# Minimum distance between the last turning point and the tip of the
|
|
81
|
+
# arrow.
|
|
82
|
+
endGap = 10
|
|
83
|
+
|
|
84
|
+
if endPoint[0] - startPoint[0] > startGap + endGap + 2
|
|
85
|
+
# If the horizontal distance between start and end point is large enough
|
|
86
|
+
# we can try a direct route.
|
|
87
|
+
#
|
|
88
|
+
# xSeg
|
|
89
|
+
# |startGap|
|
|
90
|
+
# startPoint X--------1
|
|
91
|
+
# |
|
|
92
|
+
# |
|
|
93
|
+
# 2------X end Point
|
|
94
|
+
# |endGap|
|
|
95
|
+
#
|
|
96
|
+
xSeg = placeLine([ startPoint[1], endPoint[1] ],
|
|
97
|
+
false, startPoint[0] + startGap, 1)
|
|
98
|
+
if xSeg && xSeg < endPoint[0] - endGap
|
|
99
|
+
addLineTo(points, xSeg, startPoint[1]) # Point 1
|
|
100
|
+
addLineTo(points, xSeg, endPoint[1]) # Point 2
|
|
101
|
+
addLineTo(points, *endPoint)
|
|
102
|
+
return points
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# If the simple approach above fails, the try a more complex routing
|
|
107
|
+
# strategy.
|
|
108
|
+
#
|
|
109
|
+
# x1
|
|
110
|
+
# |startGap|
|
|
111
|
+
# startPoint X--------1
|
|
112
|
+
# |
|
|
113
|
+
# 3---------------2 ySeg
|
|
114
|
+
# |
|
|
115
|
+
# 4------X endPoint
|
|
116
|
+
# |endGap|
|
|
117
|
+
# x2
|
|
118
|
+
|
|
119
|
+
# Place horizontal segue. We don't know the width yet, so we have to
|
|
120
|
+
# assume full width. That's acceptable for horizontal lines.
|
|
121
|
+
ySeg = placeLine([ 0, @width - 1 ], true, startPoint[1],
|
|
122
|
+
startPoint[1] < endPoint[1] ? 1 : -1)
|
|
123
|
+
raise "Routing failed" unless ySeg
|
|
124
|
+
|
|
125
|
+
# Place 1st vertical
|
|
126
|
+
x1 = placeLine([ startPoint[1], ySeg ], false, startPoint[0] + startGap, 1)
|
|
127
|
+
raise "Routing failed" unless x1
|
|
128
|
+
|
|
129
|
+
# Place 2nd vertical
|
|
130
|
+
x2 = placeLine([ ySeg, endPoint[1] ], false, endPoint[0] - endGap, -1)
|
|
131
|
+
raise "Routing failed" unless x2
|
|
132
|
+
|
|
133
|
+
# Now add the points 1 - 4 to the list and mark the zones around them. For
|
|
134
|
+
# vertical lines, we only mark vertical zones and vice versa.
|
|
135
|
+
addLineTo(points, x1, startPoint[1]) # Point 1
|
|
136
|
+
if x1 != x2
|
|
137
|
+
addLineTo(points, x1, ySeg) # Point 2
|
|
138
|
+
addLineTo(points, x2, ySeg) # Point 3
|
|
139
|
+
end
|
|
140
|
+
addLineTo(points, x2, endPoint[1]) # Point 4
|
|
141
|
+
addLineTo(points, *endPoint)
|
|
142
|
+
|
|
143
|
+
points
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# This function is only intended for debugging purposes. It marks either the
|
|
147
|
+
# vertical or horizontal zones in the chart.
|
|
148
|
+
def to_html
|
|
149
|
+
html = []
|
|
150
|
+
# Change this to determine what zones you want to see.
|
|
151
|
+
if true
|
|
152
|
+
# Show vertical blocks
|
|
153
|
+
x = 0
|
|
154
|
+
@vLines.each do |line|
|
|
155
|
+
line.each do |segment|
|
|
156
|
+
html << lineToHTML(x, segment[0], x, segment[1], 'white')
|
|
157
|
+
end
|
|
158
|
+
x += 1
|
|
159
|
+
end
|
|
160
|
+
else
|
|
161
|
+
# Show horizontal blocks
|
|
162
|
+
y = 0
|
|
163
|
+
@hLines.each do |line|
|
|
164
|
+
line.each do |segment|
|
|
165
|
+
html << lineToHTML(segment[0], y, segment[1], y, 'white')
|
|
166
|
+
end
|
|
167
|
+
y += 1
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
html
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
private
|
|
174
|
+
|
|
175
|
+
# Simple utility function to limit _v_ between 0 and _max_.
|
|
176
|
+
def clip(v, max)
|
|
177
|
+
v = 0 if v < 0
|
|
178
|
+
v = max if v > max
|
|
179
|
+
v
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# This function makes sure that the rectangle described by _x_, _y_, _w_ and
|
|
183
|
+
# _h_ is properly justfified. If the width or height are negative, _x_ and
|
|
184
|
+
# _y_ are adjusted to describe the same rectangle with all positive
|
|
185
|
+
# coordinates.
|
|
186
|
+
def justify(x, y, w, h)
|
|
187
|
+
if w < 0
|
|
188
|
+
w = -w
|
|
189
|
+
x = x - w + 1
|
|
190
|
+
end
|
|
191
|
+
if h < 0
|
|
192
|
+
h = -h
|
|
193
|
+
y = y - h + 1
|
|
194
|
+
end
|
|
195
|
+
# Return the potentially adjusted rectangle coordinates.
|
|
196
|
+
return x, y, w, h
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# This function adds a new segment to the line. In case the new segment
|
|
200
|
+
# overlaps with or directly attaches to existing segments, these segments
|
|
201
|
+
# are merged into a single segment.
|
|
202
|
+
def addSegment(line, newSegment)
|
|
203
|
+
# Search for overlaping or directly attaching segments in the list.
|
|
204
|
+
i = 0
|
|
205
|
+
while (i < line.length)
|
|
206
|
+
segment = line[i]
|
|
207
|
+
if mergeable?(newSegment, segment)
|
|
208
|
+
# Merge exiting segment into new one
|
|
209
|
+
merge(newSegment, segment)
|
|
210
|
+
# Remove the old one from the list and restart with the newly created
|
|
211
|
+
# one at the same position.
|
|
212
|
+
line.delete_at(i)
|
|
213
|
+
next
|
|
214
|
+
elsif segment[0] > newSegment[1]
|
|
215
|
+
# Segments are stored in ascending order. If the next segment starts
|
|
216
|
+
# with a larger value, we insert the new segment before the larger
|
|
217
|
+
# one.
|
|
218
|
+
line.insert(i, newSegment)
|
|
219
|
+
return
|
|
220
|
+
end
|
|
221
|
+
i += 1
|
|
222
|
+
end
|
|
223
|
+
# Append new segment
|
|
224
|
+
line << newSegment
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Return true if the two segments described by _s1_ and _s2_ overlap each
|
|
228
|
+
# other. A segment is a [ start, end ] Array. The two points are part of the
|
|
229
|
+
# segment.
|
|
230
|
+
def overlaps?(s1, s2)
|
|
231
|
+
(s1[0] <= s2[0] && s2[0] <= s1[1]) ||
|
|
232
|
+
(s2[0] <= s1[0] && s1[0] <= s2[1])
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Return true if the two segments described by _s1_ and _s2_ overlap each
|
|
236
|
+
# other or are directly attached to each other.
|
|
237
|
+
def mergeable?(s1, s2)
|
|
238
|
+
overlaps?(s1, s2) ||
|
|
239
|
+
(s1[1] + 1 == s2[0]) ||
|
|
240
|
+
(s2[1] + 1 == s1[0])
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Merge the two segments described by _dst_ and _src_ into _dst_.
|
|
244
|
+
def merge(dst, seg)
|
|
245
|
+
dst[0] = seg[0] if seg[0] < dst[0]
|
|
246
|
+
dst[1] = seg[1] if seg[1] > dst[1]
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Find out if any of the segments in _line_ overlap with the _probeSegment_.
|
|
250
|
+
# If so, return true, false otherwise.
|
|
251
|
+
def collision?(line, probeSegment)
|
|
252
|
+
# For complex charts, the segment lists can be rather long. We use a
|
|
253
|
+
# binary search to be fairly efficient.
|
|
254
|
+
l = 0
|
|
255
|
+
u = line.length - 1
|
|
256
|
+
while l <= u
|
|
257
|
+
# Look at the element in the middle between l and u.
|
|
258
|
+
p = l + ((u - l) / 2).to_i
|
|
259
|
+
return true if overlaps?(line[p], probeSegment)
|
|
260
|
+
|
|
261
|
+
if probeSegment[0] > line[p][1]
|
|
262
|
+
# The potential target is above p. Adjust lower bound.
|
|
263
|
+
l = p + 1
|
|
264
|
+
else
|
|
265
|
+
# The potential target is below p. Adjust upper bound.
|
|
266
|
+
u = p - 1
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
# TODO: This code uses a simple linear search to double check the above
|
|
270
|
+
# binary search. It can be removed once we know the above code always
|
|
271
|
+
# works properly.
|
|
272
|
+
line.each do |segment|
|
|
273
|
+
if overlaps?(probeSegment, segment)
|
|
274
|
+
raise "Binary search failed to find collision"
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
false
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# This function is at the heart of the routing algorithm. It tries to find a
|
|
282
|
+
# place for the line described by _segment_ without overlapping with the
|
|
283
|
+
# defined zones. _horizontal_ determines whether the line is running
|
|
284
|
+
# horizontally or vertically. _start_ is the first coordinate that is looked
|
|
285
|
+
# at. In case of collisions, _start_ is moved by _delta_ and the check is
|
|
286
|
+
# repeated. The function returns the first collision free coordinate or the
|
|
287
|
+
# outside edge of the routing area.
|
|
288
|
+
def placeLine(segment, horizontal, start, delta)
|
|
289
|
+
raise "delta may not be 0" if delta == 0
|
|
290
|
+
# Start must be an integer and lie within the routing area.
|
|
291
|
+
pos = start.to_i
|
|
292
|
+
pos = 0 if pos < 0
|
|
293
|
+
max = (horizontal ? @height: @width) - 1
|
|
294
|
+
pos = max if pos > max
|
|
295
|
+
|
|
296
|
+
# Make sure that the segment coordinates are in ascending order.
|
|
297
|
+
segment.sort!
|
|
298
|
+
lines = horizontal ? @hLines : @vLines
|
|
299
|
+
# TODO: Remove this check once the code becomes stable.
|
|
300
|
+
checkLines(lines)
|
|
301
|
+
while collision?(lines[pos], segment)
|
|
302
|
+
pos += delta
|
|
303
|
+
# Check if we have exceded the chart area towards top/left.
|
|
304
|
+
if delta < 0
|
|
305
|
+
if pos < 0
|
|
306
|
+
break
|
|
307
|
+
end
|
|
308
|
+
else
|
|
309
|
+
# And towards right/bottom.
|
|
310
|
+
break if pos >= (horizontal ? @height : @width)
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
doubleCheckLine(horizontal ? @hLines : @vLines, pos, segment)
|
|
314
|
+
pos
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# This function adds another waypoint to an existing line. In addition it
|
|
318
|
+
# adds a zone that is 2 pixel wide on each side of the line and runs in the
|
|
319
|
+
# direction of the line. This avoids too closely aligned parallel lines in
|
|
320
|
+
# the chart.
|
|
321
|
+
def addLineTo(points, x2, y2)
|
|
322
|
+
raise "Point list may not be empty" if points.empty?
|
|
323
|
+
|
|
324
|
+
x1, y1 = points[-1]
|
|
325
|
+
points << [ x2, y2 ]
|
|
326
|
+
|
|
327
|
+
if x1 == x2
|
|
328
|
+
# vertical line
|
|
329
|
+
return if x1 < 0 || x1 >= @width
|
|
330
|
+
x, y, w, h = justify(x1 - 2, y1, 5, y2 - y1 + 1)
|
|
331
|
+
addZone(x, y, w, h, false, true)
|
|
332
|
+
else
|
|
333
|
+
# horizontal line
|
|
334
|
+
return if y1 < 0 || x1 >= @height
|
|
335
|
+
x, y, w, h = justify(x1, y1 - 2, x2 - x1 + 1, 5)
|
|
336
|
+
addZone(x, y, w, h, true, false)
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# This is just an internal sanity check that is not needed for normal
|
|
341
|
+
# operation. It checks that all the line segments are valid and stored in
|
|
342
|
+
# ascending order.
|
|
343
|
+
def checkLines(lines)
|
|
344
|
+
lines.each do |line|
|
|
345
|
+
v = nil
|
|
346
|
+
line.each do |segment|
|
|
347
|
+
if segment[0] > segment[1]
|
|
348
|
+
raise "Invalid segment [#{segment[0]}, #{segment[1]}]"
|
|
349
|
+
end
|
|
350
|
+
if v
|
|
351
|
+
raise "Segment sequence error" if v >= segment[0]
|
|
352
|
+
end
|
|
353
|
+
v = segment[1]
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# Internal function that is only used for testing. It raises an exception if
|
|
359
|
+
# the placed line at _pos_ and [ _lineSegment_[0], _lineSegment_[1] ]
|
|
360
|
+
# overlaps with a segment of _lines_.
|
|
361
|
+
def doubleCheckLine(lines, pos, lineSegment)
|
|
362
|
+
return if pos < 0 || lines[pos].nil?
|
|
363
|
+
lines[pos].each do |segment|
|
|
364
|
+
if overlaps?(lineSegment, segment)
|
|
365
|
+
raise "Internal router failure for #{lines == @vLines ? 'v' : 'h'}" +
|
|
366
|
+
"Line #{pos}: [#{lineSegment.join(', ')}] overlaps with " +
|
|
367
|
+
"[#{segment.join(', ')}]."
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
end
|
|
375
|
+
|