taskjuggler 0.0.3 → 0.0.4
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/benchmarks/UTF-8-Strings.rb +58 -0
- data/data/css/tjmanual.css +52 -0
- data/data/css/tjreport.css +195 -0
- data/data/icons/details.png +0 -0
- data/data/icons/flag-green.png +0 -0
- data/data/icons/flag-red.png +0 -0
- data/data/icons/flag-yellow.png +0 -0
- data/data/icons/resource.png +0 -0
- data/data/icons/resourcegroup.png +0 -0
- data/data/icons/task.png +0 -0
- data/data/icons/taskgroup.png +0 -0
- data/data/icons/trend-down.png +0 -0
- data/data/icons/trend-flat.png +0 -0
- data/data/icons/trend-up.png +0 -0
- data/data/scripts/wz_tooltip.js +1301 -0
- data/doc/classes/AppConfig.html +298 -230
- data/doc/classes/Arguments.html +8 -8
- data/doc/classes/Object.html +7 -7
- data/doc/classes/String.html +89 -89
- data/doc/classes/TaskJuggler.html +396 -264
- data/doc/classes/TaskJuggler/Account.html +18 -18
- data/doc/classes/TaskJuggler/AccountAttribute.html +26 -26
- data/doc/classes/TaskJuggler/AccountScenario.html +12 -12
- data/doc/classes/TaskJuggler/Allocation.html +30 -30
- data/doc/classes/TaskJuggler/AllocationAttribute.html +26 -26
- data/doc/classes/TaskJuggler/AttributeBase.html +227 -115
- data/doc/classes/TaskJuggler/AttributeDefinition.html +6 -6
- data/doc/classes/TaskJuggler/BatchProcessor.html +117 -83
- data/doc/classes/TaskJuggler/Booking.html +18 -18
- data/doc/classes/TaskJuggler/BookingListAttribute.html +26 -26
- data/doc/classes/TaskJuggler/BooleanAttribute.html +26 -26
- data/doc/classes/TaskJuggler/CSVFile.html +24 -24
- data/doc/classes/TaskJuggler/CellSettingPattern.html +201 -0
- data/doc/classes/TaskJuggler/CellSettingPatternList.html +253 -0
- data/doc/classes/TaskJuggler/Charge.html +18 -18
- data/doc/classes/TaskJuggler/ChargeListAttribute.html +20 -20
- data/doc/classes/TaskJuggler/ChargeSet.html +37 -37
- data/doc/classes/TaskJuggler/ChargeSetListAttribute.html +26 -26
- data/doc/classes/TaskJuggler/ColumnListAttribute.html +20 -20
- data/doc/classes/TaskJuggler/ColumnTable.html +40 -40
- data/doc/classes/TaskJuggler/DateAttribute.html +54 -15
- data/doc/classes/TaskJuggler/DefinitionListAttribute.html +10 -10
- data/doc/classes/TaskJuggler/DependencyListAttribute.html +47 -47
- data/doc/classes/TaskJuggler/DurationAttribute.html +30 -30
- data/doc/classes/TaskJuggler/FixnumAttribute.html +20 -20
- data/doc/classes/TaskJuggler/FlagListAttribute.html +43 -43
- data/doc/classes/TaskJuggler/FloatAttribute.html +30 -30
- data/doc/classes/TaskJuggler/FormatListAttribute.html +21 -21
- data/doc/classes/TaskJuggler/GanttChart.html +48 -48
- data/doc/classes/TaskJuggler/GanttContainer.html +42 -42
- data/doc/classes/TaskJuggler/GanttHeader.html +12 -12
- data/doc/classes/TaskJuggler/GanttHeaderScaleItem.html +12 -12
- data/doc/classes/TaskJuggler/GanttLine.html +24 -24
- data/doc/classes/TaskJuggler/GanttLoadStack.html +18 -18
- data/doc/classes/TaskJuggler/GanttMilestone.html +42 -42
- data/doc/classes/TaskJuggler/GanttRouter.html +24 -24
- data/doc/classes/TaskJuggler/GanttTaskBar.html +42 -42
- data/doc/classes/TaskJuggler/HTMLDocument.html +13 -13
- data/doc/classes/TaskJuggler/HTMLGraphics.html +12 -12
- data/doc/classes/TaskJuggler/Interval.html +57 -57
- data/doc/classes/TaskJuggler/IntervalListAttribute.html +47 -47
- data/doc/classes/TaskJuggler/JobInfo.html +68 -12
- data/doc/classes/TaskJuggler/Journal.html +266 -20
- data/doc/classes/TaskJuggler/JournalEntry.html +79 -23
- data/doc/classes/TaskJuggler/JournalEntryList.html +454 -0
- data/doc/classes/TaskJuggler/KeywordArray.html +10 -10
- data/doc/classes/TaskJuggler/KeywordDocumentation.html +171 -170
- data/doc/classes/TaskJuggler/Limits.html +36 -36
- data/doc/classes/TaskJuggler/Limits/Limit.html +30 -30
- data/doc/classes/TaskJuggler/LimitsAttribute.html +40 -40
- data/doc/classes/TaskJuggler/ListAttributeBase.html +20 -20
- data/doc/classes/TaskJuggler/Log.html +145 -107
- data/doc/classes/TaskJuggler/LogicalAttribute.html +65 -36
- data/doc/classes/TaskJuggler/LogicalExpression.html +61 -24
- data/doc/classes/TaskJuggler/LogicalExpressionAttribute.html +20 -20
- data/doc/classes/TaskJuggler/LogicalFlag.html +31 -51
- data/doc/classes/TaskJuggler/LogicalFunction.html +64 -53
- data/doc/classes/TaskJuggler/LogicalOperation.html +103 -55
- data/doc/classes/TaskJuggler/Macro.html +6 -6
- data/doc/classes/TaskJuggler/MacroParser.html +36 -36
- data/doc/classes/TaskJuggler/MacroTable.html +37 -37
- data/doc/classes/TaskJuggler/Message.html +12 -12
- data/doc/classes/TaskJuggler/MessageHandler.html +32 -20
- data/doc/classes/TaskJuggler/Navigator.html +110 -46
- data/doc/classes/TaskJuggler/NavigatorElement.html +449 -0
- data/doc/classes/TaskJuggler/OnShiftCache.html +24 -24
- data/doc/classes/TaskJuggler/Project.html +1158 -893
- data/doc/classes/TaskJuggler/ProjectFileParser.html +94 -91
- data/doc/classes/TaskJuggler/PropertyAttribute.html +20 -20
- data/doc/classes/TaskJuggler/PropertyList.html +225 -155
- data/doc/classes/TaskJuggler/PropertySet.html +375 -332
- data/doc/classes/TaskJuggler/PropertyTreeNode.html +750 -510
- data/doc/classes/TaskJuggler/Query.html +404 -139
- data/doc/classes/TaskJuggler/{RTPNavigator.html → RTFNavigator.html} +57 -56
- data/doc/classes/TaskJuggler/RTFQuery.html +343 -0
- data/doc/classes/TaskJuggler/{RTPReport.html → RTFReport.html} +70 -67
- data/doc/classes/TaskJuggler/RealFormat.html +18 -18
- data/doc/classes/TaskJuggler/RealFormatAttribute.html +10 -10
- data/doc/classes/TaskJuggler/ReferenceAttribute.html +107 -40
- data/doc/classes/TaskJuggler/RemoteServiceManager.html +335 -0
- data/doc/classes/TaskJuggler/Report.html +66 -64
- data/doc/classes/TaskJuggler/ReportBase.html +112 -123
- data/doc/classes/TaskJuggler/ReportContext.html +43 -38
- data/doc/classes/TaskJuggler/ReportServer.html +320 -0
- data/doc/classes/TaskJuggler/ReportTable.html +42 -42
- data/doc/classes/TaskJuggler/ReportTableCell.html +221 -129
- data/doc/classes/TaskJuggler/ReportTableColumn.html +27 -27
- data/doc/classes/TaskJuggler/ReportTableLegend.html +24 -24
- data/doc/classes/TaskJuggler/ReportTableLine.html +126 -80
- data/doc/classes/TaskJuggler/Resource.html +12 -12
- data/doc/classes/TaskJuggler/ResourceListAttribute.html +82 -47
- data/doc/classes/TaskJuggler/ResourceListRE.html +43 -39
- data/doc/classes/TaskJuggler/ResourceScenario.html +413 -321
- data/doc/classes/TaskJuggler/RichText.html +64 -248
- data/doc/classes/TaskJuggler/RichTextAttribute.html +94 -30
- data/doc/classes/TaskJuggler/RichTextDocument.html +87 -85
- data/doc/classes/TaskJuggler/RichTextElement.html +456 -363
- data/doc/classes/TaskJuggler/RichTextException.html +13 -13
- data/doc/classes/TaskJuggler/{RichTextProtocolExample.html → RichTextFunctionExample.html} +64 -63
- data/doc/classes/TaskJuggler/{RichTextProtocolHandler.html → RichTextFunctionHandler.html} +42 -36
- data/doc/classes/TaskJuggler/RichTextIntermediate.html +563 -0
- data/doc/classes/TaskJuggler/RichTextParser.html +54 -51
- data/doc/classes/TaskJuggler/RichTextScanner.html +94 -92
- data/doc/classes/TaskJuggler/RichTextSnip.html +96 -60
- data/doc/classes/TaskJuggler/RichTextSyntaxRules.html +369 -227
- data/doc/classes/TaskJuggler/Scenario.html +6 -6
- data/doc/classes/TaskJuggler/ScenarioData.html +37 -37
- data/doc/classes/TaskJuggler/ScenarioListAttribute.html +31 -31
- data/doc/classes/TaskJuggler/Scoreboard.html +66 -66
- data/doc/classes/TaskJuggler/Shift.html +18 -18
- data/doc/classes/TaskJuggler/ShiftAssignment.html +54 -54
- data/doc/classes/TaskJuggler/ShiftAssignments.html +78 -78
- data/doc/classes/TaskJuggler/ShiftAssignmentsAttribute.html +40 -40
- data/doc/classes/TaskJuggler/ShiftScenario.html +24 -24
- data/doc/classes/TaskJuggler/SortListAttribute.html +22 -22
- data/doc/classes/TaskJuggler/SourceFileInfo.html +12 -12
- data/doc/classes/TaskJuggler/StringAttribute.html +30 -30
- data/doc/classes/TaskJuggler/SymbolAttribute.html +20 -20
- data/doc/classes/TaskJuggler/SyntaxReference.html +42 -42
- data/doc/classes/TaskJuggler/TOCEntry.html +12 -12
- data/doc/classes/TaskJuggler/TSResourceRecord.html +197 -0
- data/doc/classes/TaskJuggler/TSTaskRecord.html +215 -0
- data/doc/classes/TaskJuggler/TableColumnDefinition.html +64 -43
- data/doc/classes/TaskJuggler/TableOfContents.html +18 -18
- data/doc/classes/TaskJuggler/TableReport.html +447 -468
- data/doc/classes/TaskJuggler/Task.html +12 -12
- data/doc/classes/TaskJuggler/TaskDependency.html +12 -12
- data/doc/classes/TaskJuggler/TaskListAttribute.html +47 -47
- data/doc/classes/TaskJuggler/TaskListRE.html +43 -39
- data/doc/classes/TaskJuggler/TaskScenario.html +529 -282
- data/doc/classes/TaskJuggler/TextParser.html +215 -194
- data/doc/classes/TaskJuggler/TextParser/Pattern.html +97 -97
- data/doc/classes/TaskJuggler/TextParser/Rule.html +84 -84
- data/doc/classes/TaskJuggler/TextParser/StackElement.html +16 -15
- data/doc/classes/TaskJuggler/TextParser/TextParserResultArray.html +12 -12
- data/doc/classes/TaskJuggler/TextParser/TokenDoc.html +6 -6
- data/doc/classes/TaskJuggler/TextReport.html +77 -74
- data/doc/classes/TaskJuggler/TextScanner.html +294 -281
- data/doc/classes/TaskJuggler/TextScanner/BufferStreamHandle.html +70 -70
- data/doc/classes/TaskJuggler/TextScanner/FileStreamHandle.html +59 -60
- data/doc/classes/TaskJuggler/TextScanner/StreamHandle.html +12 -12
- data/doc/classes/TaskJuggler/TimeSheetReport.html +406 -0
- data/doc/classes/TaskJuggler/TjException.html +6 -6
- data/doc/classes/TaskJuggler/TjTime.html +522 -513
- data/doc/classes/TaskJuggler/TjpExample.html +25 -25
- data/doc/classes/TaskJuggler/TjpExportRE.html +21 -24
- data/doc/classes/TaskJuggler/TjpSyntaxRules.html +6177 -4318
- data/doc/classes/TaskJuggler/UserManual.html +212 -213
- data/doc/classes/TaskJuggler/WorkingHours.html +49 -49
- data/doc/classes/TaskJuggler/WorkingHoursAttribute.html +53 -53
- data/doc/classes/TaskJuggler/XMLBlob.html +21 -21
- data/doc/classes/TaskJuggler/XMLComment.html +21 -21
- data/doc/classes/TaskJuggler/XMLDocument.html +27 -26
- data/doc/classes/TaskJuggler/XMLElement.html +86 -50
- data/doc/classes/TaskJuggler/XMLNamedText.html +11 -11
- data/doc/classes/TaskJuggler/XMLText.html +36 -36
- data/doc/files/COPYING.html +1 -1
- data/doc/files/README.html +1 -1
- data/doc/files/lib/AccountScenario_rb.html +3 -2
- data/doc/files/lib/Account_rb.html +3 -2
- data/doc/files/lib/Allocation_rb.html +3 -2
- data/doc/files/lib/AppConfig_rb.html +5 -2
- data/doc/files/lib/AttributeBase_rb.html +3 -2
- data/doc/files/lib/AttributeDefinition_rb.html +3 -2
- data/doc/files/lib/Attributes_rb.html +3 -2
- data/doc/files/lib/BatchProcessor_rb.html +4 -3
- data/doc/files/lib/Booking_rb.html +3 -2
- data/doc/files/lib/ChargeSet_rb.html +3 -2
- data/doc/files/lib/Charge_rb.html +3 -2
- data/doc/files/lib/HTMLDocument_rb.html +3 -2
- data/doc/files/lib/Interval_rb.html +3 -2
- data/doc/files/lib/Journal_rb.html +4 -3
- data/doc/files/lib/KeywordArray_rb.html +3 -2
- data/doc/files/lib/KeywordDocumentation_rb.html +3 -2
- data/doc/files/lib/Limits_rb.html +3 -2
- data/doc/files/lib/Log_rb.html +3 -2
- data/doc/files/lib/LogicalExpression_rb.html +3 -2
- data/doc/files/lib/LogicalFunction_rb.html +3 -2
- data/doc/files/lib/LogicalOperation_rb.html +3 -2
- data/doc/files/lib/MacroParser_rb.html +3 -2
- data/doc/files/lib/MacroTable_rb.html +3 -2
- data/doc/files/lib/MessageHandler_rb.html +3 -2
- data/doc/files/lib/Message_rb.html +3 -2
- data/doc/files/lib/ProjectFileParser_rb.html +7 -4
- data/doc/files/lib/Project_rb.html +3 -2
- data/doc/files/lib/PropertyList_rb.html +3 -2
- data/doc/files/lib/PropertySet_rb.html +3 -2
- data/doc/files/lib/PropertyTreeNode_rb.html +3 -2
- data/doc/files/lib/Query_rb.html +3 -2
- data/doc/files/lib/{RTPNavigator_rb.html → RTFNavigator_rb.html} +8 -7
- data/doc/files/lib/RTFQuery_rb.html +121 -0
- data/doc/files/lib/{RTPReport_rb.html → RTFReport_rb.html} +8 -7
- data/doc/files/lib/RealFormat_rb.html +3 -2
- data/doc/files/lib/RemoteServiceManager_rb.html +117 -0
- data/doc/files/lib/ReportServer_rb.html +107 -0
- data/doc/files/lib/ResourceScenario_rb.html +3 -2
- data/doc/files/lib/Resource_rb.html +3 -2
- data/doc/files/lib/RichTextDocument_rb.html +4 -3
- data/doc/files/lib/RichTextElement_rb.html +3 -2
- data/doc/files/lib/{RichTextProtocolExample_rb.html → RichTextFunctionExample_rb.html} +8 -7
- data/doc/files/lib/{RichTextProtocolHandler_rb.html → RichTextFunctionHandler_rb.html} +7 -6
- data/doc/files/lib/RichTextParser_rb.html +3 -2
- data/doc/files/lib/RichTextScanner_rb.html +3 -2
- data/doc/files/lib/RichTextSnip_rb.html +3 -2
- data/doc/files/lib/RichTextSyntaxRules_rb.html +3 -2
- data/doc/files/lib/RichText_rb.html +3 -2
- data/doc/files/lib/ScenarioData_rb.html +3 -2
- data/doc/files/lib/Scenario_rb.html +3 -2
- data/doc/files/lib/Scoreboard_rb.html +3 -2
- data/doc/files/lib/ShiftAssignments_rb.html +3 -2
- data/doc/files/lib/ShiftScenario_rb.html +3 -2
- data/doc/files/lib/Shift_rb.html +3 -2
- data/doc/files/lib/SourceFileInfo_rb.html +3 -2
- data/doc/files/lib/SyntaxReference_rb.html +3 -2
- data/doc/files/lib/TOCEntry_rb.html +3 -2
- data/doc/files/lib/TableColumnDefinition_rb.html +3 -2
- data/doc/files/lib/TableOfContents_rb.html +3 -2
- data/doc/files/lib/TaskDependency_rb.html +3 -2
- data/doc/files/lib/TaskJuggler_rb.html +7 -2
- data/doc/files/lib/TaskScenario_rb.html +3 -2
- data/doc/files/lib/Task_rb.html +3 -2
- data/doc/files/lib/TextParser/Pattern_rb.html +4 -3
- data/doc/files/lib/TextParser/Rule_rb.html +4 -3
- data/doc/files/lib/TextParser/StackElement_rb.html +4 -3
- data/doc/files/lib/TextParser/TokenDoc_rb.html +4 -3
- data/doc/files/lib/TextParser_rb.html +3 -2
- data/doc/files/lib/TextScanner_rb.html +3 -2
- data/doc/files/lib/Tj3Config_rb.html +3 -2
- data/doc/files/lib/TjException_rb.html +3 -2
- data/doc/files/lib/TjTime_rb.html +3 -2
- data/doc/files/lib/TjpExample_rb.html +3 -2
- data/doc/files/lib/TjpSyntaxRules_rb.html +3 -2
- data/doc/files/lib/UTF8String_rb.html +14 -6
- data/doc/files/lib/UserManual_rb.html +6 -3
- data/doc/files/lib/WorkingHours_rb.html +3 -2
- data/doc/files/lib/XMLDocument_rb.html +3 -2
- data/doc/files/lib/XMLElement_rb.html +3 -2
- data/doc/files/lib/deep_copy_rb.html +3 -2
- data/doc/files/lib/reports/CSVFile_rb.html +3 -2
- data/doc/files/lib/reports/ColumnTable_rb.html +3 -2
- data/doc/files/lib/reports/GanttChart_rb.html +3 -2
- data/doc/files/lib/reports/GanttContainer_rb.html +3 -2
- data/doc/files/lib/reports/GanttHeaderScaleItem_rb.html +3 -2
- data/doc/files/lib/reports/GanttHeader_rb.html +3 -2
- data/doc/files/lib/reports/GanttLine_rb.html +3 -2
- data/doc/files/lib/reports/GanttLoadStack_rb.html +3 -2
- data/doc/files/lib/reports/GanttMilestone_rb.html +3 -2
- data/doc/files/lib/reports/GanttRouter_rb.html +3 -2
- data/doc/files/lib/reports/GanttTaskBar_rb.html +3 -2
- data/doc/files/lib/reports/HTMLGraphics_rb.html +3 -2
- data/doc/files/lib/reports/Navigator_rb.html +3 -2
- data/doc/files/lib/reports/ReportBase_rb.html +3 -2
- data/doc/files/lib/reports/ReportContext_rb.html +3 -2
- data/doc/files/lib/reports/ReportTableCell_rb.html +3 -2
- data/doc/files/lib/reports/ReportTableColumn_rb.html +3 -2
- data/doc/files/lib/reports/ReportTableLegend_rb.html +3 -2
- data/doc/files/lib/reports/ReportTableLine_rb.html +3 -2
- data/doc/files/lib/reports/ReportTable_rb.html +3 -2
- data/doc/files/lib/reports/Report_rb.html +7 -2
- data/doc/files/lib/reports/ResourceListRE_rb.html +3 -2
- data/doc/files/lib/reports/TableReport_rb.html +3 -2
- data/doc/files/lib/reports/TaskListRE_rb.html +3 -2
- data/doc/files/lib/reports/TextReport_rb.html +4 -3
- data/doc/files/lib/reports/TimeSheetReport_rb.html +117 -0
- data/doc/files/lib/reports/TjpExportRE_rb.html +3 -2
- data/doc/files/lib/taskjuggler3_rb.html +94 -77
- data/doc/files/lib/tj3client_rb.html +280 -0
- data/doc/files/lib/tj3man_rb.html +10 -9
- data/doc/fr_class_index.html +27 -5
- data/doc/fr_file_index.html +15 -7
- data/doc/fr_method_index.html +1312 -1020
- data/examples/tutorial.tjp +113 -14
- data/gem_spec.rb +2 -1
- data/lib/Account.rb +1 -1
- data/lib/AccountScenario.rb +1 -1
- data/lib/Allocation.rb +1 -1
- data/lib/AppConfig.rb +23 -10
- data/lib/AttributeBase.rb +34 -6
- data/lib/AttributeDefinition.rb +1 -1
- data/lib/Attributes.rb +51 -16
- data/lib/BatchProcessor.rb +204 -77
- data/lib/Booking.rb +1 -1
- data/lib/Charge.rb +1 -1
- data/lib/ChargeSet.rb +1 -1
- data/lib/HTMLDocument.rb +2 -2
- data/lib/Interval.rb +1 -1
- data/lib/Journal.rb +231 -9
- data/lib/KeywordArray.rb +1 -1
- data/lib/KeywordDocumentation.rb +6 -4
- data/lib/Limits.rb +1 -1
- data/lib/Log.rb +8 -1
- data/lib/LogicalExpression.rb +14 -13
- data/lib/LogicalFunction.rb +88 -14
- data/lib/LogicalOperation.rb +124 -53
- data/lib/MacroParser.rb +1 -1
- data/lib/MacroTable.rb +2 -2
- data/lib/Message.rb +1 -1
- data/lib/MessageHandler.rb +7 -3
- data/lib/Project.rb +93 -14
- data/lib/ProjectFileParser.rb +30 -15
- data/lib/PropertyList.rb +103 -36
- data/lib/PropertySet.rb +22 -10
- data/lib/PropertyTreeNode.rb +120 -15
- data/lib/Query.rb +119 -48
- data/lib/{RTPNavigator.rb → RTFNavigator.rb} +11 -10
- data/lib/RTFQuery.rb +166 -0
- data/lib/{RTPReport.rb → RTFReport.rb} +11 -8
- data/lib/RealFormat.rb +1 -1
- data/lib/RemoteServiceManager.rb +80 -0
- data/lib/ReportServer.rb +66 -0
- data/lib/Resource.rb +1 -1
- data/lib/ResourceScenario.rb +48 -19
- data/lib/RichText.rb +98 -41
- data/lib/RichTextDocument.rb +10 -8
- data/lib/RichTextElement.rb +72 -28
- data/lib/{RichTextProtocolExample.rb → RichTextFunctionExample.rb} +8 -7
- data/lib/{RichTextProtocolHandler.rb → RichTextFunctionHandler.rb} +12 -14
- data/lib/RichTextParser.rb +6 -3
- data/lib/RichTextScanner.rb +91 -19
- data/lib/RichTextSnip.rb +8 -3
- data/lib/RichTextSyntaxRules.rb +103 -45
- data/lib/Scenario.rb +1 -1
- data/lib/ScenarioData.rb +2 -2
- data/lib/Scoreboard.rb +1 -1
- data/lib/Shift.rb +1 -1
- data/lib/ShiftAssignments.rb +1 -1
- data/lib/ShiftScenario.rb +1 -1
- data/lib/SourceFileInfo.rb +1 -1
- data/lib/SyntaxReference.rb +2 -2
- data/lib/TOCEntry.rb +1 -1
- data/lib/TableColumnDefinition.rb +59 -16
- data/lib/TableOfContents.rb +1 -1
- data/lib/Task.rb +1 -1
- data/lib/TaskDependency.rb +1 -1
- data/lib/TaskJuggler.rb +31 -8
- data/lib/TaskScenario.rb +165 -16
- data/lib/TextParser.rb +36 -22
- data/lib/TextParser/Pattern.rb +3 -3
- data/lib/TextParser/Rule.rb +2 -2
- data/lib/TextParser/StackElement.rb +4 -3
- data/lib/TextParser/TokenDoc.rb +2 -2
- data/lib/TextScanner.rb +52 -37
- data/lib/Tj3Config.rb +6 -5
- data/lib/TjException.rb +1 -1
- data/lib/TjTime.rb +12 -3
- data/lib/TjpExample.rb +1 -1
- data/lib/TjpSyntaxRules.rb +1044 -150
- data/lib/UTF8String.rb +2 -1
- data/lib/UserManual.rb +18 -70
- data/lib/WorkingHours.rb +3 -3
- data/lib/XMLDocument.rb +3 -2
- data/lib/XMLElement.rb +6 -1
- data/lib/deep_copy.rb +1 -1
- data/lib/reports/CSVFile.rb +1 -1
- data/lib/reports/ColumnTable.rb +9 -9
- data/lib/reports/GanttChart.rb +1 -1
- data/lib/reports/GanttContainer.rb +1 -1
- data/lib/reports/GanttHeader.rb +1 -1
- data/lib/reports/GanttHeaderScaleItem.rb +1 -1
- data/lib/reports/GanttLine.rb +40 -40
- data/lib/reports/GanttLoadStack.rb +1 -1
- data/lib/reports/GanttMilestone.rb +1 -1
- data/lib/reports/GanttRouter.rb +1 -1
- data/lib/reports/GanttTaskBar.rb +1 -1
- data/lib/reports/HTMLGraphics.rb +1 -1
- data/lib/reports/Navigator.rb +149 -22
- data/lib/reports/Report.rb +115 -172
- data/lib/reports/ReportBase.rb +22 -27
- data/lib/reports/ReportContext.rb +29 -15
- data/lib/reports/ReportTable.rb +1 -1
- data/lib/reports/ReportTableCell.rb +120 -27
- data/lib/reports/ReportTableColumn.rb +3 -3
- data/lib/reports/ReportTableLegend.rb +1 -1
- data/lib/reports/ReportTableLine.rb +10 -2
- data/lib/reports/ResourceListRE.rb +5 -1
- data/lib/reports/TableReport.rb +237 -287
- data/lib/reports/TaskListRE.rb +5 -1
- data/lib/reports/TextReport.rb +7 -4
- data/lib/reports/TimeSheetReport.rb +233 -0
- data/lib/reports/TjpExportRE.rb +2 -2
- data/lib/taskjuggler3.rb +27 -11
- data/lib/tj3client.rb +110 -0
- data/lib/tj3man.rb +4 -4
- data/manual/Getting_Started +0 -50
- data/manual/How_To_Contribute +6 -13
- data/manual/Installation +102 -28
- data/manual/Intro +11 -1
- data/manual/Reporting_Bugs +23 -7
- data/manual/Rich_Text_Attributes +59 -6
- data/manual/TaskJuggler_2x_Migration +27 -0
- data/manual/The_TaskJuggler_Syntax +104 -0
- data/manual/Tutorial +10 -9
- data/prj_cfg.rb +8 -2
- data/tasks/csts.rake +1 -1
- data/tasks/manual.rake +5 -3
- data/test/MessageChecker.rb +1 -1
- data/test/TestSuite/HTML-Reports/Alerts.html +172 -0
- data/test/TestSuite/HTML-Reports/Alerts.tjp +77 -0
- data/test/TestSuite/HTML-Reports/CellText.html +758 -0
- data/test/TestSuite/HTML-Reports/CellText.tjp +75 -0
- data/test/TestSuite/HTML-Reports/ColumnPeriods.html +156 -0
- data/test/TestSuite/HTML-Reports/ColumnPeriods.tjp +44 -0
- data/test/TestSuite/HTML-Reports/IsOngoing.html +172 -0
- data/test/TestSuite/HTML-Reports/IsOngoing.tjp +34 -0
- data/test/TestSuite/HTML-Reports/LogicalFunctions.html +80 -0
- data/test/TestSuite/HTML-Reports/LogicalFunctions.tjp +20 -0
- data/test/TestSuite/HTML-Reports/Query.html +31 -0
- data/test/TestSuite/HTML-Reports/Query.tjp +28 -0
- data/test/TestSuite/HTML-Reports/Sorting.tjp +68 -0
- data/test/TestSuite/HTML-Reports/TimeSheet.tjp +69 -0
- data/test/TestSuite/HTML-Reports/UDAQuery.tjp +27 -0
- data/test/TestSuite/HTML-Reports/css/tjmanual.css +52 -0
- data/test/TestSuite/HTML-Reports/css/tjreport.css +195 -0
- data/test/TestSuite/HTML-Reports/depArrows.html +842 -0
- data/test/TestSuite/HTML-Reports/icons/details.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/flag-green.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/flag-red.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/flag-yellow.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/resource.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/resourcegroup.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/task.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/taskgroup.png +0 -0
- data/test/TestSuite/HTML-Reports/reference.tjp +7 -8
- data/test/TestSuite/HTML-Reports/scripts/scripts/wz_tooltip.js +1301 -0
- data/test/TestSuite/HTML-Reports/scripts/wz_tooltip.js +1301 -0
- data/test/TestSuite/Scheduler/Correct/Mandatory.tjp +34 -0
- data/test/TestSuite/Syntax/Correct/Celltext.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/Journal.tjp +2 -2
- data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +2 -1
- data/test/TestSuite/Syntax/Correct/LogicalFunction.tjp +20 -0
- data/test/TestSuite/Syntax/Correct/Query.tjp +18 -0
- data/test/TestSuite/Syntax/Correct/StatusSheet.tjp +45 -0
- data/test/TestSuite/Syntax/Correct/TimeSheet.tjp +49 -0
- data/test/TestSuite/Syntax/Correct/icons/details.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/resource.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/task.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/Syntax/Correct/scripts/wz_tooltip.js +1301 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +113 -14
- data/test/TestSuite/Syntax/Errors/macro_stack_overflow.tjp +28 -0
- data/test/TestSuite/Syntax/Errors/unsupported_token.tjp +12 -0
- data/test/all.rb +2 -2
- data/test/test_BatchProcessor.rb +42 -13
- data/test/test_CSV-Reports.rb +1 -1
- data/test/test_Journal.rb +176 -0
- data/test/test_Limits.rb +1 -1
- data/test/test_LogicalExpression.rb +14 -5
- data/test/test_MacroTable.rb +1 -1
- data/test/test_Project.rb +1 -1
- data/test/test_PropertySet.rb +1 -1
- data/test/test_Query.rb +1 -1
- data/test/test_RealFormat.rb +1 -1
- data/test/test_RichText.rb +30 -20
- data/test/test_Scheduler.rb +1 -1
- data/test/test_ShiftAssignments.rb +2 -2
- data/test/test_Syntax.rb +1 -1
- data/test/test_TextScanner.rb +1 -1
- data/test/test_TjTime.rb +1 -1
- data/test/test_TjpExample.rb +1 -1
- data/test/test_UTF8String.rb +1 -1
- data/test/test_WorkingHours.rb +1 -1
- data/test/test_deep_copy.rb +2 -2
- metadata +610 -532
- data/doc/files/lib/ms_test_rb.html +0 -90
- data/examples/ContactList.html +0 -1467
- data/examples/Deliveries.html +0 -485
- data/examples/Development.html +0 -2525
- data/examples/Overview.html +0 -747
- data/examples/Resource Graph.html +0 -616
- data/lib/ms_test.rb +0 -27
- data/test/TestSuite/HTML-Reports/reference-export.html +0 -187
data/lib/BatchProcessor.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env ruby -w
|
|
2
2
|
# encoding: UTF-8
|
|
3
3
|
#
|
|
4
|
-
# =
|
|
4
|
+
# = BatchProcessor.rb -- The TaskJuggler III Project Management Software
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
7
|
#
|
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
|
@@ -21,8 +21,8 @@ class TaskJuggler
|
|
|
21
21
|
class JobInfo
|
|
22
22
|
|
|
23
23
|
attr_reader :jobId, :block, :tag
|
|
24
|
-
attr_accessor :pid, :retVal, :stdoutP, :stdoutC, :stdout,
|
|
25
|
-
:stderrP, :stderrC, :stderr
|
|
24
|
+
attr_accessor :pid, :retVal, :stdoutP, :stdoutC, :stdout, :stdoutEOT,
|
|
25
|
+
:stderrP, :stderrC, :stderr, :stderrEOT
|
|
26
26
|
|
|
27
27
|
def initialize(jobId, block, tag)
|
|
28
28
|
# The job id. A unique number that is used by the BatchProcessor objects
|
|
@@ -34,13 +34,22 @@ class TaskJuggler
|
|
|
34
34
|
# to uniquely identify the job.
|
|
35
35
|
@tag = tag
|
|
36
36
|
# The pipe to transfer stdout data from the child to the parent.
|
|
37
|
-
@stdoutP, @stdoutC =
|
|
37
|
+
@stdoutP, @stdoutC = nil
|
|
38
38
|
# The stdout output of the child
|
|
39
39
|
@stdout = ''
|
|
40
|
+
# This flag is set to true when the EOT character has been received.
|
|
41
|
+
@stdoutEOF = false
|
|
40
42
|
# The pipe to transfer stderr data from the child to the parent.
|
|
41
|
-
@stderrP, @stderrC =
|
|
43
|
+
@stderrP, @stderrC = nil
|
|
42
44
|
# The stderr output of the child
|
|
43
45
|
@stderr = ''
|
|
46
|
+
# This flag is set to true when the EOT character has been received.
|
|
47
|
+
@stderrEOT = false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def openPipes
|
|
51
|
+
@stdoutP, @stdoutC = IO.pipe
|
|
52
|
+
@stderrP, @stderrC = IO.pipe
|
|
44
53
|
end
|
|
45
54
|
|
|
46
55
|
end
|
|
@@ -50,7 +59,7 @@ class TaskJuggler
|
|
|
50
59
|
# executed in parallel. The number of CPU cores to use is limited at object
|
|
51
60
|
# creation time. The submitted jobs will be queued and scheduled to the
|
|
52
61
|
# given number of CPUs. The usage model is simple. Create an BatchProcessor
|
|
53
|
-
# object.
|
|
62
|
+
# object. Use BatchProcessor#queue to submit all the jobs and then use
|
|
54
63
|
# BatchProcessor#wait to wait for completion and to process the results.
|
|
55
64
|
class BatchProcessor
|
|
56
65
|
|
|
@@ -58,59 +67,89 @@ class TaskJuggler
|
|
|
58
67
|
# simultaneously spawned processes.
|
|
59
68
|
def initialize(maxCpuCores)
|
|
60
69
|
@maxCpuCores = maxCpuCores
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
#
|
|
70
|
+
# Jobs submitted by calling queue() are put in the @toRunQueue. The
|
|
71
|
+
# pusher Thread will pick them up and fork them off into another
|
|
72
|
+
# process.
|
|
73
|
+
@toRunQueue = Queue.new
|
|
74
|
+
# A hash that maps the JobInfo objects of running jobs by their PID.
|
|
75
|
+
@runningJobs = { }
|
|
76
|
+
# A list of jobs that wait to complete their writing.
|
|
77
|
+
@spoolingJobs = [ ]
|
|
78
|
+
# The wait() method will then clean the @toDropQueue, executes the post
|
|
79
|
+
# processing block and removes all JobInfo related objects.
|
|
80
|
+
@toDropQueue = Queue.new
|
|
81
|
+
|
|
82
|
+
# A semaphore to guard accesses to @runningJobs, @spoolingJobs and
|
|
83
|
+
# following shared data structures.
|
|
64
84
|
@lock = Monitor.new
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
@pendingJobs = 0
|
|
85
|
+
# We count the submitted and completed jobs. The @jobsIn counter also
|
|
86
|
+
# doubles as a unique job ID.
|
|
87
|
+
@jobsIn = @jobsOut = 0
|
|
69
88
|
# An Array that holds all the IO objects to receive data from.
|
|
70
89
|
@pipes = []
|
|
71
90
|
# A hash that maps IO objects to JobInfo objects
|
|
72
91
|
@pipeToJob = {}
|
|
92
|
+
|
|
73
93
|
# This global flag is set to true to signal the threads to terminate.
|
|
74
94
|
@terminate = false
|
|
75
|
-
# Sleep time of the threads when no data is pending.
|
|
76
|
-
|
|
95
|
+
# Sleep time of the threads when no data is pending. This value must be
|
|
96
|
+
# large enough to allow for a context switch between the sending
|
|
97
|
+
# (forked-off) process and this process. If it's too large, throughput
|
|
98
|
+
# will suffer.
|
|
99
|
+
@timeout = 0.02
|
|
77
100
|
|
|
78
101
|
Thread.abort_on_exception = true
|
|
79
|
-
# The JobInfo objects in the @queue are processed by the pusher thread.
|
|
80
|
-
# It forkes off processes to execute the code block associated with the
|
|
81
|
-
# JobInfo.
|
|
82
|
-
@pusher = Thread.new { pusher }
|
|
83
|
-
# The popper thread waits for terminated childs and picks up the
|
|
84
|
-
# results.
|
|
85
|
-
@popper = Thread.new { popper }
|
|
86
|
-
# The grabber thread collects $stdout and $stderr data from each child
|
|
87
|
-
# process and stores them in the corresponding JobInfo.
|
|
88
|
-
@grabber = Thread.new { grabber }
|
|
89
102
|
end
|
|
90
103
|
|
|
91
104
|
# Add a new job the job queue. +tag+ is some data that the caller can use
|
|
92
105
|
# to identify the job upon completion. +block+ is a Ruby code block to be
|
|
93
106
|
# executed in a separate process.
|
|
94
107
|
def queue(tag = nil, &block)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
@
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
raise 'You cannot call queue() while wait() is running!' if @jobsOut > 0
|
|
109
|
+
|
|
110
|
+
# If this is the first queued job for this run, we have to start the
|
|
111
|
+
# helper threads.
|
|
112
|
+
if @jobsIn == 0
|
|
113
|
+
# The JobInfo objects in the @toRunQueue are processed by the pusher
|
|
114
|
+
# thread. It forkes off processes to execute the code block associated
|
|
115
|
+
# with the JobInfo.
|
|
116
|
+
@pusher = Thread.new { pusher }
|
|
117
|
+
# The popper thread waits for terminated childs and picks up the
|
|
118
|
+
# results.
|
|
119
|
+
@popper = Thread.new { popper }
|
|
120
|
+
# The grabber thread collects $stdout and $stderr data from each child
|
|
121
|
+
# process and stores them in the corresponding JobInfo.
|
|
122
|
+
@grabber = Thread.new { grabber }
|
|
106
123
|
end
|
|
124
|
+
|
|
125
|
+
# Create a new JobInfo object for the job and push it to the @toRunQueue.
|
|
126
|
+
job = JobInfo.new(@jobsIn, block, tag)
|
|
127
|
+
# Increase job counter
|
|
128
|
+
@lock.synchronize { @jobsIn += 1 }
|
|
129
|
+
@toRunQueue.push(job)
|
|
107
130
|
end
|
|
108
131
|
|
|
109
132
|
# Wait for all jobs to complete. The code block will get the JobInfo
|
|
110
133
|
# objects for each job to pick up the results.
|
|
111
134
|
def wait
|
|
112
|
-
|
|
113
|
-
|
|
135
|
+
# When we have received as many jobs in the @toDropQueue than we have
|
|
136
|
+
# started then we're done.
|
|
137
|
+
while !@lock.synchronize { @jobsIn == @jobsOut }
|
|
138
|
+
if @toDropQueue.empty?
|
|
139
|
+
sleep(@timeout)
|
|
140
|
+
else
|
|
141
|
+
# We have completed jobs.
|
|
142
|
+
while !@toDropQueue.empty?
|
|
143
|
+
# Pop a job from the @toDropQueue and call the block with it.
|
|
144
|
+
job = @toDropQueue.pop
|
|
145
|
+
# Remove the job related entries from the housekeeping tables.
|
|
146
|
+
@lock.synchronize { @jobsOut += 1 }
|
|
147
|
+
|
|
148
|
+
# Call the post-processing block that was passed to wait() with
|
|
149
|
+
# the JobInfo object as argument.
|
|
150
|
+
yield(job)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
114
153
|
end
|
|
115
154
|
|
|
116
155
|
# Signal threads to stop
|
|
@@ -120,38 +159,59 @@ class TaskJuggler
|
|
|
120
159
|
@popper.join
|
|
121
160
|
@grabber.join
|
|
122
161
|
|
|
123
|
-
#
|
|
124
|
-
@
|
|
162
|
+
# Reset some variables so we can reuse the object for further job runs.
|
|
163
|
+
@jobsIn = @jobsOut = 0
|
|
164
|
+
@terminate = false
|
|
165
|
+
|
|
166
|
+
# Make sure all data structures are empty and clean.
|
|
167
|
+
check
|
|
125
168
|
end
|
|
126
169
|
|
|
127
170
|
private
|
|
128
171
|
|
|
129
172
|
# This function runs in a separate thread to pop JobInfo items from the
|
|
130
|
-
# @
|
|
173
|
+
# @toRunQueue and create child processes for them.
|
|
131
174
|
def pusher
|
|
132
175
|
# Run until the terminate flag is set.
|
|
133
176
|
until @terminate
|
|
134
|
-
if @
|
|
135
|
-
# We have no jobs in the @
|
|
177
|
+
if @toRunQueue.empty? || @runningJobs.length >= @maxCpuCores
|
|
178
|
+
# We have no jobs in the @toRunQueue or all CPU cores in use already.
|
|
136
179
|
sleep(@timeout)
|
|
137
180
|
else
|
|
138
|
-
# Get a new job from the @
|
|
139
|
-
job = @
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
181
|
+
# Get a new job from the @toRunQueue
|
|
182
|
+
job = @toRunQueue.pop
|
|
183
|
+
|
|
184
|
+
job.openPipes
|
|
185
|
+
# Add the receiver end of the pipe to the @pipes Array.
|
|
186
|
+
@pipes << job.stdoutP
|
|
187
|
+
# Map the pipe end to this JobInfo object.
|
|
188
|
+
@pipeToJob[job.stdoutP] = job
|
|
189
|
+
# Same for $stderr.
|
|
190
|
+
@pipes << job.stderrP
|
|
191
|
+
@pipeToJob[job.stderrP] = job
|
|
192
|
+
|
|
150
193
|
@lock.synchronize do
|
|
194
|
+
pid = fork do
|
|
195
|
+
# This is the child process now. Connect $stdout and $stderr to
|
|
196
|
+
# the pipes.
|
|
197
|
+
$stdout.reopen(job.stdoutC)
|
|
198
|
+
job.stdoutC.close
|
|
199
|
+
$stderr.reopen(job.stderrC)
|
|
200
|
+
job.stderrC.close
|
|
201
|
+
# Call the Ruby code block
|
|
202
|
+
retVal = job.block.call
|
|
203
|
+
# Send EOT character to mark the end of the text.
|
|
204
|
+
$stdout.putc 4
|
|
205
|
+
$stdout.close
|
|
206
|
+
$stderr.putc 4
|
|
207
|
+
$stderr.close
|
|
208
|
+
# Now exit the child process and return the return value of the
|
|
209
|
+
# block as process return value.
|
|
210
|
+
exit retVal
|
|
211
|
+
end
|
|
212
|
+
job.pid = pid
|
|
151
213
|
# Save the process ID in the PID to JobInfo hash.
|
|
152
|
-
@
|
|
153
|
-
# Increase the jobs-in-flight counter.
|
|
154
|
-
@pendingJobs += 1
|
|
214
|
+
@runningJobs[pid] = job
|
|
155
215
|
end
|
|
156
216
|
end
|
|
157
217
|
end
|
|
@@ -162,20 +222,31 @@ class TaskJuggler
|
|
|
162
222
|
# corresponding JobInfo object.
|
|
163
223
|
def popper
|
|
164
224
|
until @terminate
|
|
165
|
-
if @
|
|
225
|
+
if @runningJobs.empty?
|
|
166
226
|
# No pending jobs, wait a bit.
|
|
167
227
|
sleep(@timeout)
|
|
168
228
|
else
|
|
169
229
|
# Wait for the next job to complete.
|
|
170
230
|
pid, retVal = Process.wait2
|
|
231
|
+
job = nil
|
|
171
232
|
@lock.synchronize do
|
|
172
233
|
# Get the JobInfo object that corresponds to the process ID.
|
|
173
|
-
job = @
|
|
174
|
-
raise "Unknown
|
|
234
|
+
job = @runningJobs[pid]
|
|
235
|
+
raise "Unknown pid #{pid}" if job.nil?
|
|
236
|
+
# Remove the job from the @runningJobs Hash.
|
|
237
|
+
@runningJobs.delete(pid)
|
|
175
238
|
# Save the return value.
|
|
176
|
-
job.retVal = retVal
|
|
177
|
-
|
|
178
|
-
|
|
239
|
+
job.retVal = retVal.dup
|
|
240
|
+
if retVal.signaled?
|
|
241
|
+
cleanPipes(job)
|
|
242
|
+
# Aborted jobs will probably not send an EOT. So we fastrack
|
|
243
|
+
# them to the toDropQueue.
|
|
244
|
+
@toDropQueue.push(job)
|
|
245
|
+
else
|
|
246
|
+
# Push the job into the @spoolingJobs list to wait for it to
|
|
247
|
+
# finish writing IO.
|
|
248
|
+
@spoolingJobs << job
|
|
249
|
+
end
|
|
179
250
|
end
|
|
180
251
|
end
|
|
181
252
|
end
|
|
@@ -186,24 +257,80 @@ class TaskJuggler
|
|
|
186
257
|
# object that corresponds to each child process.
|
|
187
258
|
def grabber
|
|
188
259
|
until @terminate
|
|
189
|
-
# Wait for output in any of the pipes or a timeout.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
260
|
+
# Wait for output in any of the pipes or a timeout. To make sure that
|
|
261
|
+
# we get all output, we remain in the loop until the select() call
|
|
262
|
+
# times out.
|
|
263
|
+
res = nil
|
|
264
|
+
begin
|
|
265
|
+
@lock.synchronize do
|
|
266
|
+
if (res = select(@pipes, nil, @pipes, @timeout))
|
|
267
|
+
# We have output data from at least one child. Check which pipe
|
|
268
|
+
# actually triggered the select.
|
|
269
|
+
res[0].each do |pipe|
|
|
270
|
+
# Find the corresponding JobInfo object.
|
|
271
|
+
job = @pipeToJob[pipe]
|
|
272
|
+
# Store the output.
|
|
273
|
+
if pipe == job.stdoutP
|
|
274
|
+
# Look for the EOT character to signal the end of the text.
|
|
275
|
+
if (c = pipe.getc) == ?\004
|
|
276
|
+
job.stdoutEOT = true
|
|
277
|
+
else
|
|
278
|
+
job.stdout << c
|
|
279
|
+
end
|
|
280
|
+
else
|
|
281
|
+
if (c = pipe.getc) == ?\004
|
|
282
|
+
job.stderrEOT = true
|
|
283
|
+
else
|
|
284
|
+
job.stderr << c
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
sleep(@timeout) unless res
|
|
291
|
+
end while res
|
|
292
|
+
|
|
293
|
+
# Search the @spoolingJobs list for jobs that have completed IO and
|
|
294
|
+
# push them to the @toDropQueue.
|
|
295
|
+
@lock.synchronize do
|
|
296
|
+
@spoolingJobs.each do |job|
|
|
297
|
+
# Both stdout and stderr need to have reached the end of text.
|
|
298
|
+
if job.stdoutEOT && job.stderrEOT
|
|
299
|
+
@spoolingJobs.delete(job)
|
|
300
|
+
cleanPipes(job)
|
|
301
|
+
@toDropQueue.push(job)
|
|
302
|
+
# Since we deleted a list item during an iterator run, we
|
|
303
|
+
# terminate the iterator.
|
|
304
|
+
break
|
|
201
305
|
end
|
|
202
306
|
end
|
|
203
307
|
end
|
|
204
308
|
end
|
|
205
309
|
end
|
|
206
310
|
|
|
311
|
+
def cleanPipes(job)
|
|
312
|
+
@pipes.delete(job.stdoutP)
|
|
313
|
+
@pipeToJob.delete(job.stdoutP)
|
|
314
|
+
@pipes.delete(job.stderrP)
|
|
315
|
+
@pipeToJob.delete(job.stderrP)
|
|
316
|
+
job.stdoutC.close
|
|
317
|
+
job.stdoutP.close
|
|
318
|
+
job.stderrC.close
|
|
319
|
+
job.stderrP.close
|
|
320
|
+
job.stdoutC = job.stderrC = nil
|
|
321
|
+
job.stdoutP = job.stderrP = nil
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def check
|
|
325
|
+
raise "toRunQueue not empty!" unless @toRunQueue.empty?
|
|
326
|
+
raise "runningJobs list not empty!" unless @runningJobs.empty?
|
|
327
|
+
raise "spoolingJobs list not empty!" unless @spoolingJobs.empty?
|
|
328
|
+
raise "toDropQueue not empty!" unless @toDropQueue.empty?
|
|
329
|
+
|
|
330
|
+
raise "pipe list not empty!" unless @pipes.empty?
|
|
331
|
+
raise "pipe map not empty!" unless @pipeToJob.empty?
|
|
332
|
+
end
|
|
333
|
+
|
|
207
334
|
end
|
|
208
335
|
|
|
209
336
|
end
|
data/lib/Booking.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# = Booking.rb -- The TaskJuggler III Project Management Software
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
7
|
#
|
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
data/lib/Charge.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# = Charge.rb -- The TaskJuggler III Project Management Software
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
7
|
#
|
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
data/lib/ChargeSet.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# = ChargeSet.rb -- The TaskJuggler III Project Management Software
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
7
|
#
|
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
data/lib/HTMLDocument.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# = HTMLDocument.rb -- The TaskJuggler III Project Management Software
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
7
|
#
|
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
|
@@ -25,7 +25,7 @@ class TaskJuggler
|
|
|
25
25
|
def initialize(docType = :transitional)
|
|
26
26
|
super()
|
|
27
27
|
|
|
28
|
-
@elements << XMLBlob.new('<?xml version="1.0" encoding="
|
|
28
|
+
@elements << XMLBlob.new('<?xml version="1.0" encoding="utf-8"?>')
|
|
29
29
|
case docType
|
|
30
30
|
when :strict
|
|
31
31
|
dtdRef = 'Strict'
|
data/lib/Interval.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# = Interval.rb -- The TaskJuggler III Project Management Software
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
7
|
#
|
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
data/lib/Journal.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env ruby -w
|
|
2
2
|
# encoding: UTF-8
|
|
3
3
|
#
|
|
4
|
-
# =
|
|
4
|
+
# = Journal.rb -- The TaskJuggler III Project Management Software
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
7
|
#
|
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
|
@@ -12,31 +12,253 @@
|
|
|
12
12
|
|
|
13
13
|
class TaskJuggler
|
|
14
14
|
|
|
15
|
+
# A JournalEntry stores some RichText strings to describe a status or a
|
|
16
|
+
# property of the project at a certain point in time. Additionally, the
|
|
17
|
+
# entry can contain a reference to a Resource as author and an alert level.
|
|
18
|
+
# The text is structured in 3 different elements, a headline, a short
|
|
19
|
+
# summary and a longer text segment. The headline is mandatory, the
|
|
20
|
+
# summary and details sections are optional.
|
|
15
21
|
class JournalEntry
|
|
16
22
|
|
|
17
|
-
attr_reader :date, :headline, :property
|
|
18
|
-
attr_accessor :
|
|
23
|
+
attr_reader :date, :headline, :property, :sourceFileInfo
|
|
24
|
+
attr_accessor :author, :summary, :details, :alertLevel
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
# Create a new JournalEntry object.
|
|
27
|
+
def initialize(journal, date, headline, property, sourceFileInfo = nil)
|
|
28
|
+
# A reference to the Journal object this entry belongs to.
|
|
21
29
|
@journal = journal
|
|
22
|
-
|
|
30
|
+
# The date of the entry.
|
|
23
31
|
@date = date
|
|
32
|
+
# A very short description. Should not be longer than about 40
|
|
33
|
+
# characters.
|
|
24
34
|
@headline = headline
|
|
35
|
+
# A reference to a PropertyTreeNode object.
|
|
25
36
|
@property = property
|
|
26
|
-
|
|
27
|
-
@
|
|
37
|
+
# Source file location of this entry of type SourceFileInfo
|
|
38
|
+
@sourceFileInfo = sourceFileInfo
|
|
39
|
+
# A reference to a Resource.
|
|
40
|
+
@author = nil
|
|
41
|
+
# An introductory or summarizing RichText paragraph.
|
|
42
|
+
@summary = nil
|
|
43
|
+
# A RichText of arbitrary length.
|
|
44
|
+
@details = nil
|
|
45
|
+
# The alert level.
|
|
46
|
+
@alertLevel = 0
|
|
47
|
+
|
|
48
|
+
# Add the new entry to the journal.
|
|
49
|
+
@journal.addEntry(self)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Just for debugging
|
|
53
|
+
def to_s # :nodoc:
|
|
54
|
+
@headline
|
|
28
55
|
end
|
|
29
56
|
|
|
30
57
|
end
|
|
31
58
|
|
|
32
|
-
|
|
59
|
+
# The JournalEntryList is an Array with a twist. Before any data retrieval
|
|
60
|
+
# function is called, the list of JournalEntry objects will be sorted by
|
|
61
|
+
# date. This is a utility class only. Use Journal to store a journal.
|
|
62
|
+
class JournalEntryList
|
|
33
63
|
|
|
34
64
|
def initialize
|
|
35
65
|
@entries = []
|
|
66
|
+
@sorted = false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Return the number of entries.
|
|
70
|
+
def count
|
|
71
|
+
@entries.length
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Add a new JournalEntry to the list. The list will be marked as unsorted.
|
|
75
|
+
def <<(entry)
|
|
76
|
+
@entries << entry
|
|
77
|
+
@sorted = false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Add a list of JournalEntry objects to the existing list. The list will
|
|
81
|
+
# be marked unsorted.
|
|
82
|
+
def +(list)
|
|
83
|
+
@entries + list
|
|
36
84
|
end
|
|
37
85
|
|
|
86
|
+
# Return the _index_-th entry.
|
|
87
|
+
def[](index)
|
|
88
|
+
sort
|
|
89
|
+
@entries[index]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# The well known iterator. The list will be sorted first.
|
|
93
|
+
def each
|
|
94
|
+
sort
|
|
95
|
+
@entries.each do |entry|
|
|
96
|
+
yield entry
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Like Array::include?
|
|
101
|
+
def include?(entry)
|
|
102
|
+
@entries.include?(entry)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Returns the last elements (by date) if date is nil or the last elements
|
|
106
|
+
# right before the given _date_. If there are multiple entries with
|
|
107
|
+
# exactly the same date, all are returned. Otherwise the result Array will
|
|
108
|
+
# only contain one element. In case no matching entry is found, the Array
|
|
109
|
+
# will be empty.
|
|
110
|
+
def last(date = nil)
|
|
111
|
+
result = []
|
|
112
|
+
sort
|
|
113
|
+
# If we have no date, return the latest entry.
|
|
114
|
+
return [ @entries.last ] unless date
|
|
115
|
+
|
|
116
|
+
@entries.reverse_each do |e|
|
|
117
|
+
if result.empty?
|
|
118
|
+
result << e if e.date <= date
|
|
119
|
+
elsif result.first.date == e.date
|
|
120
|
+
result << e
|
|
121
|
+
else
|
|
122
|
+
break
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
result
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
# Sort the list of entries. First by ascending by date, than by alertLevel
|
|
131
|
+
# and finally by PropertyTreeNode sequence number.
|
|
132
|
+
def sort
|
|
133
|
+
return if @sorted
|
|
134
|
+
|
|
135
|
+
@entries.sort! { |a, b| a.date != b.date ?
|
|
136
|
+
a.date <=> b.date :
|
|
137
|
+
(a.alertLevel != b.alertLevel ?
|
|
138
|
+
a.alertLevel <=> b.alertLevel :
|
|
139
|
+
a.property.sequenceNo <=>
|
|
140
|
+
b.property.sequenceNo) }
|
|
141
|
+
@sorted = true
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# A Journal is a list of JournalEntry objects. It provides methods to add
|
|
147
|
+
# JournalEntry objects and retrieve specific entries or other processed
|
|
148
|
+
# information.
|
|
149
|
+
class Journal
|
|
150
|
+
|
|
151
|
+
# Create a new Journal object.
|
|
152
|
+
def initialize
|
|
153
|
+
# This list holds all entries.
|
|
154
|
+
@entries = JournalEntryList.new
|
|
155
|
+
# This hash holds a list of entries for each property.
|
|
156
|
+
@propertyToEntries = {}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Add a new JournalEntry to the Journal.
|
|
38
160
|
def addEntry(entry)
|
|
161
|
+
return if @entries.include?(entry)
|
|
39
162
|
@entries << entry
|
|
163
|
+
|
|
164
|
+
return if entry.property.nil?
|
|
165
|
+
|
|
166
|
+
unless @propertyToEntries.include?(entry.property)
|
|
167
|
+
@propertyToEntries[entry.property] = JournalEntryList.new
|
|
168
|
+
end
|
|
169
|
+
@propertyToEntries[entry.property] << entry
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def entries(startDate = nil, endDate = nil, property = nil,
|
|
173
|
+
alertLevel = nil)
|
|
174
|
+
list = []
|
|
175
|
+
@entries.each do |entry|
|
|
176
|
+
if (startDate.nil? || startDate <= entry.date) &&
|
|
177
|
+
(endDate.nil? || endDate >= entry.date) &&
|
|
178
|
+
(property.nil? || property == entry.property ||
|
|
179
|
+
entry.property.isChildOf?(property)) ||
|
|
180
|
+
(alertLevel.nil? || alertLevel == entry.alertLevel)
|
|
181
|
+
list << entry
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
list
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Determine the alert level for the given _property_ at the given _date_.
|
|
188
|
+
# If the property does not have any JournalEntry objects or they are out
|
|
189
|
+
# of date compared to the child properties, the level is computed based on
|
|
190
|
+
# the highest level of the children.
|
|
191
|
+
def alertLevel(date, property)
|
|
192
|
+
maxLevel = 0
|
|
193
|
+
# Gather all the current (as of the specified _date_) JournalEntry
|
|
194
|
+
# objects for the property and than find the highest level.
|
|
195
|
+
currentEntriesR(date, property).each do |e|
|
|
196
|
+
maxLevel = e.alertLevel if maxLevel < e.alertLevel
|
|
197
|
+
end
|
|
198
|
+
maxLevel
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# This function returns a list of entries that have all the exact same
|
|
202
|
+
# date and are the last entries before the deadline _date_. Only messages
|
|
203
|
+
# with at least the required alert level _minLevel_ are returned. Messages
|
|
204
|
+
# with alert level _minLevel_ must not be older than _minDate_.
|
|
205
|
+
def currentEntries(date, property, minLevel, minDate)
|
|
206
|
+
pEntries = @propertyToEntries[property] ?
|
|
207
|
+
@propertyToEntries[property].last(date) : []
|
|
208
|
+
# Remove entries below the minium alert level or before the timeout
|
|
209
|
+
# date.
|
|
210
|
+
pEntries.delete_if { |e| e.alertLevel < minLevel || e.headline.empty? ||
|
|
211
|
+
(e.alertLevel == minLevel && e.date < minDate) }
|
|
212
|
+
|
|
213
|
+
return [] if pEntries.empty?
|
|
214
|
+
|
|
215
|
+
# Check parents for a more important or more up-to-date message.
|
|
216
|
+
p = property.parent
|
|
217
|
+
while p do
|
|
218
|
+
ppEntries = @propertyToEntries[p] ?
|
|
219
|
+
@propertyToEntries[p].last(date) : []
|
|
220
|
+
|
|
221
|
+
# A parent has a more up-to-date message.
|
|
222
|
+
if !ppEntries.empty? && ppEntries.first.date >= pEntries.first.date
|
|
223
|
+
return []
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
p = p.parent
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
pEntries
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# This function recursively traverses a tree of PropertyTreeNode objects
|
|
233
|
+
# from bottom to top. It returns the last entries before _date_ for each
|
|
234
|
+
# property unless there is a property in the sub-tree specified by the
|
|
235
|
+
# root _property_ with more up-to-date entries. The result is a
|
|
236
|
+
# JournalEntryList.
|
|
237
|
+
def currentEntriesR(date, property)
|
|
238
|
+
# See if this property has any current JournalEntry objects.
|
|
239
|
+
pEntries = @propertyToEntries[property] ?
|
|
240
|
+
@propertyToEntries[property].last(date) : []
|
|
241
|
+
|
|
242
|
+
entries = JournalEntryList.new
|
|
243
|
+
latestDate = nil
|
|
244
|
+
# Now gather all current entries of the child properties and find the
|
|
245
|
+
# date that is closest to and right before the given _date_.
|
|
246
|
+
property.children.each do |p|
|
|
247
|
+
currentEntriesR(date, p).each do |e|
|
|
248
|
+
latestDate = e.date if latestDate.nil? || e.date > latestDate
|
|
249
|
+
entries << e
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
# If no child property has a more current JournalEntry than this
|
|
253
|
+
# property and this property has JournalEntry objects, than those are
|
|
254
|
+
# taken.
|
|
255
|
+
if !pEntries.empty? && (latestDate.nil? ||
|
|
256
|
+
pEntries.first.date >= latestDate)
|
|
257
|
+
entries = JournalEntryList.new
|
|
258
|
+
entries += pEntries
|
|
259
|
+
end
|
|
260
|
+
# Otherwise return the list provided by the childen.
|
|
261
|
+
entries
|
|
40
262
|
end
|
|
41
263
|
|
|
42
264
|
end
|