taskjuggler 0.0.2 → 0.0.3
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/Rakefile +1 -0
- data/benchmarks/depends.tjp +2 -1
- data/benchmarks/htmltaskreport.tjp +2 -1
- data/doc/classes/AppConfig.html +124 -120
- data/doc/classes/Arguments.html +10 -6
- data/doc/classes/Object.html +229 -0
- data/doc/classes/String.html +35 -31
- data/doc/classes/TaskJuggler/Account.html +18 -18
- data/doc/classes/TaskJuggler/AccountAttribute.html +261 -0
- data/doc/classes/TaskJuggler/AccountScenario.html +12 -12
- data/doc/classes/TaskJuggler/Allocation.html +34 -30
- data/doc/classes/TaskJuggler/AllocationAttribute.html +70 -70
- data/doc/classes/TaskJuggler/AttributeBase.html +131 -147
- data/doc/classes/TaskJuggler/AttributeDefinition.html +38 -21
- data/doc/classes/TaskJuggler/BatchProcessor.html +313 -0
- data/doc/classes/TaskJuggler/Booking.html +22 -18
- data/doc/classes/TaskJuggler/BookingListAttribute.html +42 -42
- data/doc/classes/TaskJuggler/BooleanAttribute.html +40 -40
- data/doc/classes/TaskJuggler/CSVFile.html +28 -24
- data/doc/classes/TaskJuggler/Charge.html +22 -18
- data/doc/classes/TaskJuggler/ChargeListAttribute.html +30 -30
- data/doc/classes/TaskJuggler/ChargeSet.html +41 -37
- data/doc/classes/TaskJuggler/ChargeSetListAttribute.html +46 -46
- data/doc/classes/TaskJuggler/ColumnListAttribute.html +231 -0
- data/doc/classes/TaskJuggler/ColumnTable.html +23 -21
- data/doc/classes/TaskJuggler/DateAttribute.html +20 -20
- data/doc/classes/TaskJuggler/DefinitionListAttribute.html +162 -0
- data/doc/classes/TaskJuggler/DependencyListAttribute.html +46 -46
- data/doc/classes/TaskJuggler/DurationAttribute.html +30 -30
- data/doc/classes/TaskJuggler/FixnumAttribute.html +20 -20
- data/doc/classes/TaskJuggler/FlagListAttribute.html +42 -42
- data/doc/classes/TaskJuggler/FloatAttribute.html +30 -30
- data/doc/classes/TaskJuggler/FormatListAttribute.html +197 -0
- data/doc/classes/TaskJuggler/GanttChart.html +236 -207
- data/doc/classes/TaskJuggler/GanttContainer.html +46 -42
- data/doc/classes/TaskJuggler/GanttHeader.html +16 -12
- data/doc/classes/TaskJuggler/GanttHeaderScaleItem.html +16 -12
- data/doc/classes/TaskJuggler/GanttLine.html +28 -24
- data/doc/classes/TaskJuggler/GanttLoadStack.html +22 -18
- data/doc/classes/TaskJuggler/GanttMilestone.html +46 -42
- data/doc/classes/TaskJuggler/GanttRouter.html +104 -98
- data/doc/classes/TaskJuggler/GanttTaskBar.html +46 -42
- data/doc/classes/TaskJuggler/HTMLDocument.html +12 -12
- data/doc/classes/TaskJuggler/HTMLGraphics.html +12 -12
- data/doc/classes/TaskJuggler/Interval.html +126 -120
- data/doc/classes/TaskJuggler/IntervalListAttribute.html +46 -46
- data/doc/classes/TaskJuggler/JobInfo.html +284 -0
- data/doc/classes/TaskJuggler/Journal.html +197 -0
- data/doc/classes/TaskJuggler/JournalEntry.html +218 -0
- data/doc/classes/TaskJuggler/KeywordArray.html +179 -0
- data/doc/classes/TaskJuggler/KeywordDocumentation.html +445 -396
- data/doc/classes/TaskJuggler/Limits/Limit.html +34 -30
- data/doc/classes/TaskJuggler/Limits.html +68 -62
- data/doc/classes/TaskJuggler/LimitsAttribute.html +40 -40
- data/doc/classes/TaskJuggler/ListAttributeBase.html +207 -0
- data/doc/classes/TaskJuggler/Log.html +72 -68
- data/doc/classes/TaskJuggler/LogicalAttribute.html +38 -34
- data/doc/classes/TaskJuggler/LogicalExpression.html +16 -12
- data/doc/classes/TaskJuggler/LogicalExpressionAttribute.html +194 -0
- data/doc/classes/TaskJuggler/LogicalFlag.html +32 -32
- data/doc/classes/TaskJuggler/LogicalFunction.html +28 -24
- data/doc/classes/TaskJuggler/LogicalOperation.html +17 -13
- data/doc/classes/TaskJuggler/Macro.html +10 -6
- data/doc/classes/TaskJuggler/MacroParser.html +36 -36
- data/doc/classes/TaskJuggler/MacroTable.html +40 -36
- data/doc/classes/TaskJuggler/Message.html +16 -12
- data/doc/classes/TaskJuggler/MessageHandler.html +16 -12
- data/doc/classes/TaskJuggler/Navigator.html +249 -0
- data/doc/classes/TaskJuggler/OnShiftCache.html +316 -0
- data/doc/classes/TaskJuggler/Project.html +1064 -678
- data/doc/classes/TaskJuggler/ProjectFileParser.html +90 -85
- data/doc/classes/TaskJuggler/PropertyAttribute.html +194 -0
- data/doc/classes/TaskJuggler/PropertyList.html +114 -113
- data/doc/classes/TaskJuggler/PropertySet.html +355 -312
- data/doc/classes/TaskJuggler/PropertyTreeNode.html +527 -474
- data/doc/classes/TaskJuggler/Query.html +90 -85
- data/doc/classes/TaskJuggler/RTPNavigator.html +292 -0
- data/doc/classes/TaskJuggler/RTPReport.html +301 -0
- data/doc/classes/TaskJuggler/RealFormat.html +114 -57
- data/doc/classes/TaskJuggler/RealFormatAttribute.html +162 -0
- data/doc/classes/TaskJuggler/ReferenceAttribute.html +87 -20
- data/doc/classes/TaskJuggler/Report.html +82 -291
- data/doc/classes/TaskJuggler/ReportBase.html +448 -0
- data/doc/classes/TaskJuggler/ReportContext.html +243 -0
- data/doc/classes/TaskJuggler/ReportTable.html +158 -129
- data/doc/classes/TaskJuggler/ReportTableCell.html +30 -26
- data/doc/classes/TaskJuggler/ReportTableColumn.html +29 -25
- data/doc/classes/TaskJuggler/ReportTableLegend.html +28 -24
- data/doc/classes/TaskJuggler/ReportTableLine.html +34 -30
- data/doc/classes/TaskJuggler/Resource.html +12 -12
- data/doc/classes/TaskJuggler/ResourceListAttribute.html +46 -46
- data/doc/classes/TaskJuggler/ResourceListRE.html +49 -57
- data/doc/classes/TaskJuggler/ResourceScenario.html +126 -126
- data/doc/classes/TaskJuggler/RichText.html +52 -48
- data/doc/classes/TaskJuggler/RichTextAttribute.html +30 -30
- data/doc/classes/TaskJuggler/RichTextDocument.html +41 -37
- data/doc/classes/TaskJuggler/RichTextElement.html +274 -264
- data/doc/classes/TaskJuggler/RichTextException.html +13 -13
- data/doc/classes/TaskJuggler/RichTextParser.html +48 -47
- data/doc/classes/TaskJuggler/RichTextProtocolExample.html +52 -55
- data/doc/classes/TaskJuggler/RichTextProtocolHandler.html +55 -10
- data/doc/classes/TaskJuggler/RichTextScanner.html +106 -245
- data/doc/classes/TaskJuggler/RichTextSnip.html +28 -24
- data/doc/classes/TaskJuggler/RichTextSyntaxRules.html +381 -301
- data/doc/classes/TaskJuggler/Scenario.html +6 -6
- data/doc/classes/TaskJuggler/ScenarioData.html +40 -36
- data/doc/classes/TaskJuggler/ScenarioListAttribute.html +229 -0
- data/doc/classes/TaskJuggler/Scoreboard.html +70 -66
- data/doc/classes/TaskJuggler/Shift.html +18 -18
- data/doc/classes/TaskJuggler/ShiftAssignment.html +58 -54
- data/doc/classes/TaskJuggler/ShiftAssignments.html +82 -78
- data/doc/classes/TaskJuggler/ShiftAssignmentsAttribute.html +40 -40
- data/doc/classes/TaskJuggler/ShiftScenario.html +24 -24
- data/doc/classes/TaskJuggler/SortListAttribute.html +196 -0
- data/doc/classes/TaskJuggler/SourceFileInfo.html +16 -12
- data/doc/classes/TaskJuggler/StringAttribute.html +30 -30
- data/doc/classes/TaskJuggler/SymbolAttribute.html +20 -20
- data/doc/classes/TaskJuggler/SyntaxReference.html +46 -42
- data/doc/classes/TaskJuggler/TOCEntry.html +16 -12
- data/doc/classes/TaskJuggler/TableColumnDefinition.html +48 -33
- data/doc/classes/TaskJuggler/TableOfContents.html +22 -18
- data/doc/classes/TaskJuggler/TableReport.html +1036 -0
- data/doc/classes/TaskJuggler/Task.html +12 -12
- data/doc/classes/TaskJuggler/TaskDependency.html +16 -12
- data/doc/classes/TaskJuggler/TaskListAttribute.html +46 -46
- data/doc/classes/TaskJuggler/TaskListRE.html +49 -58
- data/doc/classes/TaskJuggler/TaskScenario.html +1270 -1180
- data/doc/classes/TaskJuggler/TextParser/Pattern.html +100 -96
- data/doc/classes/TaskJuggler/TextParser/Rule.html +88 -84
- data/doc/classes/TaskJuggler/TextParser/StackElement.html +16 -12
- data/doc/classes/TaskJuggler/TextParser/TextParserResultArray.html +12 -12
- data/doc/classes/TaskJuggler/TextParser/TokenDoc.html +10 -6
- data/doc/classes/TaskJuggler/TextParser.html +203 -140
- data/doc/classes/TaskJuggler/TextReport.html +364 -0
- data/doc/classes/TaskJuggler/TextScanner/BufferStreamHandle.html +70 -70
- data/doc/classes/TaskJuggler/TextScanner/FileStreamHandle.html +50 -42
- data/doc/classes/TaskJuggler/TextScanner/StreamHandle.html +16 -12
- data/doc/classes/TaskJuggler/TextScanner.html +334 -240
- data/doc/classes/TaskJuggler/TjException.html +6 -6
- data/doc/classes/TaskJuggler/TjTime.html +547 -497
- data/doc/classes/TaskJuggler/TjpExample.html +29 -25
- data/doc/classes/TaskJuggler/TjpExportRE.html +77 -97
- data/doc/classes/TaskJuggler/TjpSyntaxRules.html +3911 -3886
- data/doc/classes/TaskJuggler/UserManual.html +54 -54
- data/doc/classes/TaskJuggler/WorkingHours.html +53 -49
- data/doc/classes/TaskJuggler/WorkingHoursAttribute.html +53 -85
- data/doc/classes/TaskJuggler/XMLBlob.html +21 -21
- data/doc/classes/TaskJuggler/XMLComment.html +21 -21
- data/doc/classes/TaskJuggler/XMLDocument.html +28 -24
- data/doc/classes/TaskJuggler/XMLElement.html +70 -58
- data/doc/classes/TaskJuggler/XMLNamedText.html +11 -11
- data/doc/classes/TaskJuggler/XMLText.html +36 -36
- data/doc/classes/TaskJuggler.html +266 -183
- data/doc/files/COPYING.html +1 -1
- data/doc/files/README.html +1 -1
- data/doc/files/lib/AccountScenario_rb.html +1 -1
- data/doc/files/lib/Account_rb.html +1 -1
- data/doc/files/lib/Allocation_rb.html +1 -1
- data/doc/files/lib/AppConfig_rb.html +1 -1
- data/doc/files/lib/AttributeBase_rb.html +11 -1
- data/doc/files/lib/AttributeDefinition_rb.html +1 -1
- data/doc/files/lib/Attributes_rb.html +1 -1
- data/doc/files/lib/{LogicalFlag_rb.html → BatchProcessor_rb.html} +8 -6
- data/doc/files/lib/Booking_rb.html +1 -1
- data/doc/files/lib/ChargeSet_rb.html +1 -1
- data/doc/files/lib/Charge_rb.html +1 -1
- data/doc/files/lib/HTMLDocument_rb.html +1 -1
- data/doc/files/lib/Interval_rb.html +1 -1
- data/doc/files/lib/Journal_rb.html +106 -0
- data/doc/files/lib/KeywordArray_rb.html +106 -0
- data/doc/files/lib/KeywordDocumentation_rb.html +1 -1
- data/doc/files/lib/Limits_rb.html +1 -1
- data/doc/files/lib/Log_rb.html +1 -1
- data/doc/files/lib/LogicalExpression_rb.html +1 -3
- data/doc/files/lib/LogicalFunction_rb.html +1 -1
- data/doc/files/lib/LogicalOperation_rb.html +1 -1
- data/doc/files/lib/MacroParser_rb.html +1 -1
- data/doc/files/lib/MacroTable_rb.html +1 -1
- data/doc/files/lib/MessageHandler_rb.html +1 -1
- data/doc/files/lib/Message_rb.html +1 -1
- data/doc/files/lib/ProjectFileParser_rb.html +5 -1
- data/doc/files/lib/Project_rb.html +5 -1
- data/doc/files/lib/PropertyList_rb.html +1 -1
- data/doc/files/lib/PropertySet_rb.html +1 -1
- data/doc/files/lib/PropertyTreeNode_rb.html +1 -1
- data/doc/files/lib/Query_rb.html +1 -1
- data/doc/files/lib/RTPNavigator_rb.html +120 -0
- data/doc/files/lib/RTPReport_rb.html +118 -0
- data/doc/files/lib/RealFormat_rb.html +1 -1
- data/doc/files/lib/ResourceScenario_rb.html +1 -1
- data/doc/files/lib/Resource_rb.html +1 -1
- data/doc/files/lib/RichTextDocument_rb.html +1 -1
- data/doc/files/lib/RichTextElement_rb.html +1 -1
- data/doc/files/lib/RichTextParser_rb.html +1 -1
- data/doc/files/lib/RichTextProtocolExample_rb.html +1 -1
- data/doc/files/lib/RichTextProtocolHandler_rb.html +1 -1
- data/doc/files/lib/RichTextScanner_rb.html +1 -1
- data/doc/files/lib/RichTextSnip_rb.html +1 -1
- data/doc/files/lib/RichTextSyntaxRules_rb.html +1 -1
- data/doc/files/lib/RichText_rb.html +1 -1
- data/doc/files/lib/ScenarioData_rb.html +1 -1
- data/doc/files/lib/Scenario_rb.html +1 -1
- data/doc/files/lib/Scoreboard_rb.html +1 -1
- data/doc/files/lib/ShiftAssignments_rb.html +1 -1
- data/doc/files/lib/ShiftScenario_rb.html +1 -1
- data/doc/files/lib/Shift_rb.html +1 -1
- data/doc/files/lib/SourceFileInfo_rb.html +1 -1
- data/doc/files/lib/SyntaxReference_rb.html +1 -1
- data/doc/files/lib/TOCEntry_rb.html +1 -1
- data/doc/files/lib/TableColumnDefinition_rb.html +1 -1
- data/doc/files/lib/TableOfContents_rb.html +1 -1
- data/doc/files/lib/TaskDependency_rb.html +1 -1
- data/doc/files/lib/TaskJuggler_rb.html +1 -1
- data/doc/files/lib/TaskScenario_rb.html +1 -1
- data/doc/files/lib/Task_rb.html +1 -1
- data/doc/files/lib/TextParser/Pattern_rb.html +1 -1
- data/doc/files/lib/TextParser/Rule_rb.html +1 -1
- data/doc/files/lib/TextParser/StackElement_rb.html +1 -1
- data/doc/files/lib/TextParser/TokenDoc_rb.html +1 -1
- data/doc/files/lib/TextParser_rb.html +1 -1
- data/doc/files/lib/TextScanner_rb.html +1 -1
- data/doc/files/lib/Tj3Config_rb.html +1 -1
- data/doc/files/lib/TjException_rb.html +1 -1
- data/doc/files/lib/TjTime_rb.html +1 -1
- data/doc/files/lib/TjpExample_rb.html +1 -1
- data/doc/files/lib/TjpSyntaxRules_rb.html +1 -1
- data/doc/files/lib/UTF8String_rb.html +1 -1
- data/doc/files/lib/UserManual_rb.html +1 -1
- data/doc/files/lib/WorkingHours_rb.html +1 -1
- data/doc/files/lib/XMLDocument_rb.html +1 -1
- data/doc/files/lib/XMLElement_rb.html +1 -1
- data/doc/files/lib/deep_copy_rb.html +106 -0
- data/doc/files/lib/ms_test_rb.html +90 -0
- data/doc/files/lib/reports/CSVFile_rb.html +1 -1
- data/doc/files/lib/reports/ColumnTable_rb.html +1 -1
- data/doc/files/lib/reports/GanttChart_rb.html +1 -1
- data/doc/files/lib/reports/GanttContainer_rb.html +1 -1
- data/doc/files/lib/reports/GanttHeaderScaleItem_rb.html +1 -1
- data/doc/files/lib/reports/GanttHeader_rb.html +1 -1
- data/doc/files/lib/reports/GanttLine_rb.html +1 -1
- data/doc/files/lib/reports/GanttLoadStack_rb.html +1 -1
- data/doc/files/lib/reports/GanttMilestone_rb.html +1 -1
- data/doc/files/lib/reports/GanttRouter_rb.html +1 -1
- data/doc/files/lib/reports/GanttTaskBar_rb.html +1 -1
- data/doc/files/lib/reports/HTMLGraphics_rb.html +1 -1
- data/doc/files/lib/reports/{ReportElement_rb.html → Navigator_rb.html} +6 -8
- data/doc/files/lib/reports/ReportBase_rb.html +106 -0
- data/doc/files/lib/reports/ReportContext_rb.html +106 -0
- data/doc/files/lib/reports/ReportTableCell_rb.html +1 -1
- data/doc/files/lib/reports/ReportTableColumn_rb.html +1 -1
- data/doc/files/lib/reports/ReportTableLegend_rb.html +1 -1
- data/doc/files/lib/reports/ReportTableLine_rb.html +1 -1
- data/doc/files/lib/reports/ReportTable_rb.html +1 -1
- data/doc/files/lib/reports/Report_rb.html +8 -2
- data/doc/files/lib/reports/ResourceListRE_rb.html +2 -2
- data/doc/files/lib/reports/{ReportTableElement_rb.html → TableReport_rb.html} +7 -5
- data/doc/files/lib/reports/TaskListRE_rb.html +2 -2
- data/doc/files/lib/reports/TextReport_rb.html +116 -0
- data/doc/files/lib/reports/TjpExportRE_rb.html +2 -2
- data/doc/files/lib/taskjuggler3_rb.html +61 -56
- data/doc/files/lib/tj3man_rb.html +1 -1
- data/doc/fr_class_index.html +41 -3
- data/doc/fr_file_index.html +21 -5
- data/doc/fr_method_index.html +1069 -959
- data/examples/ContactList.html +1467 -0
- data/examples/Deliveries.html +485 -0
- data/examples/Development.html +2525 -0
- data/examples/Overview.html +747 -0
- data/examples/Resource Graph.html +616 -0
- data/examples/tutorial.tjp +63 -67
- data/lib/AttributeBase.rb +27 -31
- data/lib/AttributeDefinition.rb +12 -7
- data/lib/Attributes.rb +134 -34
- data/lib/Interval.rb +2 -0
- data/lib/Journal.rb +44 -0
- data/lib/{LogicalFlag.rb → KeywordArray.rb} +5 -13
- data/lib/KeywordDocumentation.rb +84 -47
- data/lib/Limits.rb +7 -5
- data/lib/LogicalExpression.rb +1 -1
- data/lib/LogicalOperation.rb +33 -0
- data/lib/Project.rb +313 -99
- data/lib/ProjectFileParser.rb +88 -11
- data/lib/PropertyList.rb +2 -1
- data/lib/PropertySet.rb +13 -4
- data/lib/PropertyTreeNode.rb +34 -15
- data/lib/Query.rb +2 -1
- data/lib/RTPNavigator.rb +53 -0
- data/lib/RTPReport.rb +62 -0
- data/lib/RealFormat.rb +28 -10
- data/lib/RichTextElement.rb +18 -12
- data/lib/RichTextParser.rb +1 -0
- data/lib/RichTextProtocolExample.rb +8 -11
- data/lib/RichTextProtocolHandler.rb +11 -1
- data/lib/RichTextScanner.rb +308 -164
- data/lib/RichTextSyntaxRules.rb +24 -0
- data/lib/TableColumnDefinition.rb +5 -1
- data/lib/TaskJuggler.rb +3 -2
- data/lib/TaskScenario.rb +123 -31
- data/lib/TextParser.rb +14 -3
- data/lib/TextScanner.rb +210 -34
- data/lib/Tj3Config.rb +1 -1
- data/lib/TjTime.rb +15 -0
- data/lib/TjpExample.rb +1 -1
- data/lib/TjpSyntaxRules.rb +674 -473
- data/lib/WorkingHours.rb +1 -1
- data/lib/XMLElement.rb +11 -3
- data/lib/deep_copy.rb +72 -0
- data/lib/ms_test.rb +27 -0
- data/lib/reports/ColumnTable.rb +7 -5
- data/lib/reports/GanttChart.rb +60 -34
- data/lib/reports/GanttHeader.rb +1 -1
- data/lib/reports/GanttRouter.rb +7 -5
- data/lib/reports/Navigator.rb +72 -0
- data/lib/reports/Report.rb +58 -73
- data/lib/reports/ReportBase.rb +241 -0
- data/lib/reports/ReportContext.rb +41 -0
- data/lib/reports/ReportTable.rb +7 -2
- data/lib/reports/ReportTableCell.rb +3 -3
- data/lib/reports/ResourceListRE.rb +19 -26
- data/lib/reports/{ReportTableElement.rb → TableReport.rb} +297 -97
- data/lib/reports/TaskListRE.rb +16 -24
- data/lib/reports/TextReport.rb +87 -0
- data/lib/reports/TjpExportRE.rb +55 -50
- data/lib/taskjuggler3.rb +6 -1
- data/manual/Getting_Started +57 -6
- data/manual/How_To_Contribute +2 -4
- data/manual/Intro +2 -2
- data/manual/Reporting_Bugs +9 -2
- data/manual/Rich_Text_Attributes +41 -0
- data/manual/Tutorial +219 -173
- data/tasks/test.rake +3 -0
- data/test/TestSuite/CSV-Reports/celltext.tjp +2 -1
- data/test/TestSuite/CSV-Reports/resourcereport.tjp +2 -1
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks.tjp +2 -1
- data/test/TestSuite/CSV-Reports/sortByTree.tjp +2 -1
- data/test/TestSuite/CSV-Reports/sortBy_duration.down.tjp +2 -1
- data/test/TestSuite/CSV-Reports/sortBy_effort.up.tjp +2 -1
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down.tjp +2 -1
- data/test/TestSuite/CSV-Reports/taskreport.tjp +2 -1
- data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +2 -1
- data/test/TestSuite/HTML-Reports/depArrows.tjp +72 -0
- data/test/TestSuite/HTML-Reports/reference-export.html +187 -0
- data/test/TestSuite/HTML-Reports/reference.tjp +21 -0
- data/test/TestSuite/Scheduler/Correct/Allocate.tjp +2 -1
- data/test/TestSuite/Scheduler/Correct/AutomaticMilestones.tjp +3 -3
- data/test/TestSuite/Scheduler/Correct/Booking.tjp +3 -3
- data/test/TestSuite/Scheduler/Correct/Container-2.tjp +37 -0
- data/test/TestSuite/Scheduler/Correct/Container.tjp +40 -0
- data/test/TestSuite/Scheduler/Correct/Depends.tjp +9 -14
- data/test/TestSuite/Scheduler/Correct/Duration.tjp +2 -1
- data/test/TestSuite/Scheduler/Correct/InheritStartEnd.tjp +20 -29
- data/test/TestSuite/Scheduler/Correct/Limits.tjp +11 -13
- data/test/TestSuite/Scheduler/Correct/Optimize-1.tjp +6 -5
- data/test/TestSuite/Scheduler/Correct/Optimize-2.tjp +10 -6
- data/test/TestSuite/Scheduler/Correct/Optimize-3.tjp +9 -6
- data/test/TestSuite/Scheduler/Correct/Optimize-4.tjp +9 -6
- data/test/TestSuite/Scheduler/Correct/Optimize-5.tjp +13 -10
- data/test/TestSuite/Scheduler/Correct/Precedes.tjp +9 -14
- data/test/TestSuite/Scheduler/Correct/Shift.tjp +9 -8
- data/test/TestSuite/Scheduler/Correct/checks.tji +4 -0
- data/test/TestSuite/Scheduler/Errors/weak_end_dep.tjp +16 -0
- data/test/TestSuite/Scheduler/Errors/weak_start_dep.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/Account.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/AutoID.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/AutoMacros.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/Caption.tjp +7 -6
- data/test/TestSuite/Syntax/Correct/Celltext.tjp +7 -4
- data/test/TestSuite/Syntax/Correct/Comments.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/CompletedWork.tji +11 -19
- data/test/TestSuite/Syntax/Correct/CriticalPath.tjp +4 -3
- data/test/TestSuite/Syntax/Correct/Export.tjp +3 -1
- data/test/TestSuite/Syntax/Correct/Flags.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/HtmlTaskReport.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/Journal.tjp +18 -0
- data/test/TestSuite/Syntax/Correct/LoadUnits.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/Period.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/RawHTML.tjp +4 -2
- data/test/TestSuite/Syntax/Correct/Reports.tjp +4 -2
- data/test/TestSuite/Syntax/Correct/ResourcePrefix.tji +2 -0
- data/test/TestSuite/Syntax/Correct/ResourcePrefix.tjp +23 -0
- data/test/TestSuite/Syntax/Correct/Responsible.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/Simple.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/String.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +92 -70
- data/test/TestSuite/Syntax/Errors/bad_comment.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/bad_include.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/bad_time_zone.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/bad_timing_res.tjp +5 -0
- data/test/TestSuite/Syntax/Errors/chargeset_master.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/container_attribute.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/cost_acct_no_top.tjp +3 -2
- data/test/TestSuite/Syntax/Errors/cost_rev_same.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/eof_in_istring1.tjp +5 -0
- data/test/TestSuite/Syntax/Errors/eof_in_istring2.tjp +5 -0
- data/test/TestSuite/Syntax/Errors/eof_in_istring3.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/eof_in_istring4.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/eof_in_istring5.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/include_recursion.tji +1 -0
- data/test/TestSuite/Syntax/Errors/include_recursion.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/junk_after_cut.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/navigator_exists.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/operand_unkn_flag.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/report_end.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/report_exists.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/report_start.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/rev_acct_no_top.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/sort_direction.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/sort_unknown_scen.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/sorting_crit_exptd1.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/sorting_crit_exptd2.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/sorting_wbs.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/too_large_timing_res.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/unknown_scenario_idx.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/unknown_task.tjp +1 -1
- data/test/all.rb +1 -16
- data/test/test_CSV-Reports.rb +8 -5
- data/test/test_Query.rb +2 -2
- data/test/test_RichText.rb +95 -0
- data/test/test_Scheduler.rb +8 -4
- data/test/test_Syntax.rb +8 -4
- data/test/test_deep_copy.rb +83 -0
- metadata +549 -487
- data/benchmarks/UTF-8-Strings.rb +0 -58
- data/doc/classes/TaskJuggler/ReportElement.html +0 -1070
- data/doc/classes/TaskJuggler/ReportTableElement.html +0 -644
- data/lib/reports/ReportElement.rb +0 -427
- data/test/TestSuite/Syntax/Correct/csvtest +0 -16
- data/test/TestSuite/Syntax/Errors/no_csv_suffix.tjp +0 -10
- data/test/TestSuite/Syntax/Errors/no_html_suffix.tjp +0 -10
- data/test/TestSuite/Syntax/Errors/report_redifinition.tjp +0 -10
data/lib/WorkingHours.rb
CHANGED
|
@@ -159,7 +159,7 @@ class TaskJuggler
|
|
|
159
159
|
# Return true of the given WorkingHours object +wh+ is identical to this
|
|
160
160
|
# object.
|
|
161
161
|
def ==(wh)
|
|
162
|
-
return false if @timezone != wh.timezone
|
|
162
|
+
return false if wh.nil? || @timezone != wh.timezone
|
|
163
163
|
|
|
164
164
|
7.times do |d|
|
|
165
165
|
return false if @days[d].length != wh.days[d].length
|
data/lib/XMLElement.rb
CHANGED
|
@@ -45,11 +45,19 @@ class TaskJuggler
|
|
|
45
45
|
if arg.is_a?(XMLElement)
|
|
46
46
|
@children << arg
|
|
47
47
|
elsif arg.is_a?(Array)
|
|
48
|
+
# Delete all nil entries
|
|
49
|
+
arg.delete_if { |i| i.nil? }
|
|
50
|
+
# Check that the rest are really all XMLElement objects.
|
|
51
|
+
arg.each do |i|
|
|
52
|
+
unless i.is_a?(XMLElement)
|
|
53
|
+
raise "Element must be of type XMLElement not #{i.class}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
48
56
|
@children += arg
|
|
49
57
|
elsif arg.nil?
|
|
50
58
|
# do nothing
|
|
51
59
|
else
|
|
52
|
-
raise
|
|
60
|
+
raise "Elements must be of type XMLElement not #{arg.class}"
|
|
53
61
|
end
|
|
54
62
|
self
|
|
55
63
|
end
|
|
@@ -57,8 +65,8 @@ class TaskJuggler
|
|
|
57
65
|
# Return the element and all sub elements as properly formatted XML.
|
|
58
66
|
def to_s(indent = 0)
|
|
59
67
|
out = '<' + @name
|
|
60
|
-
@attributes.each do |attrName
|
|
61
|
-
out <<
|
|
68
|
+
@attributes.keys.sort.each do |attrName|
|
|
69
|
+
out << " #{attrName}=\"#{quoteAttr(@attributes[attrName])}\""
|
|
62
70
|
end
|
|
63
71
|
if @children.empty? && !@mayNotBeEmpty
|
|
64
72
|
out << '/>'
|
data/lib/deep_copy.rb
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = deep_copy.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
|
+
# This file extends some Ruby core classes to add deep-copying support. I'm
|
|
14
|
+
# aware of the commonly suggested method using Marshal:
|
|
15
|
+
#
|
|
16
|
+
# class Object
|
|
17
|
+
# def deep_copy
|
|
18
|
+
# Marshal.load(Marshal.dump(self))
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# But just because I program in Ruby, I don't have to write bloatware. It's
|
|
23
|
+
# like taking a trip to the moon and back to shop groceries at the store
|
|
24
|
+
# around the corner. I'm not sure if I need more special cases than Array and
|
|
25
|
+
# Hash, but this file works for me.
|
|
26
|
+
#
|
|
27
|
+
# In certain cases the full deep copy may not be desired. To preserve
|
|
28
|
+
# references to objects, you need to overload deep_clone and handle the
|
|
29
|
+
# special cases. Alternatively, an object can be frozen to prevent deep
|
|
30
|
+
# copies.
|
|
31
|
+
|
|
32
|
+
class Object
|
|
33
|
+
|
|
34
|
+
# This is a variant of Object#clone that returns a deep copy of an object.
|
|
35
|
+
def deep_clone
|
|
36
|
+
# We can't clone frozen objects. So just return a reference to them.
|
|
37
|
+
return self if frozen?
|
|
38
|
+
|
|
39
|
+
# In case we have loops in our graph, we return references, not
|
|
40
|
+
# deep-copied objects.
|
|
41
|
+
if RUBY_VERSION < '1.9.0'
|
|
42
|
+
return @clonedObject if instance_variables.include?('@clonedObject')
|
|
43
|
+
else
|
|
44
|
+
return @clonedObject if instance_variables.include?(:@clonedObject)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Clone the current Object (shallow copy with internal state)
|
|
48
|
+
begin
|
|
49
|
+
@clonedObject = clone
|
|
50
|
+
rescue TypeError
|
|
51
|
+
return self
|
|
52
|
+
end
|
|
53
|
+
# Recursively copy all instance variables.
|
|
54
|
+
@clonedObject.instance_variables.each do |var|
|
|
55
|
+
val = instance_variable_get(var).deep_clone
|
|
56
|
+
@clonedObject.instance_variable_set(var, val)
|
|
57
|
+
end
|
|
58
|
+
if kind_of?(Array)
|
|
59
|
+
@clonedObject.collect! { |x| x.deep_clone }
|
|
60
|
+
elsif kind_of?(Hash)
|
|
61
|
+
@clonedObject.each { |key, val| store(key, val.deep_clone) }
|
|
62
|
+
end
|
|
63
|
+
# Remove the @clonedObject again.
|
|
64
|
+
if RUBY_VERSION < '1.9.0'
|
|
65
|
+
remove_instance_variable('@clonedObject')
|
|
66
|
+
else
|
|
67
|
+
remove_instance_variable(:@clonedObject)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
data/lib/ms_test.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
project mstest "Milestone test" "1.0" 2009-06-22 +1y {
|
|
2
|
+
extend task {
|
|
3
|
+
reference Url "URL"
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
resource tux "Tux" {
|
|
8
|
+
vacation 2009-06-29 +1.5w
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
task foo "Foo" {
|
|
12
|
+
task post_ms "Post MS" {
|
|
13
|
+
start 2009-06-22
|
|
14
|
+
}
|
|
15
|
+
task milestone "MS" {
|
|
16
|
+
effort 10d
|
|
17
|
+
allocate tux
|
|
18
|
+
Url "http://www.amd64.org"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
resourcereport mstest "mstest" {
|
|
23
|
+
formats html
|
|
24
|
+
period 2009-06-25 +2m
|
|
25
|
+
columns no, name, weekly
|
|
26
|
+
hidetask 0
|
|
27
|
+
}
|
data/lib/reports/ColumnTable.rb
CHANGED
|
@@ -44,19 +44,21 @@ class TaskJuggler
|
|
|
44
44
|
# Now we generate a 'div' that will contain the nested table. It has a
|
|
45
45
|
# height that fits all lines but has a maximum width. In case the embedded
|
|
46
46
|
# table is larger, a scrollbar will appear. We assume that the scrollbar
|
|
47
|
-
# has a height of
|
|
47
|
+
# has a height of SCROLLBARHEIGHT pixels or less.
|
|
48
48
|
# Due to Firefoxes broken table rendering we have to specify a minimum
|
|
49
49
|
# width. It may not excede the maxWidth value.
|
|
50
50
|
mWidth = minWidth
|
|
51
51
|
mWidth = @maxWidth if mWidth > @maxWidth
|
|
52
52
|
td << (scrollDiv = XMLElement.new('div', 'class' => 'tabback',
|
|
53
53
|
'style' => 'position:relative; overflow:auto; ' +
|
|
54
|
-
"
|
|
55
|
-
"min-width:#{mWidth}px; " +
|
|
54
|
+
"width:#{mWidth}px; " +
|
|
56
55
|
'margin-top:-1px; margin-bottom:-1px; ' +
|
|
57
|
-
"height:#{height +
|
|
56
|
+
"height:#{height + SCROLLBARHEIGHT + 2}px;"))
|
|
58
57
|
|
|
59
|
-
scrollDiv <<
|
|
58
|
+
scrollDiv << (contentDiv = XMLElement.new('div',
|
|
59
|
+
'style' => 'margin: 0px; padding: 0px; position: absolute; top: 0px;' +
|
|
60
|
+
"left: 0px; width: #{@maxWidth}px; height: #{height}px; "))
|
|
61
|
+
contentDiv << super
|
|
60
62
|
td
|
|
61
63
|
end
|
|
62
64
|
|
data/lib/reports/GanttChart.rb
CHANGED
|
@@ -27,6 +27,10 @@ class TaskJuggler
|
|
|
27
27
|
# created, the user must call generateByWidth or generateByResolution.
|
|
28
28
|
class GanttChart
|
|
29
29
|
|
|
30
|
+
# The height in pixels of a horizontal scrollbar on an HTML page. This
|
|
31
|
+
# value should be large enough to work for all browsers.
|
|
32
|
+
SCROLLBARHEIGHT = 20
|
|
33
|
+
|
|
30
34
|
include HTMLGraphics
|
|
31
35
|
|
|
32
36
|
attr_reader :start, :end, :now, :weekStartsMonday, :header, :width,
|
|
@@ -37,7 +41,7 @@ class TaskJuggler
|
|
|
37
41
|
# more information about the chart before we can actually generate it. _now_
|
|
38
42
|
# is the date that should be used as current date. _weekStartsMonday_ is
|
|
39
43
|
# true if the weeks should start on Mondays instead of Sundays. _table_ is a
|
|
40
|
-
# reference to the
|
|
44
|
+
# reference to the TableReport that the chart is part of.
|
|
41
45
|
def initialize(now, weekStartsMonday, table = nil)
|
|
42
46
|
# The start and end dates of the reported interval.
|
|
43
47
|
@start = nil
|
|
@@ -146,15 +150,17 @@ class TaskJuggler
|
|
|
146
150
|
'style' => 'padding:0px; vertical-align:top;')
|
|
147
151
|
# Now we generate two 'div's nested into each other. The first div is the
|
|
148
152
|
# 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
|
|
150
|
-
# heigher to hold the scrollbar. Unfortunately
|
|
151
|
-
# value even though the height of the scrollbar
|
|
152
|
-
# system. This value should be good enough for
|
|
153
|
-
|
|
153
|
+
# first one. In case we need a scrollbar The outer div is
|
|
154
|
+
# SCROLLBARHEIGHT pixels heigher to hold the scrollbar. Unfortunately
|
|
155
|
+
# this must be a hardcoded value even though the height of the scrollbar
|
|
156
|
+
# varies from system to system. This value should be good enough for
|
|
157
|
+
# most systems.
|
|
158
|
+
td << (scrollDiv = XMLElement.new('div', 'class' => 'tabback',
|
|
154
159
|
'style' => 'position:relative; ' +
|
|
155
160
|
"overflow:auto; " +
|
|
156
161
|
"width:#{hasScrollbar? ? @viewWidth : @width}px; " +
|
|
157
|
-
"height:#{@height +
|
|
162
|
+
"height:#{@height +
|
|
163
|
+
(hasScrollbar? ? SCROLLBARHEIGHT : 0)}px;"))
|
|
158
164
|
scrollDiv << (div = XMLElement.new('div',
|
|
159
165
|
'style' => "margin:0px; padding:0px; " +
|
|
160
166
|
"position:absolute; " +
|
|
@@ -244,7 +250,7 @@ class TaskJuggler
|
|
|
244
250
|
@router.addZone(@header.nowLineX - 1, 0, 3, @height - 1, false, true)
|
|
245
251
|
|
|
246
252
|
@tasks.each do |task, lines|
|
|
247
|
-
|
|
253
|
+
generateDepArrows(task, lines)
|
|
248
254
|
end
|
|
249
255
|
end
|
|
250
256
|
|
|
@@ -252,41 +258,61 @@ class TaskJuggler
|
|
|
252
258
|
# for a specific _task_. _lines_ is a list of GanttLines that the tasks are
|
|
253
259
|
# displayed on. Reports with multiple scenarios have multiple lines per
|
|
254
260
|
# task.
|
|
255
|
-
def
|
|
261
|
+
def generateDepArrows(task, lines)
|
|
256
262
|
# Since we need the line and the index we use an index iterator.
|
|
257
263
|
lines.length.times do |lineIndex|
|
|
258
264
|
line = lines[lineIndex]
|
|
259
265
|
scenarioIdx = line.scenarioIdx
|
|
260
266
|
|
|
261
267
|
# Generate the dependencies on the start of the task.
|
|
262
|
-
|
|
263
|
-
|
|
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
|
|
268
|
+
collectAndSortArrows('startsuccs', task, scenarioIdx, lineIndex,
|
|
269
|
+
*line.getTask.startDepLineStart)
|
|
275
270
|
|
|
276
271
|
# Generate the dependencies on the end of the task.
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
272
|
+
collectAndSortArrows('endsuccs', task, scenarioIdx, lineIndex,
|
|
273
|
+
*line.getTask.endDepLineStart)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Generate the dependencies on the start or end of the task depending on
|
|
278
|
+
# _kind_. Use 'startsuccs' for the start and 'endsuccs' for end. _startX_
|
|
279
|
+
# and _startY_ are the graphic coordinates for the begin of the arrow
|
|
280
|
+
# line. _task_ references the Task in question and _scenarioIdx_ the
|
|
281
|
+
# scenario. _lineIndex_ specifies the line number in the chart.
|
|
282
|
+
def collectAndSortArrows(kind, task, scenarioIdx, lineIndex, startX, startY)
|
|
283
|
+
# We need to sort the arrows. This is an Array that holds 6 values for
|
|
284
|
+
# each entry: The x and y coordinates for start and end points, the
|
|
285
|
+
# sinus value of the angle between a vertical and the line specified by
|
|
286
|
+
# the points and the length of the line.
|
|
287
|
+
touples = []
|
|
288
|
+
task[kind, scenarioIdx].each do |t, onEnd|
|
|
289
|
+
# Skip inherited dependencies and tasks that are not included in the
|
|
290
|
+
# chart.
|
|
291
|
+
if (t.parent &&
|
|
292
|
+
task.hasDependency?(scenarioIdx, kind, t.parent, onEnd)) ||
|
|
293
|
+
!@tasks.include?(t)
|
|
294
|
+
next
|
|
289
295
|
end
|
|
296
|
+
endX, endY = @tasks[t][lineIndex].getTask.send(
|
|
297
|
+
onEnd ? :endDepLineEnd : :startDepLineEnd)
|
|
298
|
+
# To make sure that we minimize the crossings of arrows that
|
|
299
|
+
# originate from the same position, we sort the arrows by the
|
|
300
|
+
# smallest angle between the vertical line through the task end
|
|
301
|
+
# and the line between the start and end of the arrow.
|
|
302
|
+
oppLeg = endX - startX
|
|
303
|
+
adjLeg = (startY - endY).abs
|
|
304
|
+
hypothenuse = Math.sqrt(adjLeg ** 2 + oppLeg ** 2)
|
|
305
|
+
# We can now calculate the sinus values of the angle between the
|
|
306
|
+
# vertical and a line through the coordinates.
|
|
307
|
+
touples << [ startX, startY, endX, endY,
|
|
308
|
+
(oppLeg / hypothenuse), hypothenuse ]
|
|
309
|
+
end
|
|
310
|
+
# We sort the arrows from small to a large angle. In case the angle is
|
|
311
|
+
# identical, we use the length of the line as second criteria.
|
|
312
|
+
touples.sort! { |t1, t2| t1[4] == t2[4] ? t1[5] <=> t2[5] :
|
|
313
|
+
t1[4] <=> t2[4] }
|
|
314
|
+
touples.each do |t|
|
|
315
|
+
routeArrow(*t[0, 4])
|
|
290
316
|
end
|
|
291
317
|
end
|
|
292
318
|
|
data/lib/reports/GanttHeader.rb
CHANGED
|
@@ -74,7 +74,7 @@ class TaskJuggler
|
|
|
74
74
|
:hour)
|
|
75
75
|
when 'day'
|
|
76
76
|
genHeaderScale(@largeScale, 0, h, :beginOfMonth, :sameTimeNextMonth,
|
|
77
|
-
:
|
|
77
|
+
:monthAndYear)
|
|
78
78
|
genHeaderScale(@smallScale, h + 1, h, :midnight, :sameTimeNextDay, :day)
|
|
79
79
|
when 'week'
|
|
80
80
|
genHeaderScale(@largeScale, 0, h, :beginOfMonth, :sameTimeNextMonth,
|
data/lib/reports/GanttRouter.rb
CHANGED
|
@@ -93,7 +93,8 @@ class TaskJuggler
|
|
|
93
93
|
# 2------X end Point
|
|
94
94
|
# |endGap|
|
|
95
95
|
#
|
|
96
|
-
xSeg = placeLine([ startPoint[1]
|
|
96
|
+
xSeg = placeLine([ startPoint[1] + (startPoint[1] < endPoint[1] ?
|
|
97
|
+
1 : -1), endPoint[1] ],
|
|
97
98
|
false, startPoint[0] + startGap, 1)
|
|
98
99
|
if xSeg && xSeg < endPoint[0] - endGap
|
|
99
100
|
addLineTo(points, xSeg, startPoint[1]) # Point 1
|
|
@@ -108,7 +109,7 @@ class TaskJuggler
|
|
|
108
109
|
#
|
|
109
110
|
# x1
|
|
110
111
|
# |startGap|
|
|
111
|
-
# startPoint X--------1
|
|
112
|
+
# startPoint X--------1 yLS
|
|
112
113
|
# |
|
|
113
114
|
# 3---------------2 ySeg
|
|
114
115
|
# |
|
|
@@ -119,11 +120,12 @@ class TaskJuggler
|
|
|
119
120
|
# Place horizontal segue. We don't know the width yet, so we have to
|
|
120
121
|
# assume full width. That's acceptable for horizontal lines.
|
|
121
122
|
ySeg = placeLine([ 0, @width - 1 ], true, startPoint[1],
|
|
122
|
-
|
|
123
|
+
startPoint[1] < endPoint[1] ? 1 : -1)
|
|
123
124
|
raise "Routing failed" unless ySeg
|
|
124
125
|
|
|
125
126
|
# Place 1st vertical
|
|
126
|
-
x1 = placeLine([ startPoint[1]
|
|
127
|
+
x1 = placeLine([ startPoint[1] + (startPoint[1] < endPoint[1] ? 1 : -1),
|
|
128
|
+
ySeg ], false, startPoint[0] + startGap, 1)
|
|
127
129
|
raise "Routing failed" unless x1
|
|
128
130
|
|
|
129
131
|
# Place 2nd vertical
|
|
@@ -297,7 +299,7 @@ class TaskJuggler
|
|
|
297
299
|
segment.sort!
|
|
298
300
|
lines = horizontal ? @hLines : @vLines
|
|
299
301
|
# TODO: Remove this check once the code becomes stable.
|
|
300
|
-
checkLines(lines)
|
|
302
|
+
#checkLines(lines)
|
|
301
303
|
while collision?(lines[pos], segment)
|
|
302
304
|
pos += delta
|
|
303
305
|
# Check if we have exceded the chart area towards top/left.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = Navigator.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/ReportContext'
|
|
14
|
+
|
|
15
|
+
class TaskJuggler
|
|
16
|
+
|
|
17
|
+
class Navigator
|
|
18
|
+
|
|
19
|
+
attr_reader :id
|
|
20
|
+
attr_accessor :hideReport
|
|
21
|
+
|
|
22
|
+
def initialize(id, project)
|
|
23
|
+
@id = id
|
|
24
|
+
@project = project
|
|
25
|
+
@hideReport = LogicalExpression.new(LogicalOperation.new(0))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_html
|
|
29
|
+
reports = filterReports
|
|
30
|
+
return nil if reports.empty?
|
|
31
|
+
|
|
32
|
+
first = true
|
|
33
|
+
html = []
|
|
34
|
+
html << (div = XMLElement.new('div'))
|
|
35
|
+
reports.each do |report|
|
|
36
|
+
next unless report.get('formats').include?(:html)
|
|
37
|
+
|
|
38
|
+
if first
|
|
39
|
+
first = false
|
|
40
|
+
else
|
|
41
|
+
div << XMLText.new('|')
|
|
42
|
+
end
|
|
43
|
+
if report == @project.reportContext.report
|
|
44
|
+
div << (span = XMLElement.new('span',
|
|
45
|
+
'style' => 'class:navbar_current'))
|
|
46
|
+
span << XMLText.new(report.name)
|
|
47
|
+
else
|
|
48
|
+
div << (span = XMLElement.new('span', 'style' => 'class:navbar_other'))
|
|
49
|
+
span << (a = XMLElement.new('a', 'href' => report.name + '.html'))
|
|
50
|
+
a << XMLText.new(report.name)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
html
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def filterReports
|
|
59
|
+
list = PropertyList.new(@project.reports)
|
|
60
|
+
list.setSorting([[ 'seqno', true, -1 ]])
|
|
61
|
+
list.sort!
|
|
62
|
+
# Remove all reports that the user doesn't want to have include.
|
|
63
|
+
list.delete_if do |property|
|
|
64
|
+
@hideReport.eval(property, nil)
|
|
65
|
+
end
|
|
66
|
+
list
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
data/lib/reports/Report.rb
CHANGED
|
@@ -10,71 +10,33 @@
|
|
|
10
10
|
# published by the Free Software Foundation.
|
|
11
11
|
#
|
|
12
12
|
|
|
13
|
-
require '
|
|
13
|
+
require 'PropertyTreeNode'
|
|
14
|
+
require 'reports/TextReport'
|
|
14
15
|
require 'reports/TaskListRE'
|
|
15
16
|
require 'reports/ResourceListRE'
|
|
16
17
|
require 'reports/TjpExportRE'
|
|
17
18
|
require 'reports/CSVFile'
|
|
19
|
+
require 'reports/Navigator'
|
|
20
|
+
require 'reports/ReportContext'
|
|
18
21
|
require 'HTMLDocument'
|
|
19
22
|
|
|
20
23
|
class TaskJuggler
|
|
21
24
|
|
|
22
|
-
# The Report class holds the fundamental description and functionality to
|
|
23
|
-
# the scheduled project into a user readable form. A report
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
class Report
|
|
25
|
+
# The Report class holds the fundamental description and functionality to
|
|
26
|
+
# turn the scheduled project into a user readable form. A report may contain
|
|
27
|
+
# other reports.
|
|
28
|
+
class Report < PropertyTreeNode
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
:sourceFileInfo
|
|
30
|
-
attr_accessor :costAccount, :currencyformat, :loadUnit, :now,
|
|
31
|
-
:numberformat, :resourceRoot, :revenueAccount,
|
|
32
|
-
:shorttimeformat, :taskRoot, :timeformat, :timezone,
|
|
33
|
-
:weekstartsmonday
|
|
30
|
+
attr_accessor :typeSpec, :content
|
|
34
31
|
|
|
35
32
|
# Create a new report object.
|
|
36
|
-
def initialize(project,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@project.addReport(self)
|
|
40
|
-
@outputFormats = [ format ]
|
|
41
|
-
@sourceFileInfo = sourceFileInfo
|
|
33
|
+
def initialize(project, id, name, parent)
|
|
34
|
+
super(project.reports, id, name, parent)
|
|
35
|
+
project.addReport(self)
|
|
42
36
|
|
|
43
|
-
# The
|
|
44
|
-
|
|
45
|
-
@
|
|
46
|
-
@loadUnit = @project['loadunit']
|
|
47
|
-
@end = @project['end']
|
|
48
|
-
@now = @project['now']
|
|
49
|
-
@numberformat = @project['numberformat']
|
|
50
|
-
@resourceRoot = nil
|
|
51
|
-
@revenueAccount = @project['revenueAccount']
|
|
52
|
-
@shorttimeformat = @project['shorttimeformat']
|
|
53
|
-
@start = @project['start']
|
|
54
|
-
@taskRoot = nil
|
|
55
|
-
@timeformat = @project['timeformat']
|
|
56
|
-
@timezone = @project['timezone']
|
|
57
|
-
@userDefinedPeriod = false
|
|
58
|
-
@weekstartsmonday = @project['weekstartsmonday']
|
|
59
|
-
|
|
60
|
-
@elements = []
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Set the start _date_ of the report period and mark it as user defined.
|
|
64
|
-
def start=(date)
|
|
65
|
-
@start = date
|
|
66
|
-
@userDefinedPeriod = true
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Set the end _date_ of the report period and mark it as user defined.
|
|
70
|
-
def end=(date)
|
|
71
|
-
@end = date
|
|
72
|
-
@userDefinedPeriod = true
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Add new ouput format request.
|
|
76
|
-
def addFormat(format)
|
|
77
|
-
@outputFormats << format
|
|
37
|
+
# The type specifier must be set for every report. It tells whether this
|
|
38
|
+
# is a task, resource, text or other report.
|
|
39
|
+
@typeSpec = nil
|
|
78
40
|
end
|
|
79
41
|
|
|
80
42
|
# The generate function is where the action happens in this class. The
|
|
@@ -82,14 +44,26 @@ class TaskJuggler
|
|
|
82
44
|
# generated according the the requested output format(s).
|
|
83
45
|
def generate
|
|
84
46
|
begin
|
|
47
|
+
@content = nil
|
|
48
|
+
case @typeSpec
|
|
49
|
+
when :export
|
|
50
|
+
# Does not have an intermediate representation. Nothing to do here.
|
|
51
|
+
when :resourcereport
|
|
52
|
+
@content = ResourceListRE.new(self)
|
|
53
|
+
when :textreport
|
|
54
|
+
@content = TextReport.new(self)
|
|
55
|
+
when :taskreport
|
|
56
|
+
@content = TaskListRE.new(self)
|
|
57
|
+
else
|
|
58
|
+
raise "Unknown report type"
|
|
59
|
+
end
|
|
60
|
+
|
|
85
61
|
# Most output format can be generated from a common intermediate
|
|
86
62
|
# representation of the elements. We generate that IR first.
|
|
87
|
-
@
|
|
88
|
-
element.generateIntermediateFormat
|
|
89
|
-
end
|
|
63
|
+
@content.generateIntermediateFormat if @content
|
|
90
64
|
|
|
91
65
|
# Then generate the actual output format.
|
|
92
|
-
|
|
66
|
+
get('formats').each do |format|
|
|
93
67
|
case format
|
|
94
68
|
when :html
|
|
95
69
|
generateHTML
|
|
@@ -97,8 +71,6 @@ class TaskJuggler
|
|
|
97
71
|
generateCSV
|
|
98
72
|
when :export
|
|
99
73
|
generateExport
|
|
100
|
-
when :gui
|
|
101
|
-
# TODO: Find a way to hook up the GUI here.
|
|
102
74
|
else
|
|
103
75
|
raise 'Unknown report output format.'
|
|
104
76
|
end
|
|
@@ -110,13 +82,17 @@ class TaskJuggler
|
|
|
110
82
|
end
|
|
111
83
|
end
|
|
112
84
|
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
@elements << element
|
|
85
|
+
# Render the content of the report as HTML (without the framing).
|
|
86
|
+
def to_html
|
|
87
|
+
@content ? @content.to_html : nil
|
|
117
88
|
end
|
|
118
89
|
|
|
90
|
+
|
|
119
91
|
private
|
|
92
|
+
# Convenience function to access a report attribute
|
|
93
|
+
def a(attribute)
|
|
94
|
+
get(attribute)
|
|
95
|
+
end
|
|
120
96
|
|
|
121
97
|
# Generate an HTML version of the report.
|
|
122
98
|
def generateHTML
|
|
@@ -180,6 +156,7 @@ class TaskJuggler
|
|
|
180
156
|
.tabline { color:#000000 }
|
|
181
157
|
.tabcell {
|
|
182
158
|
white-space:nowrap;
|
|
159
|
+
overflow:hidden;
|
|
183
160
|
padding:0px;
|
|
184
161
|
}
|
|
185
162
|
.taskcell1 {
|
|
@@ -246,7 +223,7 @@ class TaskJuggler
|
|
|
246
223
|
position:absolute;
|
|
247
224
|
}
|
|
248
225
|
.free {
|
|
249
|
-
background-color:#
|
|
226
|
+
background-color:#a5ffb5;
|
|
250
227
|
position:absolute;
|
|
251
228
|
}
|
|
252
229
|
.busy {
|
|
@@ -286,17 +263,22 @@ EOT
|
|
|
286
263
|
)
|
|
287
264
|
html << (body = XMLElement.new('body'))
|
|
288
265
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
266
|
+
# Make sure we have some margins around the report.
|
|
267
|
+
body << (frame = XMLElement.new('div',
|
|
268
|
+
'style' => 'margin: 35px 5% 25px 5%; '))
|
|
292
269
|
|
|
293
|
-
|
|
270
|
+
frame << @content.to_html if @content
|
|
271
|
+
|
|
272
|
+
html.write((@name[0] == '/' ? '' : @project.outputDir) +
|
|
273
|
+
@name + (@name == '.' ? '' : '.html'))
|
|
294
274
|
end
|
|
295
275
|
|
|
296
276
|
# Generate a CSV version of the report.
|
|
297
277
|
def generateCSV
|
|
278
|
+
return nil unless @content
|
|
279
|
+
|
|
298
280
|
# CSV format can only handle the first element.
|
|
299
|
-
csv = @
|
|
281
|
+
csv = @content.to_csv
|
|
300
282
|
# Expand nested tables into the outer table.
|
|
301
283
|
columnIdx = 0
|
|
302
284
|
while columnIdx < csv[0].length do
|
|
@@ -328,14 +310,17 @@ EOT
|
|
|
328
310
|
|
|
329
311
|
# Use the CSVFile class to write the Array of Arrays to a colon
|
|
330
312
|
# separated file. Write to $stdout if the filename was set to '.'.
|
|
331
|
-
CSVFile.new(csv, ';').write(@name)
|
|
313
|
+
CSVFile.new(csv, ';').write((@name[0] == '/' ? '' : @project.outputDir) +
|
|
314
|
+
@name + (@name == '.' ? '' : '.csv'))
|
|
332
315
|
end
|
|
333
316
|
|
|
334
317
|
# Generate an export report
|
|
335
318
|
def generateExport
|
|
336
|
-
|
|
337
|
-
f = @name == '.' ? $stdout :
|
|
338
|
-
|
|
319
|
+
@content = TjpExportRE.new(self)
|
|
320
|
+
f = @name == '.' ? $stdout :
|
|
321
|
+
File.new((@name[0] == '/' ? '' : @project.outputDir) +
|
|
322
|
+
@name, 'w')
|
|
323
|
+
f.puts "#{@content.to_tjp}"
|
|
339
324
|
end
|
|
340
325
|
|
|
341
326
|
end
|