taskjuggler 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +61 -0
- data/README.rdoc +43 -27
- data/data/css/tjreport.css +30 -0
- data/data/tjp.vim +100 -89
- data/examples/ProjectTemplate/template.tjp +338 -0
- data/examples/ToDo-List/todolist.tjp +84 -0
- data/examples/{tutorial.tjp → Tutorial/tutorial.tjp} +9 -7
- data/lib/header.tmpl +1 -1
- data/lib/taskjuggler/Account.rb +2 -2
- data/lib/taskjuggler/AccountCredit.rb +29 -0
- data/lib/taskjuggler/AccountScenario.rb +73 -7
- data/lib/taskjuggler/AlertLevelDefinitions.rb +104 -0
- data/lib/taskjuggler/AlgorithmDiff.rb +2 -2
- data/lib/taskjuggler/Allocation.rb +1 -1
- data/lib/taskjuggler/AppConfig.rb +1 -1
- data/lib/taskjuggler/AttributeBase.rb +1 -1
- data/lib/taskjuggler/AttributeDefinition.rb +1 -1
- data/lib/taskjuggler/Attributes.rb +40 -3
- data/lib/taskjuggler/BatchProcessor.rb +15 -14
- data/lib/taskjuggler/Booking.rb +1 -1
- data/lib/taskjuggler/Charge.rb +2 -2
- data/lib/taskjuggler/ChargeSet.rb +1 -1
- data/lib/taskjuggler/DataCache.rb +24 -12
- data/lib/taskjuggler/FileList.rb +1 -1
- data/lib/taskjuggler/HTMLDocument.rb +1 -1
- data/lib/taskjuggler/HTMLElements.rb +1 -1
- data/lib/taskjuggler/ICalendar.rb +1 -1
- data/lib/taskjuggler/Interval.rb +1 -1
- data/lib/taskjuggler/IntervalList.rb +1 -1
- data/lib/taskjuggler/Journal.rb +61 -41
- data/lib/taskjuggler/KeywordArray.rb +1 -1
- data/lib/taskjuggler/KeywordDocumentation.rb +121 -33
- data/lib/taskjuggler/LeaveList.rb +103 -0
- data/lib/taskjuggler/Limits.rb +1 -1
- data/lib/taskjuggler/Log.rb +6 -3
- data/lib/taskjuggler/LogFile.rb +1 -1
- data/lib/taskjuggler/LogicalExpression.rb +1 -1
- data/lib/taskjuggler/LogicalFunction.rb +16 -2
- data/lib/taskjuggler/LogicalOperation.rb +3 -1
- data/lib/taskjuggler/MessageHandler.rb +13 -4
- data/lib/taskjuggler/PTNProxy.rb +118 -0
- data/lib/taskjuggler/Project.rb +58 -67
- data/lib/taskjuggler/ProjectFileParser.rb +39 -5
- data/lib/taskjuggler/ProjectFileScanner.rb +1 -1
- data/lib/taskjuggler/PropertyList.rb +26 -2
- data/lib/taskjuggler/PropertySet.rb +8 -1
- data/lib/taskjuggler/PropertyTreeNode.rb +36 -32
- data/lib/taskjuggler/Query.rb +1 -1
- data/lib/taskjuggler/RealFormat.rb +4 -2
- data/lib/taskjuggler/Resource.rb +3 -3
- data/lib/taskjuggler/ResourceScenario.rb +219 -140
- data/lib/taskjuggler/RichText.rb +1 -1
- data/lib/taskjuggler/RichText/Document.rb +2 -2
- data/lib/taskjuggler/RichText/Element.rb +2 -2
- data/lib/taskjuggler/RichText/FunctionExample.rb +2 -2
- data/lib/taskjuggler/RichText/FunctionHandler.rb +2 -2
- data/lib/taskjuggler/RichText/Parser.rb +2 -2
- data/lib/taskjuggler/RichText/RTFHandlers.rb +1 -1
- data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
- data/lib/taskjuggler/RichText/RTFQuery.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -1
- data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
- data/lib/taskjuggler/RichText/Scanner.rb +18 -4
- data/lib/taskjuggler/RichText/Snip.rb +2 -2
- data/lib/taskjuggler/RichText/SyntaxRules.rb +6 -14
- data/lib/taskjuggler/RichText/TOCEntry.rb +16 -7
- data/lib/taskjuggler/RichText/TableOfContents.rb +3 -2
- data/lib/taskjuggler/RuntimeConfig.rb +1 -1
- data/lib/taskjuggler/Scenario.rb +1 -1
- data/lib/taskjuggler/ScenarioData.rb +1 -1
- data/lib/taskjuggler/Scoreboard.rb +1 -1
- data/lib/taskjuggler/SheetHandlerBase.rb +1 -1
- data/lib/taskjuggler/SheetReceiver.rb +1 -1
- data/lib/taskjuggler/SheetSender.rb +3 -3
- data/lib/taskjuggler/Shift.rb +2 -2
- data/lib/taskjuggler/ShiftAssignments.rb +24 -19
- data/lib/taskjuggler/ShiftScenario.rb +4 -4
- data/lib/taskjuggler/SimpleQueryExpander.rb +1 -1
- data/lib/taskjuggler/StatusSheetReceiver.rb +1 -1
- data/lib/taskjuggler/StatusSheetSender.rb +1 -1
- data/lib/taskjuggler/StdIoWrapper.rb +1 -1
- data/lib/taskjuggler/SyntaxReference.rb +5 -2
- data/lib/taskjuggler/TableColumnDefinition.rb +1 -1
- data/lib/taskjuggler/Task.rb +4 -8
- data/lib/taskjuggler/TaskDependency.rb +1 -1
- data/lib/taskjuggler/TaskJuggler.rb +1 -1
- data/lib/taskjuggler/TaskScenario.rb +131 -51
- data/lib/taskjuggler/TernarySearchTree.rb +6 -4
- data/lib/taskjuggler/TextFormatter.rb +9 -2
- data/lib/taskjuggler/TextParser.rb +13 -3
- data/lib/taskjuggler/TextParser/MacroTable.rb +1 -1
- data/lib/taskjuggler/TextParser/Pattern.rb +52 -8
- data/lib/taskjuggler/TextParser/Rule.rb +11 -5
- data/lib/taskjuggler/TextParser/Scanner.rb +1 -1
- data/lib/taskjuggler/TextParser/SourceFileInfo.rb +1 -1
- data/lib/taskjuggler/TextParser/StackElement.rb +1 -1
- data/lib/taskjuggler/TextParser/State.rb +2 -2
- data/lib/taskjuggler/TextParser/TokenDoc.rb +1 -1
- data/lib/taskjuggler/TimeSheetReceiver.rb +1 -1
- data/lib/taskjuggler/TimeSheetSender.rb +1 -1
- data/lib/taskjuggler/TimeSheetSummary.rb +1 -1
- data/lib/taskjuggler/TimeSheets.rb +4 -6
- data/lib/taskjuggler/Tj3AppBase.rb +18 -1
- data/lib/taskjuggler/Tj3Config.rb +4 -4
- data/lib/taskjuggler/Tj3SheetAppBase.rb +1 -1
- data/lib/taskjuggler/TjException.rb +1 -1
- data/lib/taskjuggler/TjTime.rb +1 -1
- data/lib/taskjuggler/TjpExample.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +920 -392
- data/lib/taskjuggler/URLParameter.rb +1 -1
- data/lib/taskjuggler/UTF8String.rb +1 -1
- data/lib/taskjuggler/UserManual.rb +1 -1
- data/lib/taskjuggler/VimSyntax.rb +9 -6
- data/lib/taskjuggler/WorkingHours.rb +12 -1
- data/lib/taskjuggler/XMLDocument.rb +1 -1
- data/lib/taskjuggler/XMLElement.rb +1 -1
- data/lib/taskjuggler/apps/Tj3.rb +8 -3
- data/lib/taskjuggler/apps/Tj3Client.rb +1 -1
- data/lib/taskjuggler/apps/Tj3Daemon.rb +1 -1
- data/lib/taskjuggler/apps/Tj3Man.rb +1 -1
- data/lib/taskjuggler/apps/Tj3SsReceiver.rb +2 -2
- data/lib/taskjuggler/apps/Tj3SsSender.rb +1 -1
- data/lib/taskjuggler/apps/Tj3TsReceiver.rb +1 -1
- data/lib/taskjuggler/apps/Tj3TsSender.rb +1 -1
- data/lib/taskjuggler/apps/Tj3TsSummary.rb +1 -1
- data/lib/taskjuggler/daemon/Daemon.rb +1 -1
- data/lib/taskjuggler/daemon/ProcessIntercom.rb +1 -1
- data/lib/taskjuggler/daemon/ProjectBroker.rb +1 -1
- data/lib/taskjuggler/daemon/ProjectServer.rb +1 -1
- data/lib/taskjuggler/daemon/ReportServer.rb +2 -2
- data/lib/taskjuggler/daemon/ReportServlet.rb +1 -1
- data/lib/taskjuggler/daemon/WebServer.rb +1 -1
- data/lib/taskjuggler/daemon/WelcomePage.rb +1 -1
- data/lib/taskjuggler/deep_copy.rb +1 -1
- data/lib/taskjuggler/reports/AccountListRE.rb +115 -0
- data/lib/taskjuggler/reports/CSVFile.rb +1 -1
- data/lib/taskjuggler/reports/CollisionDetector.rb +1 -1
- data/lib/taskjuggler/reports/ColumnTable.rb +1 -1
- data/lib/taskjuggler/reports/GanttChart.rb +1 -1
- data/lib/taskjuggler/reports/GanttContainer.rb +1 -3
- data/lib/taskjuggler/reports/GanttHeader.rb +1 -1
- data/lib/taskjuggler/reports/GanttHeaderScaleItem.rb +1 -1
- data/lib/taskjuggler/reports/GanttLine.rb +23 -12
- data/lib/taskjuggler/reports/GanttLoadStack.rb +1 -1
- data/lib/taskjuggler/reports/GanttMilestone.rb +1 -1
- data/lib/taskjuggler/reports/GanttRouter.rb +1 -1
- data/lib/taskjuggler/reports/GanttTaskBar.rb +1 -1
- data/lib/taskjuggler/reports/HTMLGraphics.rb +1 -1
- data/lib/taskjuggler/reports/ICalReport.rb +5 -2
- data/lib/taskjuggler/reports/Navigator.rb +1 -1
- data/lib/taskjuggler/reports/NikuReport.rb +1 -1
- data/lib/taskjuggler/reports/Report.rb +29 -4
- data/lib/taskjuggler/reports/ReportBase.rb +15 -1
- data/lib/taskjuggler/reports/ReportContext.rb +1 -1
- data/lib/taskjuggler/reports/ReportTable.rb +1 -1
- data/lib/taskjuggler/reports/ReportTableCell.rb +1 -1
- data/lib/taskjuggler/reports/ReportTableColumn.rb +1 -1
- data/lib/taskjuggler/reports/ReportTableLegend.rb +1 -1
- data/lib/taskjuggler/reports/ReportTableLine.rb +1 -1
- data/lib/taskjuggler/reports/ResourceListRE.rb +3 -5
- data/lib/taskjuggler/reports/StatusSheetReport.rb +2 -2
- data/lib/taskjuggler/reports/TableReport.rb +336 -204
- data/lib/taskjuggler/reports/TableReportColumn.rb +30 -0
- data/lib/taskjuggler/reports/TagFile.rb +2 -2
- data/lib/taskjuggler/reports/TaskListRE.rb +3 -6
- data/lib/taskjuggler/reports/TextReport.rb +1 -1
- data/lib/taskjuggler/reports/TimeSheetReport.rb +3 -3
- data/lib/taskjuggler/reports/TjpExportRE.rb +4 -1
- data/lib/tj3.rb +1 -1
- data/lib/tj3client.rb +1 -1
- data/lib/tj3d.rb +1 -1
- data/lib/tj3man.rb +1 -1
- data/lib/tj3ss_receiver.rb +1 -1
- data/lib/tj3ss_sender.rb +1 -1
- data/lib/tj3ts_receiver.rb +1 -1
- data/lib/tj3ts_sender.rb +1 -1
- data/lib/tj3ts_summary.rb +1 -1
- data/lib/updateheader.sh +4 -1
- data/manual/Getting_Started +7 -4
- data/manual/How_To_Contribute +26 -5
- data/manual/Installation +26 -18
- data/manual/Intro +55 -33
- data/manual/Reporting_Bugs +18 -8
- data/manual/Rich_Text_Attributes +16 -3
- data/manual/Software +2 -2
- data/manual/TaskJuggler_2x_Migration +2 -2
- data/manual/The_TaskJuggler_Syntax +10 -0
- data/manual/Tutorial +2 -2
- data/manual/html/Day_To_Day_Juggling.html +16 -12
- data/manual/html/Getting_Started.html +9 -7
- data/manual/html/How_To_Contribute.html +18 -10
- data/manual/html/Installation.html +18 -15
- data/manual/html/Intro.html +44 -28
- data/manual/html/Reporting_Bugs.html +9 -7
- data/manual/html/Rich_Text_Attributes.html +11 -8
- data/manual/html/Software.html +5 -5
- data/manual/html/TaskJuggler_2x_Migration.html +4 -4
- data/manual/html/TaskJuggler_Internals.html +3 -3
- data/manual/html/The_TaskJuggler_Syntax.html +6 -3
- data/manual/html/Tutorial.html +12 -12
- data/manual/html/account.html +19 -10
- data/manual/html/account.task.html +5 -28
- data/manual/html/accountprefix.html +5 -5
- data/manual/html/{report.html → accountreport.html} +140 -23
- data/manual/html/accountroot.html +142 -0
- data/manual/html/active.html +5 -5
- data/manual/html/adopt.task.html +7 -8
- data/manual/html/aggregate.html +145 -0
- data/manual/html/alert.html +12 -11
- data/manual/html/alertlevels.html +102 -0
- data/manual/html/allocate.html +6 -6
- data/manual/html/alphabet.html +1 -1
- data/manual/html/alternative.html +3 -3
- data/manual/html/author.html +3 -3
- data/manual/html/balance.html +84 -11
- data/manual/html/booking.resource.html +3 -3
- data/manual/html/booking.task.html +3 -3
- data/manual/html/caption.html +6 -4
- data/manual/html/cellcolor.column.html +3 -3
- data/manual/html/celltext.column.html +3 -3
- data/manual/html/center.html +28 -4
- data/manual/html/charge.html +3 -3
- data/manual/html/chargeset.html +5 -5
- data/manual/html/columnid.html +40 -9
- data/manual/html/columns.html +6 -4
- data/manual/html/complete.html +15 -9
- data/manual/html/copyright.html +5 -5
- data/manual/html/{credit.html → credits.html} +15 -12
- data/manual/html/css/tjreport.css +30 -0
- data/manual/html/currency.html +28 -15
- data/manual/html/currencyformat.html +4 -4
- data/manual/html/dailymax.html +3 -3
- data/manual/html/dailymin.html +3 -3
- data/manual/html/dailyworkinghours.html +3 -3
- data/manual/html/date.extend.html +3 -3
- data/manual/html/date.html +3 -3
- data/manual/html/definitions.html +3 -3
- data/manual/html/depends.html +3 -3
- data/manual/html/details.html +3 -3
- data/manual/html/disabled.html +9 -3
- data/manual/html/duration.html +3 -3
- data/manual/html/efficiency.html +3 -3
- data/manual/html/effort.html +3 -3
- data/manual/html/email.html +3 -3
- data/manual/html/enabled.html +9 -3
- data/manual/html/end.column.html +3 -3
- data/manual/html/end.html +3 -3
- data/manual/html/end.limit.html +3 -3
- data/manual/html/end.report.html +4 -4
- data/manual/html/end.timesheet.html +3 -3
- data/manual/html/endcredit.html +18 -9
- data/manual/html/epilog.html +6 -4
- data/manual/html/export.html +10 -6
- data/manual/html/extend.html +3 -3
- data/manual/html/fail.html +3 -3
- data/manual/html/fdl.html +3 -3
- data/manual/html/flags.account.html +3 -3
- data/manual/html/flags.html +3 -3
- data/manual/html/flags.journalentry.html +3 -3
- data/manual/html/flags.report.html +6 -4
- data/manual/html/flags.resource.html +3 -3
- data/manual/html/flags.statussheet.html +3 -3
- data/manual/html/flags.task.html +3 -3
- data/manual/html/flags.timesheet.html +3 -3
- data/manual/html/fontcolor.column.html +3 -3
- data/manual/html/footer.html +28 -4
- data/manual/html/formats.html +4 -4
- data/manual/html/functions.html +4 -4
- data/manual/html/gapduration.html +3 -3
- data/manual/html/gaplength.html +4 -4
- data/manual/html/halign.center.html +3 -3
- data/manual/html/halign.column.html +3 -3
- data/manual/html/halign.left.html +3 -3
- data/manual/html/halign.right.html +3 -3
- data/manual/html/hasalert.html +3 -3
- data/manual/html/header.html +28 -4
- data/manual/html/headline.html +6 -6
- data/manual/html/hideaccount.html +73 -0
- data/manual/html/hidejournalentry.html +6 -6
- data/manual/html/hidereport.html +3 -3
- data/manual/html/hideresource.html +4 -4
- data/manual/html/hidetask.html +4 -4
- data/manual/html/icalreport.html +3 -3
- data/manual/html/include.macro.html +4 -4
- data/manual/html/include.project.html +5 -6
- data/manual/html/include.properties.html +5 -97
- data/manual/html/index.html +2 -2
- data/manual/html/inherit.extend.html +3 -3
- data/manual/html/interval1.html +3 -3
- data/manual/html/interval2.html +3 -3
- data/manual/html/interval3.html +3 -3
- data/manual/html/interval4.html +3 -3
- data/manual/html/isactive.html +3 -3
- data/manual/html/ischildof.html +3 -3
- data/manual/html/isdependencyof.html +3 -3
- data/manual/html/isdutyof.html +3 -3
- data/manual/html/isfeatureof.html +3 -3
- data/manual/html/isleaf.html +3 -3
- data/manual/html/ismilestone.html +3 -3
- data/manual/html/isongoing.html +3 -3
- data/manual/html/isresource.html +5 -5
- data/manual/html/{alert level.html → isresponsibilityof.html} +19 -14
- data/manual/html/istask.html +5 -5
- data/manual/html/journalattributes.html +6 -4
- data/manual/html/journalentry.html +3 -3
- data/manual/html/journalmode.html +8 -6
- data/manual/html/leaveallowance.html +139 -0
- data/manual/html/leaves.html +140 -0
- data/manual/html/left.html +30 -6
- data/manual/html/length.html +4 -4
- data/manual/html/limits.allocate.html +5 -32
- data/manual/html/limits.html +3 -3
- data/manual/html/limits.resource.html +3 -3
- data/manual/html/limits.task.html +3 -3
- data/manual/html/listitem.column.html +3 -3
- data/manual/html/listtype.column.html +3 -3
- data/manual/html/loadunit.html +6 -4
- data/manual/html/logicalexpression.html +3 -3
- data/manual/html/logicalflagexpression.html +3 -3
- data/manual/html/macro.html +3 -3
- data/manual/html/managers.html +3 -3
- data/manual/html/mandatory.html +3 -3
- data/manual/html/maxend.html +3 -3
- data/manual/html/maximum.html +3 -3
- data/manual/html/maxstart.html +3 -3
- data/manual/html/milestone.html +3 -3
- data/manual/html/minend.html +3 -3
- data/manual/html/minimum.html +3 -3
- data/manual/html/minstart.html +3 -3
- data/manual/html/monthlymax.html +3 -3
- data/manual/html/monthlymin.html +3 -3
- data/manual/html/navbar.html +23 -5
- data/manual/html/navigator.html +34 -3
- data/manual/html/newtask.html +3 -3
- data/manual/html/nikureport.html +3 -3
- data/manual/html/note.task.html +3 -3
- data/manual/html/now.html +3 -3
- data/manual/html/numberformat.html +4 -4
- data/manual/html/onend.html +3 -3
- data/manual/html/onstart.html +3 -3
- data/manual/html/opennodes.html +6 -4
- data/manual/html/overtime.booking.html +4 -4
- data/manual/html/period.column.html +3 -3
- data/manual/html/period.limit.html +3 -3
- data/manual/html/period.report.html +4 -4
- data/manual/html/period.task.html +3 -3
- data/manual/html/persistent.html +3 -3
- data/manual/html/precedes.html +3 -3
- data/manual/html/priority.html +3 -3
- data/manual/html/priority.timesheet.html +3 -3
- data/manual/html/project.html +4 -4
- data/manual/html/projectid.html +3 -3
- data/manual/html/projectid.task.html +3 -3
- data/manual/html/projectids.html +3 -3
- data/manual/html/projection.html +9 -3
- data/manual/html/prolog.html +6 -4
- data/manual/html/properties.html +193 -9
- data/manual/html/purge.html +5 -5
- data/manual/html/rate.html +3 -3
- data/manual/html/rate.resource.html +3 -3
- data/manual/html/reference.extend.html +3 -3
- data/manual/html/remaining.html +3 -3
- data/manual/html/replace.html +9 -6
- data/manual/html/reportprefix.html +5 -5
- data/manual/html/resource.html +22 -4
- data/manual/html/resourceattributes.html +6 -6
- data/manual/html/resourceprefix.html +3 -3
- data/manual/html/resourcereport.html +311 -8
- data/manual/html/resourceroot.html +6 -4
- data/manual/html/resources.limit.html +4 -4
- data/manual/html/responsible.html +3 -3
- data/manual/html/richtext.extend.html +3 -3
- data/manual/html/right.html +30 -6
- data/manual/html/rollupaccount.html +69 -0
- data/manual/html/rollupresource.html +6 -6
- data/manual/html/rolluptask.html +4 -4
- data/manual/html/scale.column.html +3 -3
- data/manual/html/scenario.html +3 -3
- data/manual/html/scenario.ical.html +3 -3
- data/manual/html/scenarios.export.html +3 -3
- data/manual/html/scenarios.html +6 -4
- data/manual/html/scenariospecific.extend.html +3 -3
- data/manual/html/scheduled.html +3 -3
- data/manual/html/scheduling.html +3 -3
- data/manual/html/select.html +3 -3
- data/manual/html/selfcontained.html +6 -4
- data/manual/html/shift.allocate.html +77 -0
- data/manual/html/shift.html +13 -7
- data/manual/html/shift.resource.html +11 -5
- data/manual/html/shift.task.html +9 -3
- data/manual/html/shift.timesheet.html +4 -4
- data/manual/html/shifts.allocate.html +6 -6
- data/manual/html/shifts.resource.html +3 -3
- data/manual/html/shifts.task.html +3 -3
- data/manual/html/shorttimeformat.html +3 -3
- data/manual/html/sloppy.booking.html +4 -4
- data/manual/html/sloppy.projection.html +12 -6
- data/manual/html/sortaccounts.html +73 -0
- data/manual/html/sortjournalentries.html +8 -6
- data/manual/html/sortresources.html +4 -4
- data/manual/html/sorttasks.html +4 -4
- data/manual/html/start.column.html +3 -3
- data/manual/html/start.html +3 -3
- data/manual/html/start.limit.html +3 -3
- data/manual/html/start.report.html +4 -4
- data/manual/html/startcredit.html +10 -4
- data/manual/html/status.statussheet.html +5 -5
- data/manual/html/status.timesheet.html +5 -5
- data/manual/html/statussheet.html +3 -3
- data/manual/html/statussheetreport.html +10 -6
- data/manual/html/strict.projection.html +10 -4
- data/manual/html/summary.html +3 -3
- data/manual/html/supplement.html +5 -5
- data/manual/html/supplement.resource.html +22 -4
- data/manual/html/supplement.task.html +4 -4
- data/manual/html/tagfile.html +3 -3
- data/manual/html/task.html +3 -3
- data/manual/html/task.statussheet.html +3 -3
- data/manual/html/task.timesheet.html +3 -3
- data/manual/html/taskattributes.html +3 -3
- data/manual/html/taskprefix.html +3 -3
- data/manual/html/taskreport.html +347 -8
- data/manual/html/taskroot.html +6 -4
- data/manual/html/text.extend.html +3 -3
- data/manual/html/textreport.html +333 -8
- data/manual/html/timeformat.html +4 -4
- data/manual/html/timeoff.nikureport.html +3 -3
- data/manual/html/timesheet.html +3 -3
- data/manual/html/timesheetreport.html +10 -6
- data/manual/html/timezone.export.html +3 -3
- data/manual/html/timezone.html +3 -3
- data/manual/html/timezone.report.html +6 -4
- data/manual/html/timezone.shift.html +3 -3
- data/manual/html/timingresolution.html +3 -3
- data/manual/html/title.column.html +3 -3
- data/manual/html/title.html +4 -4
- data/manual/html/toc.html +1705 -658
- data/manual/html/tooltip.column.html +3 -3
- data/manual/html/trackingscenario.html +3 -3
- data/manual/html/treelevel.html +3 -3
- data/manual/html/vacation.html +3 -3
- data/manual/html/vacation.resource.html +4 -4
- data/manual/html/vacation.shift.html +4 -4
- data/manual/html/warn.html +3 -3
- data/manual/html/weeklymax.html +3 -3
- data/manual/html/weeklymin.html +3 -3
- data/manual/html/weekstartsmonday.html +3 -3
- data/manual/html/weekstartssunday.html +3 -3
- data/manual/html/width.column.html +3 -3
- data/manual/html/work.html +3 -3
- data/manual/html/workinghours.project.html +3 -3
- data/manual/html/workinghours.resource.html +3 -3
- data/manual/html/workinghours.shift.html +3 -3
- data/manual/html/yearlyworkingdays.html +4 -4
- data/spec/ICalendar_spec.rb +4 -2
- data/spec/IntervalList_spec.rb +1 -1
- data/spec/ProjectBroker_spec.rb +2 -6
- data/spec/StatusSheets_spec.rb +1 -1
- data/spec/TernarySearchTree_spec.rb +2 -2
- data/spec/TimeSheets_spec.rb +1 -1
- data/spec/Tj3Daemon_spec.rb +1 -1
- data/spec/Tj3_spec.rb +1 -1
- data/spec/support/DaemonControl.rb +1 -1
- data/spec/support/spec_helper.rb +19 -0
- data/taskjuggler.gemspec +1 -0
- data/test/MessageChecker.rb +1 -1
- data/test/ReferenceGenerator.rb +1 -1
- data/test/TestSuite/CSV-Reports/Leave.tjp +37 -0
- data/test/TestSuite/CSV-Reports/celltext.tjp +1 -1
- data/test/TestSuite/CSV-Reports/efficiency.tjp +20 -0
- data/test/TestSuite/CSV-Reports/headcount.tjp +31 -0
- data/test/TestSuite/CSV-Reports/refs/Leave.csv +5 -0
- data/test/TestSuite/CSV-Reports/refs/alert.csv +6 -0
- data/test/TestSuite/CSV-Reports/refs/celltext.csv +6 -0
- data/test/TestSuite/CSV-Reports/refs/efficiency.csv +5 -0
- data/test/TestSuite/CSV-Reports/refs/headcount.csv +4 -0
- data/test/TestSuite/CSV-Reports/refs/sortByTree.csv +6 -0
- data/test/TestSuite/CSV-Reports/refs/sortBy_duration.down.csv +6 -0
- data/test/TestSuite/CSV-Reports/refs/sortBy_effort.up.csv +6 -0
- data/test/TestSuite/CSV-Reports/refs/sortBy_plan.start.down.csv +6 -0
- data/test/TestSuite/CSV-Reports/refs/taskreport.csv +6 -0
- data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +14 -0
- data/test/TestSuite/CSV-Reports/resourcereport.tjp +1 -1
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks.tjp +1 -1
- data/test/TestSuite/CSV-Reports/sortByTree.tjp +1 -1
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down.tjp +1 -1
- data/test/TestSuite/CSV-Reports/taskreport.tjp +1 -1
- data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +1 -1
- data/test/TestSuite/Export-Reports/refs/AccountReport.tjp +1089 -0
- data/test/TestSuite/Export-Reports/refs/AlertLevels.tjp +24 -0
- data/test/TestSuite/Export-Reports/refs/Complete.tjp +5 -25
- data/test/TestSuite/Export-Reports/refs/navigator.tjp +58 -0
- data/test/TestSuite/Export-Reports/refs/template.tjp +142 -0
- data/test/TestSuite/Export-Reports/refs/textreport.tjp +19 -0
- data/test/TestSuite/ReportGenerator/Correct/Alerts.tjp +26 -7
- data/test/TestSuite/ReportGenerator/Correct/refs/Alerts-1.csv +177 -141
- data/test/TestSuite/ReportGenerator/Correct/refs/FTE-1.csv +1 -1
- data/test/TestSuite/Scheduler/Correct/Allocate.tjp +2 -2
- data/test/TestSuite/Scheduler/Correct/Shift2.tjp +4 -4
- data/test/TestSuite/Syntax/Correct/Account.tjp +23 -10
- data/test/TestSuite/Syntax/Correct/AccountReport.tjp +74 -0
- data/test/TestSuite/Syntax/Correct/AdoptedTasks.tjp +4 -0
- data/test/TestSuite/Syntax/Correct/AlertLevels.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/Celltext.tjp +3 -3
- data/test/TestSuite/Syntax/Correct/Complete.tjp +8 -5
- data/test/TestSuite/Syntax/Correct/Leave.tjp +37 -0
- data/test/TestSuite/Syntax/Correct/Reports.tjp +4 -4
- data/test/TestSuite/Syntax/Correct/Shift.tjp +4 -4
- data/test/TestSuite/Syntax/Correct/manual2example.rb +4 -3
- data/test/TestSuite/Syntax/Correct/navigator.tjp +31 -0
- data/test/TestSuite/Syntax/Correct/template.tjp +338 -0
- data/test/TestSuite/Syntax/Correct/textreport.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +12 -10
- data/test/TestSuite/Syntax/Errors/{adopt_duplicate_child.tjp → adopt_duplicate_child-1.tjp} +0 -0
- data/test/TestSuite/Syntax/Errors/{adopt_common_root.tjp → adopt_duplicate_child-2.tjp} +1 -1
- data/test/TestSuite/Syntax/Errors/{adopt_duplicate_parent.tjp → adopt_duplicate_child-3.tjp} +1 -1
- data/test/TestSuite/Syntax/Errors/adopt_self.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/alert_level_redef.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/alert_name_redef.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/too_few_alert_levels.tjp +5 -0
- data/test/TjpGen.rb +1 -1
- data/test/all.rb +1 -1
- data/test/test_AlgorithmDiff.rb +1 -1
- data/test/test_BatchProcessor.rb +23 -10
- data/test/test_CSV-Reports.rb +1 -1
- data/test/test_CSVFile.rb +1 -1
- data/test/test_CollisionDetector.rb +1 -1
- data/test/test_Export-Reports.rb +1 -1
- data/test/test_Journal.rb +42 -15
- data/test/test_Limits.rb +1 -1
- data/test/test_LogicalExpression.rb +1 -1
- data/test/test_MacroTable.rb +8 -3
- data/test/test_Project.rb +1 -1
- data/test/test_ProjectFileScanner.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_ReportGenerator.rb +1 -1
- data/test/test_RichText.rb +1 -1
- data/test/test_Scheduler.rb +1 -1
- data/test/test_ShiftAssignments.rb +1 -1
- data/test/test_SimpleQueryExpander.rb +1 -1
- data/test/test_Syntax.rb +1 -1
- data/test/test_TextFormatter.rb +1 -1
- data/test/test_TjTime.rb +1 -1
- data/test/test_TjpExample.rb +1 -1
- data/test/test_URLParameter.rb +1 -1
- data/test/test_UTF8String.rb +1 -1
- data/test/test_WorkingHours.rb +1 -1
- data/test/test_deep_copy.rb +1 -1
- metadata +318 -248
- data/test/TestSuite/Syntax/Errors/purge_no_list.tjp +0 -8
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = ProjectFileParser.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -237,20 +237,37 @@ class TaskJuggler
|
|
237
237
|
# type. +sourceFileInfo+ is a SourceFileInfo of the report definition. The
|
238
238
|
# method returns the newly created Report.
|
239
239
|
def newReport(id, name, type, sourceFileInfo)
|
240
|
+
# If there is no parent property and the report prefix is not empty, the
|
241
|
+
# reportprefix defines the parent property.
|
242
|
+
if @property.nil? && !@reportprefix.empty?
|
243
|
+
@property = @project.report(@reportprefix)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Report IDs must be unique. If an ID was provided, check if it exists
|
247
|
+
# already.
|
248
|
+
if id
|
249
|
+
# If we have a scope property, we need to prepend the ID of the scope
|
250
|
+
# property to the provided ID.
|
251
|
+
id = (@property ? @property.fullId + '.' : '') + @val[1]
|
252
|
+
|
253
|
+
if @project.report(id)
|
254
|
+
error('report_exists', "report #{id} has already been defined.",
|
255
|
+
sourceFileInfo, @property)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
240
259
|
@reportCounter += 1
|
241
|
-
if name != '.'
|
260
|
+
if name != '.' && name != ''
|
242
261
|
if @project.reportByName(name)
|
243
262
|
error('report_redefinition',
|
244
263
|
"A report with the name #{name} has already been defined.")
|
245
264
|
end
|
246
265
|
end
|
247
266
|
@property = Report.new(@project, id || "report#{@reportCounter}",
|
248
|
-
name,
|
267
|
+
name, @property)
|
249
268
|
@property.typeSpec = type
|
250
269
|
@property.sourceFileInfo = sourceFileInfo
|
251
|
-
@property.set('formats', [ :tjp ])
|
252
270
|
@property.inheritAttributes
|
253
|
-
@property
|
254
271
|
end
|
255
272
|
|
256
273
|
# If the @limitResources list is not empty, we have to create a Limits
|
@@ -394,6 +411,11 @@ class TaskJuggler
|
|
394
411
|
@cr.setLastSyntaxToken(idx)
|
395
412
|
end
|
396
413
|
|
414
|
+
# Specify the support level for the current pattern.
|
415
|
+
def level(level)
|
416
|
+
@cr.setSupportLevel(level)
|
417
|
+
end
|
418
|
+
|
397
419
|
# Add a reference to another pattern. This information is only used to
|
398
420
|
# generate the documentation for the patterns of this rule.
|
399
421
|
def also(seeAlso)
|
@@ -454,6 +476,18 @@ class TaskJuggler
|
|
454
476
|
@property = nil
|
455
477
|
end
|
456
478
|
|
479
|
+
# This method most be used instead of the += operator for all list
|
480
|
+
# attributes. += will always return an Array object. This will cause
|
481
|
+
# trouble with the list attributes that are not plain Arrays.
|
482
|
+
def appendScListAttribute(attrId, list)
|
483
|
+
list.each do |v|
|
484
|
+
@property[attrId, @scenarioIdx] << v
|
485
|
+
end
|
486
|
+
# The << operator does not set the 'provided' flag. Just do a self
|
487
|
+
# assignment to trigget the flag to get set.
|
488
|
+
@property[attrId, @scenarioIdx] = @property[attrId, @scenarioIdx]
|
489
|
+
end
|
490
|
+
|
457
491
|
end
|
458
492
|
|
459
493
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = ProjectFileScanner.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = PropertyList.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -11,6 +11,8 @@
|
|
11
11
|
# published by the Free Software Foundation.
|
12
12
|
#
|
13
13
|
|
14
|
+
require 'taskjuggler/PTNProxy'
|
15
|
+
|
14
16
|
class TaskJuggler
|
15
17
|
|
16
18
|
# The PropertyList is a utility class that can be used to hold a list of
|
@@ -60,6 +62,16 @@ class TaskJuggler
|
|
60
62
|
@items.method(func).call(*args, &block)
|
61
63
|
end
|
62
64
|
|
65
|
+
def includeAdopted
|
66
|
+
adopted = []
|
67
|
+
@items.each do |p|
|
68
|
+
p.adoptees.each do |ap|
|
69
|
+
adopted += includeAdoptedR(ap, p)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
append(adopted)
|
73
|
+
end
|
74
|
+
|
63
75
|
def to_ary
|
64
76
|
@items.dup
|
65
77
|
end
|
@@ -165,6 +177,18 @@ class TaskJuggler
|
|
165
177
|
|
166
178
|
private
|
167
179
|
|
180
|
+
def includeAdoptedR(property, parent)
|
181
|
+
# Create a proxy for the current PropertyTreeNode and add it to a list.
|
182
|
+
adopted = [ parentProxy = PTNProxy.new(property, parent) ]
|
183
|
+
|
184
|
+
# Add proxies for all children (adopted or not) and their children.
|
185
|
+
property.kids.each do |p|
|
186
|
+
adopted += includeAdoptedR(p, parentProxy)
|
187
|
+
end
|
188
|
+
|
189
|
+
adopted
|
190
|
+
end
|
191
|
+
|
168
192
|
# Append a new sorting level to the existing levels.
|
169
193
|
def addSortingCriteria(criteria, up, scIdx)
|
170
194
|
unless @propertySet.knownAttribute?(criteria) ||
|
@@ -214,7 +238,7 @@ class TaskJuggler
|
|
214
238
|
@items.sort! do |a, b|
|
215
239
|
res = 0
|
216
240
|
@sortingLevels.times do |i|
|
217
|
-
if @query
|
241
|
+
if @query && @sortingCriteria[i] != 'tree'
|
218
242
|
# In case we have a Query reference, we get the two values with this
|
219
243
|
# query.
|
220
244
|
@query.scenarioIdx = @scenarioIdx[i] < 0 ? nil : @scenarioIdx[i]
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = PropertySet.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -193,6 +193,12 @@ class TaskJuggler
|
|
193
193
|
property = prop
|
194
194
|
end
|
195
195
|
|
196
|
+
# Iterate over all properties and eliminate references to this the
|
197
|
+
# PropertyTreeNode to be removed.
|
198
|
+
@properties.each do |p|
|
199
|
+
p.removeReferences(p)
|
200
|
+
end
|
201
|
+
|
196
202
|
# Recursively remove all sub-nodes. The children list is modified during
|
197
203
|
# the call, so we can't use an iterator here.
|
198
204
|
until property.children.empty? do
|
@@ -205,6 +211,7 @@ class TaskJuggler
|
|
205
211
|
# Remove this node from the child list of the parent node.
|
206
212
|
property.parent.children.delete(property) if property.parent
|
207
213
|
|
214
|
+
|
208
215
|
property
|
209
216
|
end
|
210
217
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = PropertyTreeNode.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -135,34 +135,30 @@ class TaskJuggler
|
|
135
135
|
self
|
136
136
|
end
|
137
137
|
|
138
|
+
# We often use PTNProxy objects to represent PropertyTreeNode objects. The
|
139
|
+
# proxy usually does a good job acting like a PropertyTreeNode. But in
|
140
|
+
# some situations, we want to make sure to operate on the PropertyTreeNode
|
141
|
+
# and not the PTNProxy. Both classes provide a ptn() method that always
|
142
|
+
# return the PropertyTreeNode.
|
143
|
+
def ptn
|
144
|
+
self
|
145
|
+
end
|
146
|
+
|
138
147
|
# Adopt _property_ as a step child. Also register the new relationship
|
139
148
|
# with the child.
|
140
149
|
def adopt(property)
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
# ancestors.
|
145
|
-
if root == property.root
|
146
|
-
error('adopt_common_root',
|
147
|
-
"The adoptee #{property.fullId} and the parent #{fullId} " +
|
148
|
-
"may not share common ancestors.")
|
150
|
+
# A property cannot adopt itself.
|
151
|
+
if self == property
|
152
|
+
error('adopt_self', 'A property cannot adopt itself')
|
149
153
|
end
|
150
154
|
|
151
|
-
#
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
if adoptee.ancestors.include?(property)
|
155
|
+
# A top level task must never contain the same leaf task more then once!
|
156
|
+
allOfRoot = root.all
|
157
|
+
property.allLeaves.each do |adoptee|
|
158
|
+
if allOfRoot.include?(adoptee)
|
156
159
|
error('adopt_duplicate_child',
|
157
|
-
"The
|
158
|
-
"
|
159
|
-
end
|
160
|
-
# Check if the already adopted nodes are an ancestor of the to be
|
161
|
-
# adopted node.
|
162
|
-
if property.ancestors.include?(adoptee)
|
163
|
-
error('adopt_duplicate_parent',
|
164
|
-
"The parent #{adoptee.fullId} of #{property.fullId} " +
|
165
|
-
"has already been adopted by #{fullId}.")
|
160
|
+
"The task '#{adoptee.fullId}' has already been adopted by " +
|
161
|
+
"property '#{root.fullId}' or any of its sub-properties.")
|
166
162
|
end
|
167
163
|
end
|
168
164
|
|
@@ -177,7 +173,6 @@ class TaskJuggler
|
|
177
173
|
return if @stepParents.include?(property)
|
178
174
|
|
179
175
|
@stepParents << property
|
180
|
-
property.adopt(self)
|
181
176
|
end
|
182
177
|
|
183
178
|
# Return a list of all children including adopted kids.
|
@@ -202,6 +197,13 @@ class TaskJuggler
|
|
202
197
|
@attributes, @scenarioAttributes = backup
|
203
198
|
end
|
204
199
|
|
200
|
+
# Remove any references in the stored data that references the _property_.
|
201
|
+
def removeReferences(property)
|
202
|
+
@children.delete(property)
|
203
|
+
@adoptees.delete(property)
|
204
|
+
@stepParents.delete(property)
|
205
|
+
end
|
206
|
+
|
205
207
|
# Return the index of the child _node_.
|
206
208
|
def levelSeqNo(node)
|
207
209
|
@children.index(node) + 1
|
@@ -258,7 +260,7 @@ class TaskJuggler
|
|
258
260
|
# Returns a list of this node and all transient sub nodes.
|
259
261
|
def all
|
260
262
|
res = [ self ]
|
261
|
-
|
263
|
+
kids.each do |c|
|
262
264
|
res = res.concat(c.all)
|
263
265
|
end
|
264
266
|
res
|
@@ -266,11 +268,11 @@ class TaskJuggler
|
|
266
268
|
|
267
269
|
# Return a list of all leaf nodes of this node.
|
268
270
|
def allLeaves(withoutSelf = false)
|
271
|
+
res = []
|
269
272
|
if leaf?
|
270
|
-
res
|
273
|
+
res << self unless withoutSelf
|
271
274
|
else
|
272
|
-
|
273
|
-
@children.each do |c|
|
275
|
+
kids.each do |c|
|
274
276
|
res += c.allLeaves
|
275
277
|
end
|
276
278
|
end
|
@@ -553,8 +555,10 @@ class TaskJuggler
|
|
553
555
|
journal = @project['journal']
|
554
556
|
query.sortable = query.numerical = alert =
|
555
557
|
journal.alertLevel(query.end, self, query.hideJournalEntry)
|
556
|
-
|
557
|
-
|
558
|
+
alertLevel = @project['alertLevels'][alert]
|
559
|
+
query.string = alertLevel.name
|
560
|
+
rText = "<fcol:#{alertLevel.color}><nowiki>#{alertLevel.name}" +
|
561
|
+
"</nowiki></fcol>"
|
558
562
|
unless (rti = RichText.new(rText, RTFHandlers.create(@project),
|
559
563
|
@project.messageHandler).
|
560
564
|
generateIntermediateFormat)
|
@@ -645,8 +649,8 @@ class TaskJuggler
|
|
645
649
|
# provided by the class *Scenario classes. In case we can't find a function
|
646
650
|
# called for the base class we try to find it in corresponding *Scenario
|
647
651
|
# class.
|
648
|
-
def method_missing(func, scenarioIdx, *args)
|
649
|
-
@data[scenarioIdx].
|
652
|
+
def method_missing(func, scenarioIdx, *args, &block)
|
653
|
+
@data[scenarioIdx].send(func, *args, &block)
|
650
654
|
end
|
651
655
|
|
652
656
|
def error(id, text)
|
data/lib/taskjuggler/Query.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = Query.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = RealFormat.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -63,8 +63,10 @@ class TaskJuggler
|
|
63
63
|
intNumber = '0' * (@fractionDigits - intNumber.length + 1) + intNumber
|
64
64
|
end
|
65
65
|
intPart = intNumber[0..-(@fractionDigits + 1)]
|
66
|
+
# Determinate the fractional part
|
66
67
|
fracPart =
|
67
|
-
@fractionDigits > 0 ?
|
68
|
+
@fractionDigits > 0 ? @fractionSeparator +
|
69
|
+
intNumber[-(@fractionDigits)..-1] : ''
|
68
70
|
|
69
71
|
if @thousandsSeparator.empty?
|
70
72
|
out = intPart
|
data/lib/taskjuggler/Resource.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = Resource.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -37,8 +37,8 @@ class TaskJuggler
|
|
37
37
|
# provided by the class ResourceScenario. In case we can't find a
|
38
38
|
# function called for the Resource class we try to find it in
|
39
39
|
# ResourceScenario.
|
40
|
-
def method_missing(func, scenarioIdx, *args)
|
41
|
-
@data[scenarioIdx].method(func).call(*args)
|
40
|
+
def method_missing(func, scenarioIdx, *args, &block)
|
41
|
+
@data[scenarioIdx].method(func).call(*args, &block)
|
42
42
|
end
|
43
43
|
|
44
44
|
def query_dashboard(query)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = ResourceScenario.rb -- The TaskJuggler III Project Management Software
|
5
5
|
#
|
6
|
-
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
7
|
# by Chris Schlaeger <chris@linux.com>
|
8
8
|
#
|
9
9
|
# This program is free software; you can redistribute it and/or modify
|
@@ -24,13 +24,18 @@ class TaskJuggler
|
|
24
24
|
# nil: Value has not been determined yet.
|
25
25
|
# Task: A reference to a Task object
|
26
26
|
# Bit 0: Reserved
|
27
|
-
# Bit 1: 0: Work time
|
28
|
-
# 1:
|
29
|
-
# Bit 2 - 5: 0: No
|
30
|
-
# 1:
|
31
|
-
# 2
|
32
|
-
#
|
33
|
-
#
|
27
|
+
# Bit 1: 0: Work time (as defined by working hours)
|
28
|
+
# 1: No work time (as defined by working hours)
|
29
|
+
# Bit 2 - 5: 0: No holiday or leave time
|
30
|
+
# 1: Public holiday (holiday)
|
31
|
+
# 2: Annual leave
|
32
|
+
# 3: Special leave
|
33
|
+
# 4: Sick leave
|
34
|
+
# 5: unpaid leave
|
35
|
+
# 6: blocked for other projects
|
36
|
+
# 7 - 15: Reserved
|
37
|
+
# Bit 6 - 7: Reserved
|
38
|
+
# Bit 8: 0: No global override
|
34
39
|
# 1: Override global setting
|
35
40
|
# The scoreboard is only created when needed to save memory for projects
|
36
41
|
# which read-in the coporate employee database but only need a small
|
@@ -49,9 +54,9 @@ class TaskJuggler
|
|
49
54
|
# Attributed are only really created when they are accessed the first
|
50
55
|
# time. So make sure some needed attributes really exist so we don't
|
51
56
|
# have to check for existance each time we access them.
|
52
|
-
%w( alloctdeffort criticalness directreports duties efficiency
|
57
|
+
%w( alloctdeffort chargeset criticalness directreports duties efficiency
|
53
58
|
effort limits managers rate reports shifts
|
54
|
-
|
59
|
+
leaves leaveallowances workinghours ).each do |attr|
|
55
60
|
@property[attr, @scenarioIdx]
|
56
61
|
end
|
57
62
|
|
@@ -241,6 +246,26 @@ class TaskJuggler
|
|
241
246
|
book(sbIdx, booking.task, true)
|
242
247
|
end
|
243
248
|
|
249
|
+
# Compute the annual leave days within the period specified by the
|
250
|
+
# _query_. The result is in days.
|
251
|
+
def query_annualleave(query)
|
252
|
+
query.sortable = query.numerical = val =
|
253
|
+
getLeave(query.startIdx, query.endIdx, :annual)
|
254
|
+
query.string = query.scaleLoad(val)
|
255
|
+
end
|
256
|
+
|
257
|
+
def query_annualleavebalance(query)
|
258
|
+
if @property.leaf?
|
259
|
+
leave = getLeave(query.startIdx, query.endIdx, :annual)
|
260
|
+
allowanceSlots = @leaveallowances.balance(:annual, query.start,
|
261
|
+
query.end)
|
262
|
+
allowance = @project.slotsToDays(allowanceSlots)
|
263
|
+
query.sortable = query.numerical = val = allowance - leave
|
264
|
+
query.string = query.scaleLoad(val)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
|
244
269
|
# Compute the cost generated by this Resource for a given Account during a
|
245
270
|
# given interval. If a Task is provided as scopeProperty only the turnover
|
246
271
|
# directly assiciated with the Task is taken into account.
|
@@ -248,7 +273,7 @@ class TaskJuggler
|
|
248
273
|
if query.costAccount
|
249
274
|
query.sortable = query.numerical = cost =
|
250
275
|
turnover(query.startIdx, query.endIdx, query.costAccount,
|
251
|
-
query.scopeProperty)
|
276
|
+
query.scopeProperty, true)
|
252
277
|
query.string = query.currencyFormat.format(cost)
|
253
278
|
else
|
254
279
|
query.string = 'No \'balance\' defined!'
|
@@ -292,13 +317,31 @@ class TaskJuggler
|
|
292
317
|
# probably don't need to compute this for every resource.
|
293
318
|
globalWorkSlots = @project.getWorkSlots(query.startIdx, query.endIdx)
|
294
319
|
workSlots = getWorkSlots(query.startIdx, query.endIdx)
|
295
|
-
|
320
|
+
if globalWorkSlots > 0
|
321
|
+
fte = (workSlots.to_f / globalWorkSlots) * @efficiency
|
322
|
+
end
|
296
323
|
end
|
297
324
|
|
298
325
|
query.sortable = query.numerical = fte
|
299
326
|
query.string = query.numberFormat.format(fte)
|
300
327
|
end
|
301
328
|
|
329
|
+
# The headcount of the resource or group.
|
330
|
+
def query_headcount(query)
|
331
|
+
headcount = 0
|
332
|
+
if @property.container?
|
333
|
+
@property.kids.each do |resource|
|
334
|
+
resource.query_headcount(@scenarioIdx, query)
|
335
|
+
headcount += query.to_num
|
336
|
+
end
|
337
|
+
else
|
338
|
+
headcount += @efficiency.round
|
339
|
+
end
|
340
|
+
|
341
|
+
query.sortable = query.numerical = headcount
|
342
|
+
query.string = query.numberFormat.format(headcount)
|
343
|
+
end
|
344
|
+
|
302
345
|
# Get the rate of the resource.
|
303
346
|
def query_rate(query)
|
304
347
|
query.sortable = query.numerical = r = rate
|
@@ -319,14 +362,77 @@ class TaskJuggler
|
|
319
362
|
end
|
320
363
|
end
|
321
364
|
|
322
|
-
#
|
365
|
+
# Compute the sick leave days within the period specified by the
|
366
|
+
# _query_. The result is in days.
|
367
|
+
def query_sickleave(query)
|
368
|
+
query.sortable = query.numerical = val =
|
369
|
+
getLeave(query.startIdx, query.endIdx, :sick)
|
370
|
+
query.string = query.scaleLoad(val)
|
371
|
+
end
|
372
|
+
|
373
|
+
# Compute the special leave days within the period specified by the
|
374
|
+
# _query_. The result is in days.
|
375
|
+
def query_specialleave(query)
|
376
|
+
query.sortable = query.numerical = val =
|
377
|
+
getLeave(query.startIdx, query.endIdx, :special)
|
378
|
+
query.string = query.scaleLoad(val)
|
379
|
+
end
|
380
|
+
|
381
|
+
# The work time of the Resource that was blocked by leaves during the
|
323
382
|
# specified TimeInterval. The result is in working days (effort).
|
324
|
-
def
|
383
|
+
def query_timeoffdays(query)
|
325
384
|
query.sortable = query.numerical = time =
|
326
|
-
|
385
|
+
getTimeOffDays(query.startIdx, query.endIdx)
|
327
386
|
query.string = query.scaleLoad(time)
|
328
387
|
end
|
329
388
|
|
389
|
+
# Compute the unpaid leave days within the period specified by the
|
390
|
+
# _query_. The result is in days.
|
391
|
+
def query_unpaidleave(query)
|
392
|
+
query.sortable = query.numerical = val =
|
393
|
+
getLeave(query.startIdx, query.endIdx, :unpaid)
|
394
|
+
query.string = query.scaleLoad(val)
|
395
|
+
end
|
396
|
+
|
397
|
+
# A generic tree iterator that recursively accumulates the result of the
|
398
|
+
# block for each leaf object.
|
399
|
+
def treeSum(startIdx, endIdx, *args, &block)
|
400
|
+
cacheTag = "#{self.class}.#{caller[0][/`.*'/][1..-2]}"
|
401
|
+
treeSumR(cacheTag, startIdx, endIdx, *args, &block)
|
402
|
+
end
|
403
|
+
|
404
|
+
# Recursing method for treeSum.
|
405
|
+
def treeSumR(cacheTag, startIdx, endIdx, *args, &block)
|
406
|
+
# Check if the value to be computed is already in the data cache. If so,
|
407
|
+
# return it. Otherwise we have to compute it first and then store it in
|
408
|
+
# the cache. We use the signature of the method that called treeSum()
|
409
|
+
# and its arguments together with 'self' as index to the cache.
|
410
|
+
@dCache.cached(self, cacheTag, startIdx, endIdx, *args) do
|
411
|
+
if @property.container?
|
412
|
+
sum = 0.0
|
413
|
+
# Iterate over all the kids and accumulate the result of the
|
414
|
+
# recursively called method.
|
415
|
+
@property.kids.each do |resource|
|
416
|
+
sum += resource.treeSumR(@scenarioIdx, cacheTag, startIdx, endIdx,
|
417
|
+
*args, &block)
|
418
|
+
end
|
419
|
+
sum
|
420
|
+
else
|
421
|
+
instance_eval(&block)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
# Returns the number of leave days for the period described by _startIdx_
|
427
|
+
# and _endIdx_ for the given _type_ of leave.
|
428
|
+
def getLeave(startIdx, endIdx, type)
|
429
|
+
treeSum(startIdx, endIdx, type) do
|
430
|
+
@project.convertToDailyLoad(@project['scheduleGranularity'] *
|
431
|
+
getLeaveSlots(startIdx, endIdx, type))
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
|
330
436
|
# Returns the work of the resource (and its children) weighted by their
|
331
437
|
# efficiency.
|
332
438
|
def getEffectiveWork(startIdx, endIdx, task = nil)
|
@@ -337,10 +443,6 @@ class TaskJuggler
|
|
337
443
|
# The unique key we use to address the result in the cache.
|
338
444
|
@dCache.cached(self, :ResourceScenarioEffectiveWork, startIdx, endIdx,
|
339
445
|
task) do
|
340
|
-
# Convert the interval dates to indexes if needed.
|
341
|
-
startIdx = @project.dateToIdx(startIdx) if startIdx.is_a?(TjTime)
|
342
|
-
endIdx = @project.dateToIdx(endIdx) if endIdx.is_a?(TjTime)
|
343
|
-
|
344
446
|
work = 0.0
|
345
447
|
if @property.container?
|
346
448
|
@property.kids.each do |resource|
|
@@ -360,96 +462,66 @@ class TaskJuggler
|
|
360
462
|
|
361
463
|
# Returns the allocated accumulated time of this resource and its children.
|
362
464
|
def getAllocatedTime(startIdx, endIdx, task = nil)
|
363
|
-
|
364
|
-
startIdx = @project.dateToIdx(startIdx) if startIdx.is_a?(TjTime)
|
365
|
-
endIdx = @project.dateToIdx(endIdx) if endIdx.is_a?(TjTime)
|
366
|
-
|
367
|
-
time = 0
|
368
|
-
if @property.container?
|
369
|
-
@property.kids.each do |resource|
|
370
|
-
time += resource.getAllocatedTime(@scenarioIdx, startIdx, endIdx, task)
|
371
|
-
end
|
372
|
-
else
|
465
|
+
treeSum(startIdx, endIdx, task) do
|
373
466
|
return 0 if @scoreboard.nil?
|
374
467
|
|
375
|
-
|
468
|
+
@project.convertToDailyLoad(@project['scheduleGranularity'] *
|
376
469
|
getAllocatedSlots(startIdx, endIdx, task))
|
377
470
|
end
|
378
|
-
time
|
379
471
|
end
|
380
472
|
|
381
473
|
# Return the unallocated work time (in seconds) of the resource and its
|
382
474
|
# children.
|
383
475
|
def getEffectiveFreeTime(startIdx, endIdx)
|
384
|
-
|
385
|
-
|
386
|
-
endIdx = @project.dateToIdx(endIdx) if endIdx.is_a?(TjTime)
|
387
|
-
|
388
|
-
freeTime = 0
|
389
|
-
if @property.container?
|
390
|
-
@property.kids.each do |resource|
|
391
|
-
freeTime += resource.getEffectiveFreeTime(@scenarioIdx, startIdx,
|
392
|
-
endIdx)
|
393
|
-
end
|
394
|
-
else
|
395
|
-
freeTime = getFreeSlots(startIdx, endIdx) *
|
396
|
-
@project['scheduleGranularity']
|
476
|
+
treeSum(startIdx, endIdx) do
|
477
|
+
getFreeSlots(startIdx, endIdx) * @project['scheduleGranularity']
|
397
478
|
end
|
398
|
-
freeTime
|
399
479
|
end
|
400
480
|
|
401
481
|
# Return the unallocated work of the resource and its children weighted by
|
402
482
|
# their efficiency.
|
403
483
|
def getEffectiveFreeWork(startIdx, endIdx)
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
work = 0.0
|
409
|
-
if @property.container?
|
410
|
-
@property.kids.each do |resource|
|
411
|
-
work += resource.getEffectiveFreeWork(@scenarioIdx, startIdx, endIdx)
|
412
|
-
end
|
413
|
-
else
|
414
|
-
work = @project.convertToDailyLoad(
|
415
|
-
getFreeSlots(startIdx, endIdx) *
|
416
|
-
@project['scheduleGranularity']) * @efficiency
|
484
|
+
treeSum(startIdx, endIdx) do
|
485
|
+
@project.convertToDailyLoad(getFreeSlots(startIdx, endIdx) *
|
486
|
+
@project['scheduleGranularity']) *
|
487
|
+
@efficiency
|
417
488
|
end
|
418
|
-
work
|
419
489
|
end
|
420
490
|
|
421
|
-
# Return the number of working days that are blocked by
|
422
|
-
def
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
vacationDays = 0.0
|
428
|
-
if @property.container?
|
429
|
-
@property.kids.each do |resource|
|
430
|
-
vacationDays += resource.getVacationDays(@scenarioIdx,
|
431
|
-
startIdx, endIdx)
|
432
|
-
end
|
433
|
-
else
|
434
|
-
initScoreboard if @scoreboard.nil?
|
435
|
-
|
436
|
-
vacationDays = @project.convertToDailyLoad(
|
437
|
-
getVacationSlots(startIdx, endIdx) *
|
438
|
-
@project['scheduleGranularity']) * @efficiency
|
491
|
+
# Return the number of working days that are blocked by leaves.
|
492
|
+
def getTimeOffDays(startIdx, endIdx)
|
493
|
+
treeSum(startIdx, endIdx) do
|
494
|
+
@project.convertToDailyLoad(getTimeOffSlots(startIdx, endIdx) *
|
495
|
+
@project['scheduleGranularity']) *
|
496
|
+
@efficiency
|
439
497
|
end
|
440
|
-
vacationDays
|
441
498
|
end
|
442
499
|
|
443
|
-
def turnover(startIdx, endIdx, account, task = nil)
|
500
|
+
def turnover(startIdx, endIdx, account, task = nil, includeKids = false)
|
444
501
|
amount = 0.0
|
445
|
-
if @property.container?
|
502
|
+
if @property.container? && includeKids
|
446
503
|
@property.kids.each do |child|
|
447
|
-
amount += child.turnover(@scenarioIdx, startIdx, endIdx, account,
|
504
|
+
amount += child.turnover(@scenarioIdx, startIdx, endIdx, account,
|
505
|
+
task)
|
448
506
|
end
|
449
507
|
else
|
450
|
-
|
451
|
-
|
508
|
+
if task
|
509
|
+
# If we have a know task, we only include the amount that is
|
510
|
+
# specific to this resource, this task and the chargeset of the
|
511
|
+
# task.
|
512
|
+
amount += task.turnover(@scenarioIdx, startIdx, endIdx, account,
|
452
513
|
@property)
|
514
|
+
elsif !@chargeset.empty?
|
515
|
+
# If no tasks was provided, we include the amount of this resource,
|
516
|
+
# weighted by the charset of this resource.
|
517
|
+
totalResourceCost = cost(startIdx, endIdx)
|
518
|
+
@chargeset.each do |set|
|
519
|
+
set.each do |accnt, share|
|
520
|
+
if share > 0.0 && (accnt == account || accnt.isChildOf?(account))
|
521
|
+
amount += totalResourceCost * share
|
522
|
+
end
|
523
|
+
end
|
524
|
+
end
|
453
525
|
end
|
454
526
|
end
|
455
527
|
|
@@ -545,7 +617,7 @@ class TaskJuggler
|
|
545
617
|
end
|
546
618
|
|
547
619
|
# Return a list of scoreboard intervals that are at least _minDuration_ long
|
548
|
-
# and contain only off-duty and
|
620
|
+
# and contain only off-duty and leave slots. The result is an Array of
|
549
621
|
# [ start, end ] TjTime values.
|
550
622
|
def collectTimeOffIntervals(iv, minDuration)
|
551
623
|
# Time-off intervals are only useful for leaf resources. Group resources
|
@@ -581,107 +653,114 @@ class TaskJuggler
|
|
581
653
|
# Count the number of slots betweend the _startIdx_ and _endIdx_ that can
|
582
654
|
# be used for work
|
583
655
|
def getWorkSlots(startIdx, endIdx)
|
584
|
-
|
585
|
-
|
586
|
-
initScoreboard unless @scoreboard
|
587
|
-
|
588
|
-
workSlots = 0
|
589
|
-
startIdx.upto(endIdx - 1) do |idx|
|
590
|
-
slot = @scoreboard[idx]
|
656
|
+
countSlots(startIdx, endIdx) do |val|
|
591
657
|
# We count free slots and assigned slots.
|
592
|
-
|
658
|
+
val.nil? || val.is_a?(Task)
|
593
659
|
end
|
660
|
+
end
|
594
661
|
|
595
|
-
|
662
|
+
# Count the number of slots that are work time slots but marked as annual
|
663
|
+
# leave.
|
664
|
+
def getLeaveSlots(startIdx, endIdx, type)
|
665
|
+
countSlots(startIdx, endIdx) do |val|
|
666
|
+
val.is_a?(Fixnum) && (val & 0x3E) == (Leave::Types[type] << 2)
|
667
|
+
end
|
596
668
|
end
|
597
669
|
|
598
670
|
# Count the free slots between the start and end index.
|
599
671
|
def getFreeSlots(startIdx, endIdx)
|
600
|
-
|
601
|
-
|
602
|
-
initScoreboard unless @scoreboard
|
603
|
-
|
604
|
-
freeSlots = 0
|
605
|
-
startIdx.upto(endIdx - 1) do |idx|
|
606
|
-
freeSlots += 1 if @scoreboard[idx].nil?
|
672
|
+
countSlots(startIdx, endIdx) do |val|
|
673
|
+
val.nil?
|
607
674
|
end
|
608
|
-
|
609
|
-
freeSlots
|
610
675
|
end
|
611
676
|
|
612
677
|
# Count the regular work time slots between the start and end index that
|
613
|
-
# have been blocked by
|
614
|
-
def
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
vacationSlots = 0
|
620
|
-
startIdx.upto(endIdx - 1) do |idx|
|
621
|
-
val = @scoreboard[idx]
|
622
|
-
# Bit 1 needs to be unset and the vacation bits must not be 0.
|
623
|
-
vacationSlots += 1 if val.is_a?(Fixnum) && (val & 0x2) == 0 &&
|
624
|
-
(val & 0x3C) != 0
|
678
|
+
# have been blocked by leaves.
|
679
|
+
def getTimeOffSlots(startIdx, endIdx)
|
680
|
+
countSlots(startIdx, endIdx) do |val|
|
681
|
+
# Bit 1 needs to be unset and the leave bits must not be 0.
|
682
|
+
val.is_a?(Fixnum) && (val & 0x2) == 0 && (val & 0x3C) != 0
|
625
683
|
end
|
626
|
-
vacationSlots
|
627
684
|
end
|
628
685
|
|
629
686
|
private
|
630
687
|
|
631
688
|
def initScoreboard
|
632
|
-
# Create scoreboard and mark all slots as
|
689
|
+
# Create scoreboard and mark all slots as non-working-time.
|
633
690
|
@scoreboard = Scoreboard.new(@project['start'], @project['end'],
|
634
691
|
@project['scheduleGranularity'], 2)
|
635
692
|
|
636
|
-
# We'll need this frequently and can savely cache it here.
|
637
|
-
@shifts = @shifts
|
638
|
-
@workinghours = @workinghours
|
639
|
-
|
640
693
|
# Change all work time slots to nil (available) again.
|
641
694
|
@project.scoreboardSize.times do |i|
|
642
695
|
@scoreboard[i] = nil if onShift?(i)
|
643
696
|
end
|
644
697
|
|
645
|
-
# Mark all
|
646
|
-
@
|
647
|
-
startIdx = @scoreboard.dateToIdx(
|
648
|
-
endIdx = @scoreboard.dateToIdx(
|
698
|
+
# Mark all global leave slots as such
|
699
|
+
@project['leaves'].each do |leave|
|
700
|
+
startIdx = @scoreboard.dateToIdx(leave.interval.start)
|
701
|
+
endIdx = @scoreboard.dateToIdx(leave.interval.end)
|
649
702
|
startIdx.upto(endIdx - 1) do |i|
|
650
|
-
|
651
|
-
|
703
|
+
sb = @scoreboard[i]
|
704
|
+
# We preseve the work-time bit (#1).
|
705
|
+
@scoreboard[i] = (sb.nil? ? 0 : 2) | (leave.typeIdx << 2)
|
652
706
|
end
|
653
707
|
end
|
654
708
|
|
655
|
-
# Mark all
|
656
|
-
@
|
657
|
-
startIdx = @scoreboard.dateToIdx(
|
658
|
-
endIdx = @scoreboard.dateToIdx(
|
709
|
+
# Mark all resource specific leave slots as such
|
710
|
+
@leaves.each do |leave|
|
711
|
+
startIdx = @scoreboard.dateToIdx(leave.interval.start)
|
712
|
+
endIdx = @scoreboard.dateToIdx(leave.interval.end)
|
659
713
|
startIdx.upto(endIdx - 1) do |i|
|
660
|
-
|
661
|
-
|
662
|
-
|
714
|
+
if (sb = @scoreboard[i])
|
715
|
+
# The slot is already marked as non-working slot. We override the
|
716
|
+
# leave type if the new type is larger than the old one.
|
717
|
+
leaveIdx = (sb & 0x3C) >> 2
|
718
|
+
if leave.typeIdx > leaveIdx
|
719
|
+
# The work-time bit (#1) is preserved.
|
720
|
+
@scoreboard[i] = (sb & 0x2) | (leave.typeIdx << 2)
|
721
|
+
end
|
722
|
+
else
|
723
|
+
# This marks a working time slot as a leave slot. Since bit 1 is
|
724
|
+
# not set, we still know that this could be a working slot.
|
725
|
+
@scoreboard[i] = leave.typeIdx << 2
|
726
|
+
end
|
663
727
|
end
|
664
728
|
end
|
665
729
|
|
666
730
|
unless @shifts.nil?
|
667
|
-
# Mark the
|
731
|
+
# Mark the leaves from all the shifts the resource is assigned to.
|
668
732
|
@project.scoreboardSize.times do |i|
|
669
733
|
v = @shifts.getSbSlot(i)
|
670
|
-
#
|
671
|
-
|
672
|
-
|
734
|
+
# Make sure a shift is actually assigned.
|
735
|
+
next unless v
|
736
|
+
|
673
737
|
if (v & (1 << 8)) != 0
|
738
|
+
# Check if the leave replacement bit (#8) is set. In that case we
|
739
|
+
# copy the whole interval over to the resource scoreboard
|
740
|
+
# overriding any global leaves.
|
674
741
|
@scoreboard[i] = (v & 0x3E == 0) ? nil : (v & 0x3D)
|
675
|
-
elsif ((
|
742
|
+
elsif ((sb = @scoreboard[i]).nil? || ((sb & 0x3C) < (v & 0x3C))) &&
|
676
743
|
(v & 0x3C) != 0
|
677
|
-
#
|
678
|
-
#
|
744
|
+
# In merge mode, we only add the shift leaves with higher type
|
745
|
+
# index or unassigned slots.
|
679
746
|
@scoreboard[i] = v & 0x3E
|
680
747
|
end
|
681
748
|
end
|
682
749
|
end
|
683
750
|
end
|
684
751
|
|
752
|
+
def countSlots(startIdx, endIdx)
|
753
|
+
return 0 if startIdx >= endIdx
|
754
|
+
|
755
|
+
initScoreboard unless @scoreboard
|
756
|
+
|
757
|
+
slots = 0
|
758
|
+
startIdx.upto(endIdx - 1) do |idx|
|
759
|
+
slots += 1 if yield(@scoreboard[idx])
|
760
|
+
end
|
761
|
+
slots
|
762
|
+
end
|
763
|
+
|
685
764
|
# Limit the _startIdx_ and _endIdx_ to the actually assigned interval.
|
686
765
|
# If _task_ is provided, fit it for the bookings of this particular task.
|
687
766
|
def fitIndicies(startIdx, endIdx, task = nil)
|