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
data/lib/XMLDocument.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = XMLDocument.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 'XMLElement'
|
|
14
|
+
|
|
15
|
+
class TaskJuggler
|
|
16
|
+
|
|
17
|
+
# This class provides a rather simple XML document generator. It provides
|
|
18
|
+
# basic features to create a tree of XMLElements and to generate a XML String
|
|
19
|
+
# or file. It's much less powerful than REXML but provides a more efficient
|
|
20
|
+
# API to create XMLDocuments with lots of attributes.
|
|
21
|
+
class XMLDocument
|
|
22
|
+
|
|
23
|
+
# Create an empty XML document.
|
|
24
|
+
def initialize
|
|
25
|
+
@elements = []
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Add a top-level XMLElement.
|
|
29
|
+
def <<(element)
|
|
30
|
+
@elements << element
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Produce the XMLDocument as String.
|
|
34
|
+
def to_s
|
|
35
|
+
str = ''
|
|
36
|
+
@elements.each do |element|
|
|
37
|
+
str << element.to_s(0)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
str
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Write the XMLDocument to the specified file.
|
|
44
|
+
def write(filename)
|
|
45
|
+
f = File.new(filename, 'w')
|
|
46
|
+
@elements.each do |element|
|
|
47
|
+
f.puts element.to_s(0)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
data/lib/XMLElement.rb
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = XMLElement.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 'UTF8String'
|
|
14
|
+
|
|
15
|
+
class TaskJuggler
|
|
16
|
+
|
|
17
|
+
# This class models an XML node that may contain other XML nodes. XML element
|
|
18
|
+
# trees can be constructed with the class constructor and converted into XML.
|
|
19
|
+
class XMLElement
|
|
20
|
+
|
|
21
|
+
attr_writer :mayNotBeEmpty
|
|
22
|
+
|
|
23
|
+
# Construct a new XML element and include it in an existing XMLElement tree.
|
|
24
|
+
def initialize(name, attributes = {})
|
|
25
|
+
if (name.nil? && attributes.length > 0) ||
|
|
26
|
+
(!name.nil? && !name.is_a?(String))
|
|
27
|
+
raise "Name must be nil or a String "
|
|
28
|
+
end
|
|
29
|
+
@name = name
|
|
30
|
+
attributes.each do |n, v|
|
|
31
|
+
if n.nil? || v.nil?
|
|
32
|
+
raise "Attribute name (#{n}) or value (#{v}) may not be nil"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
@attributes = attributes
|
|
36
|
+
@children = []
|
|
37
|
+
# This can be set to true if <name /> is illegal for this element.
|
|
38
|
+
@mayNotBeEmpty = false
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Add a new child or a set of new childs to the element.
|
|
42
|
+
def <<(arg)
|
|
43
|
+
# If the argument is an array, we have to insert each element
|
|
44
|
+
# individually.
|
|
45
|
+
if arg.is_a?(XMLElement)
|
|
46
|
+
@children << arg
|
|
47
|
+
elsif arg.is_a?(Array)
|
|
48
|
+
@children += arg
|
|
49
|
+
elsif arg.nil?
|
|
50
|
+
# do nothing
|
|
51
|
+
else
|
|
52
|
+
raise 'Elements must be of type XMLElement'
|
|
53
|
+
end
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Return the element and all sub elements as properly formatted XML.
|
|
58
|
+
def to_s(indent = 0)
|
|
59
|
+
out = '<' + @name
|
|
60
|
+
@attributes.each do |attrName, attrValue|
|
|
61
|
+
out << ' ' + attrName + '="' + quoteAttr(attrValue) + '"'
|
|
62
|
+
end
|
|
63
|
+
if @children.empty? && !@mayNotBeEmpty
|
|
64
|
+
out << '/>'
|
|
65
|
+
else
|
|
66
|
+
out << '>'
|
|
67
|
+
@children.each do |child|
|
|
68
|
+
# We only insert newlines for multiple childs and after a tag has been
|
|
69
|
+
# closed.
|
|
70
|
+
if @children.size > 1 && !child.is_a?(XMLText) && out[-1] == ?>
|
|
71
|
+
out << "\n" + indentation(indent + 1)
|
|
72
|
+
end
|
|
73
|
+
out << child.to_s(indent + 1)
|
|
74
|
+
end
|
|
75
|
+
out << "\n" + indentation(indent) if @children.size > 1 && out[-1] == ?>
|
|
76
|
+
out << '</' + @name + '>'
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
protected
|
|
81
|
+
|
|
82
|
+
def indentation(indent)
|
|
83
|
+
' ' * indent
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
# Make sure that any double quote in _str_ is properly quoted.
|
|
89
|
+
def quoteAttr(str)
|
|
90
|
+
out = ''
|
|
91
|
+
str.each_utf8_char do |c|
|
|
92
|
+
if c == '"'
|
|
93
|
+
out << '\"'
|
|
94
|
+
else
|
|
95
|
+
out << c
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
out
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# This is a specialized XMLElement to represent a simple text.
|
|
105
|
+
class XMLText < XMLElement
|
|
106
|
+
|
|
107
|
+
def initialize(text)
|
|
108
|
+
super(nil, {})
|
|
109
|
+
raise 'Text may not be nil' unless text
|
|
110
|
+
@text = text
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_s(indent)
|
|
114
|
+
out = ''
|
|
115
|
+
@text.each_utf8_char do |c|
|
|
116
|
+
case c
|
|
117
|
+
when '<'
|
|
118
|
+
out << '<'
|
|
119
|
+
when '>'
|
|
120
|
+
out << '>'
|
|
121
|
+
when '&'
|
|
122
|
+
out << '&'
|
|
123
|
+
else
|
|
124
|
+
out << c
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
out
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# This is a convenience class that allows the creation of an XMLText nested
|
|
134
|
+
# into an XMLElement. The _name_ and _attributes_ belong to the XMLElement,
|
|
135
|
+
# the text to the XMLText.
|
|
136
|
+
class XMLNamedText < XMLElement
|
|
137
|
+
|
|
138
|
+
def initialize(text, name, attributes = {})
|
|
139
|
+
super(name, attributes)
|
|
140
|
+
self << XMLText.new(text)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# This is a specialized XMLElement to represent a comment.
|
|
146
|
+
class XMLComment < XMLElement
|
|
147
|
+
|
|
148
|
+
def initialize(text = '')
|
|
149
|
+
super(nil, {})
|
|
150
|
+
@text = text
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def to_s(indent)
|
|
154
|
+
'<!-- ' + @text + '-->'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# This is a specialized XMLElement to represent XML blobs. The content is not
|
|
160
|
+
# interpreted and must be valid XML in the content it is added.
|
|
161
|
+
class XMLBlob < XMLElement
|
|
162
|
+
|
|
163
|
+
def initialize(blob = '')
|
|
164
|
+
super(nil, {})
|
|
165
|
+
@blob = blob
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def to_s(indent)
|
|
169
|
+
@blob
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
end
|
|
175
|
+
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = CSVFile.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 'UTF8String'
|
|
14
|
+
|
|
15
|
+
class TaskJuggler
|
|
16
|
+
|
|
17
|
+
# This is a very lightweight version of the Ruby library class CSV. That class
|
|
18
|
+
# changed significantly from 1.8 to 1.9 and is a compatibility nightmare.
|
|
19
|
+
# Hence we use our own class.
|
|
20
|
+
class CSVFile
|
|
21
|
+
|
|
22
|
+
# At construction time you need to specify the +data+ container. This is an
|
|
23
|
+
# Array of Arrays that holds the table. Optionally, you can specify a
|
|
24
|
+
# +separator+ and a +quote+ string for the CSV file.
|
|
25
|
+
def initialize(data, separator = ';', quote = '"')
|
|
26
|
+
@data = data
|
|
27
|
+
@separator = separator
|
|
28
|
+
@quote = quote
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Use this function to write the table into a CSV file +fileName+. '.' can
|
|
32
|
+
# be used to write to $stdout.
|
|
33
|
+
def write(fileName)
|
|
34
|
+
if (fileName == '.')
|
|
35
|
+
file = $stdout
|
|
36
|
+
else
|
|
37
|
+
file = File.open(fileName, 'w')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@data.each do |line|
|
|
41
|
+
first = true
|
|
42
|
+
line.each do |field|
|
|
43
|
+
# Don't output a separator before the first field of the line.
|
|
44
|
+
if first
|
|
45
|
+
first = false
|
|
46
|
+
else
|
|
47
|
+
file.write @separator
|
|
48
|
+
end
|
|
49
|
+
file.write(marshal(field))
|
|
50
|
+
end
|
|
51
|
+
file.write "\n"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
file.close unless fileName == '.'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Read the data as Array of Arrays from a CSV formated file +fileName+. In
|
|
58
|
+
# case '.' is used for the +fileName+ the data is read from $stdin.
|
|
59
|
+
def read(fileName)
|
|
60
|
+
if (fileName == '.')
|
|
61
|
+
file = $stdin
|
|
62
|
+
else
|
|
63
|
+
file = File.open(fileName, 'r')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
csv = []
|
|
67
|
+
file.each_line do |line|
|
|
68
|
+
csv << parseLine(line)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
file.close unless fileName == '.'
|
|
72
|
+
csv
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Read the data as Array of Arrays from a CSV formated String +str+.
|
|
76
|
+
def parse(str)
|
|
77
|
+
csv = []
|
|
78
|
+
str.each_line do |line|
|
|
79
|
+
csv << parseLine(line)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
# This function is used to properly quote @quote and @separation characters
|
|
86
|
+
# contained in the +field+.
|
|
87
|
+
def marshal(field)
|
|
88
|
+
if field.include?(@quote) || field.include?(@separator)
|
|
89
|
+
field.gsub!(/@quote/, '""')
|
|
90
|
+
field = '"' + field + '"'
|
|
91
|
+
end
|
|
92
|
+
field
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def parseLine(line)
|
|
96
|
+
@state = 0 # start of field
|
|
97
|
+
@fields = []
|
|
98
|
+
@field = ''
|
|
99
|
+
line.each_utf8_char do |c|
|
|
100
|
+
case @state
|
|
101
|
+
when 0 # start of field
|
|
102
|
+
if c == @quote
|
|
103
|
+
@state = 1
|
|
104
|
+
else
|
|
105
|
+
@field << c
|
|
106
|
+
@state = 2
|
|
107
|
+
end
|
|
108
|
+
when 1 # in quoted field
|
|
109
|
+
if c == @quote
|
|
110
|
+
@state = 3
|
|
111
|
+
elsif c == @separator
|
|
112
|
+
closeField
|
|
113
|
+
else
|
|
114
|
+
@field << c
|
|
115
|
+
end
|
|
116
|
+
when 2 # in unquoted field
|
|
117
|
+
if c == @separator
|
|
118
|
+
closeField
|
|
119
|
+
else
|
|
120
|
+
@field << c
|
|
121
|
+
end
|
|
122
|
+
when 3 # quote found in quoted field
|
|
123
|
+
if c == @quote
|
|
124
|
+
@field << c
|
|
125
|
+
@state = 2
|
|
126
|
+
else
|
|
127
|
+
closeField
|
|
128
|
+
end
|
|
129
|
+
else
|
|
130
|
+
raise "Unknown state #{state}"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
closeField if @state != 0
|
|
134
|
+
@fields
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def closeField
|
|
138
|
+
@fields << @field
|
|
139
|
+
@field = ''
|
|
140
|
+
@state = 0
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
146
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = ColumnTable.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/ReportTable'
|
|
14
|
+
|
|
15
|
+
class TaskJuggler
|
|
16
|
+
|
|
17
|
+
# This class is essentially a wrapper around ReportTable that allows us to
|
|
18
|
+
# embed a ReportTable object as a column of another ReportTable object. Both
|
|
19
|
+
# ReportTables must have the same number of lines.
|
|
20
|
+
class ColumnTable < ReportTable
|
|
21
|
+
|
|
22
|
+
attr_writer :maxWidth
|
|
23
|
+
|
|
24
|
+
# Create a new ColumnTable object.
|
|
25
|
+
def initialize
|
|
26
|
+
super
|
|
27
|
+
@maxWidth = nil
|
|
28
|
+
# The header will have 2 lines. So, use a smaller font. This should match
|
|
29
|
+
# the font size used for the GanttChart header.
|
|
30
|
+
@headerFontSize = 10
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def to_html
|
|
34
|
+
height = 2 * @headerLineHeight + 1
|
|
35
|
+
@lines.each do |line|
|
|
36
|
+
# Add line height plus 1 pixel padding
|
|
37
|
+
height += line.height + 1
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Since we don't know the resulting width of the column, we need to always
|
|
41
|
+
# add an extra space for the scrollbar.
|
|
42
|
+
td = XMLElement.new('td', 'rowspan' => "#{2 + @lines.length + 1}",
|
|
43
|
+
'style' => 'padding:0px; vertical-align:top;')
|
|
44
|
+
# Now we generate a 'div' that will contain the nested table. It has a
|
|
45
|
+
# height that fits all lines but has a maximum width. In case the embedded
|
|
46
|
+
# table is larger, a scrollbar will appear. We assume that the scrollbar
|
|
47
|
+
# has a height of 18 pixels or less.
|
|
48
|
+
# Due to Firefoxes broken table rendering we have to specify a minimum
|
|
49
|
+
# width. It may not excede the maxWidth value.
|
|
50
|
+
mWidth = minWidth
|
|
51
|
+
mWidth = @maxWidth if mWidth > @maxWidth
|
|
52
|
+
td << (scrollDiv = XMLElement.new('div', 'class' => 'tabback',
|
|
53
|
+
'style' => 'position:relative; overflow:auto; ' +
|
|
54
|
+
"max-width:#{@maxWidth}px; " +
|
|
55
|
+
"min-width:#{mWidth}px; " +
|
|
56
|
+
'margin-top:-1px; margin-bottom:-1px; ' +
|
|
57
|
+
"height:#{height + 18 + 2}px;"))
|
|
58
|
+
|
|
59
|
+
scrollDiv << super
|
|
60
|
+
td
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = GanttChart.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/GanttHeader'
|
|
14
|
+
require 'reports/GanttLine'
|
|
15
|
+
require 'reports/GanttRouter'
|
|
16
|
+
require 'reports/HTMLGraphics'
|
|
17
|
+
|
|
18
|
+
class TaskJuggler
|
|
19
|
+
|
|
20
|
+
# This class represents an abstract (output format independent) Gantt chart.
|
|
21
|
+
# It provides generator functions that can transform the abstract form into
|
|
22
|
+
# formats such as HTML or SVG.
|
|
23
|
+
# The appearance of the chart depend on 3 variable: the report period,
|
|
24
|
+
# the geometrical width and the scale. The report period is always provided by
|
|
25
|
+
# the user. In addition the width _or_ the scale can be provided. The
|
|
26
|
+
# non-provided value will then be calculated. So after the object has been
|
|
27
|
+
# created, the user must call generateByWidth or generateByResolution.
|
|
28
|
+
class GanttChart
|
|
29
|
+
|
|
30
|
+
include HTMLGraphics
|
|
31
|
+
|
|
32
|
+
attr_reader :start, :end, :now, :weekStartsMonday, :header, :width,
|
|
33
|
+
:scale, :scales, :table
|
|
34
|
+
attr_writer :viewWidth
|
|
35
|
+
|
|
36
|
+
# Create the GanttChart object, but don't do much right now. We still need
|
|
37
|
+
# more information about the chart before we can actually generate it. _now_
|
|
38
|
+
# is the date that should be used as current date. _weekStartsMonday_ is
|
|
39
|
+
# true if the weeks should start on Mondays instead of Sundays. _table_ is a
|
|
40
|
+
# reference to the ReportTableElement that the chart is part of.
|
|
41
|
+
def initialize(now, weekStartsMonday, table = nil)
|
|
42
|
+
# The start and end dates of the reported interval.
|
|
43
|
+
@start = nil
|
|
44
|
+
@end = nil
|
|
45
|
+
@now = now
|
|
46
|
+
@table = table
|
|
47
|
+
|
|
48
|
+
# This defines the possible horizontal scales that the Gantt chart can
|
|
49
|
+
# have. The scales differ in their resolution and the amount of detail
|
|
50
|
+
# that is displayed. A scale is defined by its name. The _name_ must be
|
|
51
|
+
# unique and can be used to select the scale. The _stepSize_ defines the
|
|
52
|
+
# width of a scale step in pixels. The _stepsToFunc_ is a TjTime method
|
|
53
|
+
# that determines the number of steps between 2 dates. _minTimeOff_
|
|
54
|
+
# defines the minimum required length of an time-off interval that is
|
|
55
|
+
# displayed in this scale.
|
|
56
|
+
@@scales = [
|
|
57
|
+
{ 'name' => 'hour', 'stepSize' => 20, 'stepsToFunc' => :hoursTo,
|
|
58
|
+
'minTimeOff' => 5 * 60 },
|
|
59
|
+
{ 'name' => 'day', 'stepSize' => 20, 'stepsToFunc' => :daysTo,
|
|
60
|
+
'minTimeOff' => 6 * 60 * 60 },
|
|
61
|
+
{ 'name' => 'week', 'stepSize' => 20, 'stepsToFunc' => :weeksTo,
|
|
62
|
+
'minTimeOff' => 24 * 60 * 60 },
|
|
63
|
+
{ 'name' => 'month', 'stepSize' => 35, 'stepsToFunc' => :monthsTo,
|
|
64
|
+
'minTimeOff' => 5 * 24 * 60 * 60 },
|
|
65
|
+
{ 'name' => 'quarter', 'stepSize' => 28, 'stepsToFunc' => :quartersTo,
|
|
66
|
+
'minTimeOff' => -1 },
|
|
67
|
+
{ 'name' => 'year', 'stepSize' => 20, 'stepsToFunc' => :yearsTo,
|
|
68
|
+
'minTimeOff' => -1 }
|
|
69
|
+
]
|
|
70
|
+
# This points to one of the scales above and marks the current scale.
|
|
71
|
+
@scale = nil
|
|
72
|
+
# The height of the chart (without the header)
|
|
73
|
+
@height = 0
|
|
74
|
+
# The width of the chart in pixels.
|
|
75
|
+
@width = 0
|
|
76
|
+
# The width of the view that the chart is presented in. If it's nil, the
|
|
77
|
+
# view will be adapted to the width of the chart.
|
|
78
|
+
@viewWidth = nil
|
|
79
|
+
# True of the week starts on a Monday.
|
|
80
|
+
@weekStartsMonday = weekStartsMonday
|
|
81
|
+
|
|
82
|
+
# Reference to the GanttHeader object that models the chart header.
|
|
83
|
+
@header = nil
|
|
84
|
+
# The GanttLine objects that model the lines of the chart.
|
|
85
|
+
@lines = []
|
|
86
|
+
# The router for dependency lines.
|
|
87
|
+
@router = nil
|
|
88
|
+
# This dictionary stores primary task lines indexed by their task. To
|
|
89
|
+
# handle multiple scenarios, the dictionary stored the lines in an Array.
|
|
90
|
+
# This is used to generate dependency arrows.
|
|
91
|
+
@tasks = {}
|
|
92
|
+
# This is a list of the dependency lines. Each entry is an Array of [x, y]
|
|
93
|
+
# coordinate pairs.
|
|
94
|
+
@depArrows = []
|
|
95
|
+
# This is the list of arrow heads used for the dependency arrows. It
|
|
96
|
+
# contains an Array of [ x, y ] coordinates that mark the tip of the
|
|
97
|
+
# arrow.
|
|
98
|
+
@arrowHeads = []
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Add a primary tasks line to the dictonary. _task_ is a reference to the
|
|
102
|
+
# Task object and _line_ is the corresponding primary ReportTableLine.
|
|
103
|
+
def addTask(task, line)
|
|
104
|
+
if @tasks.include?(task)
|
|
105
|
+
# Append the line to the existing lines.
|
|
106
|
+
@tasks[task] << line
|
|
107
|
+
else
|
|
108
|
+
# Add a new Array for this tasks and store the first line.
|
|
109
|
+
@tasks[task] = [ line ]
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def generateByWidth(periodStart, periodEnd, width)
|
|
115
|
+
@start = periodStart
|
|
116
|
+
@end = periodEnd
|
|
117
|
+
@width = width
|
|
118
|
+
# TODO
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Generate the actual chart data based on the report interval specified by
|
|
122
|
+
# _periodStart_ and _periodEnd_ as well as the name of the requested scale
|
|
123
|
+
# to be used. This function (or generateByWidth) must be called before any
|
|
124
|
+
# GanttLine objects are created for this chart.
|
|
125
|
+
def generateByScale(periodStart, periodEnd, scaleName)
|
|
126
|
+
@start = periodStart
|
|
127
|
+
@end = periodEnd
|
|
128
|
+
@scale = scaleByName(scaleName)
|
|
129
|
+
@stepSize = @scale['stepSize']
|
|
130
|
+
steps = @start.send(@scale['stepsToFunc'], @end)
|
|
131
|
+
@width = @stepSize * steps
|
|
132
|
+
|
|
133
|
+
@header = GanttHeader.new(self)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Convert the chart into an HTML representation.
|
|
137
|
+
def to_html
|
|
138
|
+
completeChart
|
|
139
|
+
|
|
140
|
+
# The chart is rendered into a cell that extends over the full height of
|
|
141
|
+
# the table. No other cells for this column will be generated. In case
|
|
142
|
+
# there is a scrollbar, the table will have an extra line to hold the
|
|
143
|
+
# scrollbar.
|
|
144
|
+
td = XMLElement.new('td',
|
|
145
|
+
'rowspan' => "#{2 + @lines.length + (hasScrollbar? ? 1 : 0)}",
|
|
146
|
+
'style' => 'padding:0px; vertical-align:top;')
|
|
147
|
+
# Now we generate two 'div's nested into each other. The first div is the
|
|
148
|
+
# view. It may contain a scrollbar if the second div is wider than the
|
|
149
|
+
# first one. In case we need a scrollbar The outer div is 18 pixels
|
|
150
|
+
# heigher to hold the scrollbar. Unfortunately this must be a hardcoded
|
|
151
|
+
# value even though the height of the scrollbar varies from system to
|
|
152
|
+
# system. This value should be good enough for most systems.
|
|
153
|
+
td << (scrollDiv = XMLElement.new('div',
|
|
154
|
+
'style' => 'position:relative; ' +
|
|
155
|
+
"overflow:auto; " +
|
|
156
|
+
"width:#{hasScrollbar? ? @viewWidth : @width}px; " +
|
|
157
|
+
"height:#{@height + (hasScrollbar? ? 18 : 0)}px;"))
|
|
158
|
+
scrollDiv << (div = XMLElement.new('div',
|
|
159
|
+
'style' => "margin:0px; padding:0px; " +
|
|
160
|
+
"position:absolute; " +
|
|
161
|
+
"top:0px; left:0px; " +
|
|
162
|
+
"width:#{@width.to_i}px; " +
|
|
163
|
+
"height:#{@height}px; " +
|
|
164
|
+
"font-size:10px;"))
|
|
165
|
+
# Add the header.
|
|
166
|
+
div << @header.to_html
|
|
167
|
+
# These are the lines of the chart.
|
|
168
|
+
@lines.each do |line|
|
|
169
|
+
div << line.to_html
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# This is used for debugging and testing only.
|
|
173
|
+
#div << @router.to_html
|
|
174
|
+
|
|
175
|
+
# Render the dependency lines.
|
|
176
|
+
@depArrows.each do |arrow|
|
|
177
|
+
xx = yy = nil
|
|
178
|
+
arrow.each do |x, y|
|
|
179
|
+
if xx
|
|
180
|
+
div << lineToHTML(xx, yy, x, y, 'depline')
|
|
181
|
+
end
|
|
182
|
+
xx = x
|
|
183
|
+
yy = y
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
# And the corresponsing arrow heads.
|
|
187
|
+
@arrowHeads.each do |x, y|
|
|
188
|
+
6.times do |i|
|
|
189
|
+
div << lineToHTML(x - i, y - i, x - i, y + i, 'depline')
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
td
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# This is a noop function.
|
|
197
|
+
def to_csv(csv)
|
|
198
|
+
# Can't put a Gantt chart into a CSV file.
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Utility function that convers a date to the corresponding X-position in
|
|
202
|
+
# the Gantt chart.
|
|
203
|
+
def dateToX(date)
|
|
204
|
+
(@width / (@end - @start)) * (date - @start)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# This is not a user callable function. It's only meant for use within the
|
|
208
|
+
# library.
|
|
209
|
+
def addLine(line) #:nodoc:
|
|
210
|
+
if @scale.nil?
|
|
211
|
+
raise "generateByScale or generateByWidth must be called first"
|
|
212
|
+
end
|
|
213
|
+
@lines << line
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Returns true if the chart includes a scrollbar.
|
|
217
|
+
def hasScrollbar?
|
|
218
|
+
@viewWidth && @viewWidth < @width
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
private
|
|
222
|
+
|
|
223
|
+
# Find the scale with the name _name_ and return a reference to the scale.
|
|
224
|
+
# If nothing is round an exception is raised.
|
|
225
|
+
def scaleByName(name)
|
|
226
|
+
@@scales.each do |scale|
|
|
227
|
+
return scale if scale['name'] == name
|
|
228
|
+
end
|
|
229
|
+
raise "Unknown scale #{name}"
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Calculate the overall height of the chart and generate dependency arrows.
|
|
233
|
+
def completeChart
|
|
234
|
+
@lines.each do |line|
|
|
235
|
+
@height = line.y + line.height if line.y + line.height > @height
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
@router = GanttRouter.new(@width, @height)
|
|
239
|
+
|
|
240
|
+
@lines.each do |line|
|
|
241
|
+
line.addBlockedZones(@router)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
@router.addZone(@header.nowLineX - 1, 0, 3, @height - 1, false, true)
|
|
245
|
+
|
|
246
|
+
@tasks.each do |task, lines|
|
|
247
|
+
generateDepArrow(task, lines)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Generate an output format independent description of the dependency lines
|
|
252
|
+
# for a specific _task_. _lines_ is a list of GanttLines that the tasks are
|
|
253
|
+
# displayed on. Reports with multiple scenarios have multiple lines per
|
|
254
|
+
# task.
|
|
255
|
+
def generateDepArrow(task, lines)
|
|
256
|
+
# Since we need the line and the index we use an index iterator.
|
|
257
|
+
lines.length.times do |lineIndex|
|
|
258
|
+
line = lines[lineIndex]
|
|
259
|
+
scenarioIdx = line.scenarioIdx
|
|
260
|
+
|
|
261
|
+
# Generate the dependencies on the start of the task.
|
|
262
|
+
startX, startY = line.getTask.startDepLineStart
|
|
263
|
+
task['startsuccs', scenarioIdx].each do |t, onEnd|
|
|
264
|
+
# Skip inherited dependencies and tasks that are not included in the
|
|
265
|
+
# chart.
|
|
266
|
+
if (t.parent &&
|
|
267
|
+
task.hasDependency?(scenarioIdx, 'startsuccs', t.parent, onEnd)) ||
|
|
268
|
+
!@tasks.include?(t)
|
|
269
|
+
next
|
|
270
|
+
end
|
|
271
|
+
endX, endY = @tasks[t][lineIndex].getTask.send(
|
|
272
|
+
onEnd ? :endDepLineEnd : :startDepLineEnd)
|
|
273
|
+
routeArrow(startX, startY, endX, endY)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# Generate the dependencies on the end of the task.
|
|
277
|
+
startX, startY = line.getTask.endDepLineStart
|
|
278
|
+
task['endsuccs', scenarioIdx].each do |t, onEnd|
|
|
279
|
+
# Skip inherited dependencies and tasks that are not included in the
|
|
280
|
+
# chart.
|
|
281
|
+
if (t.parent &&
|
|
282
|
+
task.hasDependency?(scenarioIdx, 'endsuccs', t.parent, onEnd)) ||
|
|
283
|
+
!@tasks.include?(t)
|
|
284
|
+
next
|
|
285
|
+
end
|
|
286
|
+
endX, endY = @tasks[t][lineIndex].getTask.send(
|
|
287
|
+
onEnd ? :endDepLineEnd : :startDepLineEnd)
|
|
288
|
+
routeArrow(startX, startY, endX, endY)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Route the dependency lines from the start to the end point.
|
|
294
|
+
def routeArrow(startX, startY, endX, endY)
|
|
295
|
+
@depArrows << @router.route([startX, startY], [endX, endY])
|
|
296
|
+
|
|
297
|
+
# It's enough to have only a single arrow drawn at the end point even if
|
|
298
|
+
# it's the destination of multiple lines.
|
|
299
|
+
@arrowHeads.each do |x, y|
|
|
300
|
+
return if x == endX && y == endY
|
|
301
|
+
end
|
|
302
|
+
@arrowHeads << [ endX, endY ]
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
end
|
|
308
|
+
|