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
|
# = StatusSheetReport.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
|
@@ -164,7 +164,7 @@ class TaskJuggler
|
|
164
164
|
responsibility.journalEntries.each do |entry|
|
165
165
|
task = entry.property
|
166
166
|
@file << " task #{task.fullId} {\n"
|
167
|
-
alertLevel = @project['alertLevels'][entry.alertLevel]
|
167
|
+
alertLevel = @project['alertLevels'][entry.alertLevel].id
|
168
168
|
@file << " # status #{alertLevel} \"#{entry.headline}\" {\n"
|
169
169
|
@file << " # # Date: #{entry.date}\n"
|
170
170
|
if (tsRecord = entry.timeSheetRecord)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = TableReport.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
|
@@ -15,6 +15,7 @@ require 'taskjuggler/reports/ReportBase'
|
|
15
15
|
require 'taskjuggler/reports/GanttChart'
|
16
16
|
require 'taskjuggler/reports/ReportTableLegend'
|
17
17
|
require 'taskjuggler/reports/ColumnTable'
|
18
|
+
require 'taskjuggler/reports/TableReportColumn'
|
18
19
|
require 'taskjuggler/Query'
|
19
20
|
|
20
21
|
class TaskJuggler
|
@@ -27,38 +28,46 @@ class TaskJuggler
|
|
27
28
|
attr_reader :legend
|
28
29
|
|
29
30
|
@@propertiesById = {
|
30
|
-
# ID
|
31
|
-
'
|
32
|
-
'
|
33
|
-
'
|
34
|
-
'
|
35
|
-
'
|
36
|
-
'
|
37
|
-
'
|
38
|
-
'
|
39
|
-
'
|
40
|
-
'
|
41
|
-
'
|
42
|
-
'
|
43
|
-
'
|
44
|
-
'
|
45
|
-
'
|
46
|
-
'
|
47
|
-
'
|
48
|
-
'
|
49
|
-
'
|
50
|
-
'
|
51
|
-
'
|
52
|
-
'
|
53
|
-
'
|
54
|
-
'
|
55
|
-
'
|
56
|
-
'
|
57
|
-
'
|
58
|
-
'
|
59
|
-
'
|
60
|
-
'
|
61
|
-
'
|
31
|
+
# ID Header Indent Align Scen Spec.
|
32
|
+
'annualleave' => [ 'Annual Leave', true, :right, true ],
|
33
|
+
'annualleavebalance'=> [ 'Annual Leave Balance', false, :right, true ],
|
34
|
+
'alert' => [ 'Alert', true, :left, false ],
|
35
|
+
'alertmessages' => [ 'Alert Messages', false, :left, false ],
|
36
|
+
'alertsummaries' => [ 'Alert Summaries', false, :left, false ],
|
37
|
+
'alerttrend' => [ 'Alert Trend', false, :left, false ],
|
38
|
+
'balance' => [ 'Balance', true, :right, true ],
|
39
|
+
'bsi' => [ 'BSI', false, :left, false ],
|
40
|
+
'complete' => [ 'Completion', false, :right, true ],
|
41
|
+
'cost' => [ 'Cost', true, :right, true ],
|
42
|
+
'duration' => [ 'Duration', true, :right, true ],
|
43
|
+
'effort' => [ 'Effort', true, :right, true ],
|
44
|
+
'effortdone' => [ 'Effort Done', true, :right, true ],
|
45
|
+
'effortleft' => [ 'Effort Left', true, :right, true ],
|
46
|
+
'freetime' => [ 'Free Time', true, :right, true ],
|
47
|
+
'freework' => [ 'Free Work', true, :right, true ],
|
48
|
+
'followers' => [ 'Followers', false, :left, true ],
|
49
|
+
'fte' => [ 'FTE', true, :right, true ],
|
50
|
+
'headcount' => [ 'Headcount', true, :right, true ],
|
51
|
+
'id' => [ 'Id', false, :left, false ],
|
52
|
+
'inputs' => [ 'Inputs', false, :left, true ],
|
53
|
+
'journal' => [ 'Journal', false, :left, false ],
|
54
|
+
'journal_sub' => [ 'Journal', false, :left, false ],
|
55
|
+
'journalmessages' => [ 'Journal Messages', false, :left, false ],
|
56
|
+
'journalsummaries' => [ 'Journal Summaries', false, :left, false ],
|
57
|
+
'line' => [ 'Line No.', false, :right, false ],
|
58
|
+
'name' => [ 'Name', true, :left, false ],
|
59
|
+
'no' => [ 'No.', false, :right, false ],
|
60
|
+
'precursors' => [ 'Precursors', false, :left, true ],
|
61
|
+
'rate' => [ 'Rate', true, :right, true ],
|
62
|
+
'resources' => [ 'Resources', false, :left, true ],
|
63
|
+
'responsible' => [ 'Responsible', false, :left, true ],
|
64
|
+
'revenue' => [ 'Revenue', true, :right, true ],
|
65
|
+
'scenario' => [ 'Scenario', false, :left, true ],
|
66
|
+
'sickleave' => [ 'Sick Leave', true, :right, true ],
|
67
|
+
'specialleave' => [ 'Special Leave', true, :right, true ],
|
68
|
+
'status' => [ 'Status', false, :left, true ],
|
69
|
+
'targets' => [ 'Targets', false, :left, true ],
|
70
|
+
'unpaidleave' => [ 'Unpaid Leave', true, :right, true ]
|
62
71
|
}
|
63
72
|
@@propertiesByType = {
|
64
73
|
# Type Indent Align
|
@@ -76,7 +85,10 @@ class TaskJuggler
|
|
76
85
|
|
77
86
|
# Reference to the intermediate representation.
|
78
87
|
@table = nil
|
79
|
-
|
88
|
+
# The table is generated row after row. We need to hold some computed
|
89
|
+
# values that are specific to certain columns. For that we use a Hash of
|
90
|
+
# ReportTableColumn objects.
|
91
|
+
@columns = { }
|
80
92
|
|
81
93
|
@legend = ReportTableLegend.new
|
82
94
|
|
@@ -155,12 +167,12 @@ class TaskJuggler
|
|
155
167
|
end
|
156
168
|
|
157
169
|
# Return the alignment of the column based on the _colId_ or the
|
158
|
-
#
|
159
|
-
def alignment(colId,
|
170
|
+
# _attributeType_.
|
171
|
+
def alignment(colId, attributeType)
|
160
172
|
if @@propertiesById.has_key?(colId)
|
161
173
|
return @@propertiesById[colId][2]
|
162
|
-
elsif @@propertiesByType.has_key?(
|
163
|
-
return @@propertiesByType[
|
174
|
+
elsif @@propertiesByType.has_key?(attributeType)
|
175
|
+
return @@propertiesByType[attributeType][1]
|
164
176
|
else
|
165
177
|
:center
|
166
178
|
end
|
@@ -187,87 +199,119 @@ class TaskJuggler
|
|
187
199
|
|
188
200
|
protected
|
189
201
|
|
190
|
-
# These can't be determined during initialization as they have have been
|
191
|
-
# changed afterwards.
|
192
|
-
def setReportPeriod
|
193
|
-
@start = a('start')
|
194
|
-
@end = a('end')
|
195
|
-
end
|
196
|
-
|
197
202
|
# In case the user has not specified the report period, we try to fit all
|
198
|
-
# the _tasks_ in and add an extra 5% time at both ends
|
199
|
-
# list of scenario indexes.
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
+
# the _tasks_ in and add an extra 5% time at both ends for some specific
|
204
|
+
# type of columns. _scenarios_ is a list of scenario indexes. _columnDef_
|
205
|
+
# is a reference to the TableColumnDefinition object describing the
|
206
|
+
# current column.
|
207
|
+
def adjustColumnPeriod(columnDef, tasks = [], scenarios = [])
|
208
|
+
# If we have user specified dates for the report period or the column
|
209
|
+
# period, we don't adjust the period. This flag is used to mark if we
|
210
|
+
# have user-provided values.
|
211
|
+
doNotAdjust = false
|
212
|
+
|
213
|
+
# Determine the start date for the column.
|
214
|
+
if columnDef.start
|
215
|
+
# We have a user-specified, column specific start date.
|
216
|
+
rStart = columnDef.start
|
217
|
+
doNotAdjust = true
|
218
|
+
else
|
219
|
+
# Use the report start date.
|
220
|
+
rStart = a('start')
|
221
|
+
doNotAdjust = true if rStart != @project['start']
|
222
|
+
end
|
203
223
|
|
204
|
-
|
224
|
+
if columnDef.end
|
225
|
+
rEnd = columnDef.end
|
226
|
+
doNotAdjust = true
|
227
|
+
else
|
228
|
+
rEnd = a('end')
|
229
|
+
doNotAdjust = true if rEnd != @project['end']
|
230
|
+
end
|
231
|
+
|
232
|
+
# Save the unadjusted dates to the columns Hash.
|
233
|
+
@columns[columnDef] = TableReportColumn.new(rStart, rEnd)
|
234
|
+
|
235
|
+
# If the task list is empty or the user has provided a custom start or
|
236
|
+
# end date, we don't touch the report period.
|
237
|
+
return if tasks.empty? || scenarios.empty? || doNotAdjust
|
238
|
+
|
239
|
+
# Find the start date of the earliest tasks included in the report and
|
240
|
+
# the end date of the last included tasks.
|
241
|
+
rStart = rEnd = nil
|
205
242
|
scenarios.each do |scenarioIdx|
|
206
243
|
tasks.each do |task|
|
207
244
|
date = task['start', scenarioIdx] || @project['start']
|
208
|
-
|
245
|
+
rStart = date if rStart.nil? || date < rStart
|
209
246
|
date = task['end', scenarioIdx] || @project['end']
|
210
|
-
|
247
|
+
rEnd = date if rEnd.nil? || date > rEnd
|
211
248
|
end
|
212
249
|
end
|
213
250
|
|
214
251
|
# We want to add at least 5% on both ends.
|
215
252
|
margin = 0
|
216
|
-
minWidth =
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
break
|
257
|
-
end
|
253
|
+
minWidth = rEnd - rStart + 1
|
254
|
+
case columnDef.id
|
255
|
+
when 'chart'
|
256
|
+
# In case we have a 'chart' column, we enforce certain minimum width
|
257
|
+
# The following table contains an entry for each scale. The entry
|
258
|
+
# consists of the triple 'seconds per unit', 'minimum width units'
|
259
|
+
# and 'margin units'. The minimum with does not include the margins
|
260
|
+
# since they are always added.
|
261
|
+
mwMap = {
|
262
|
+
'hour' => [ 60 * 60, 18, 2 ],
|
263
|
+
'day' => [ 60 * 60 * 24, 18, 2 ],
|
264
|
+
'week' => [ 60 * 60 * 24 * 7, 6, 1 ],
|
265
|
+
'month' => [ 60 * 60 * 24 * 31, 10, 1 ],
|
266
|
+
'quarter' => [ 60 * 60 * 24 * 90, 6, 1 ],
|
267
|
+
'year' => [ 60 * 60 * 24 * 365, 4, 1 ]
|
268
|
+
}
|
269
|
+
entry = mwMap[columnDef.scale]
|
270
|
+
raise "Unknown scale #{columnDef.scale}" unless entry
|
271
|
+
margin = entry[0] * entry[2]
|
272
|
+
# If the with determined by start and end dates of the task is below
|
273
|
+
# the minimum width, we increase the width to the value provided by
|
274
|
+
# the table.
|
275
|
+
minWidth = entry[0] * entry[1] if minWidth < entry[0] * entry[1]
|
276
|
+
when 'hourly', 'daily', 'weekly', 'monthly', 'quarterly', 'yearly'
|
277
|
+
# For the calendar columns we use a similar approach as we use for
|
278
|
+
# the 'chart' column.
|
279
|
+
mwMap = {
|
280
|
+
'hourly' => [ 60 * 60, 18, 2 ],
|
281
|
+
'daily' => [ 60 * 60 * 24, 18, 2 ],
|
282
|
+
'weekly' => [ 60 * 60 * 24 * 7, 6, 1 ],
|
283
|
+
'monthly' => [ 60 * 60 * 24 * 31, 10, 1 ],
|
284
|
+
'quarterly' => [ 60 * 60 * 24 * 90, 6, 1 ],
|
285
|
+
'yearly' => [ 60 * 60 * 24 * 365, 4, 1 ]
|
286
|
+
}
|
287
|
+
entry = mwMap[columnDef.id]
|
288
|
+
raise "Unknown scale #{columnDef.id}" unless entry
|
289
|
+
margin = entry[0] * entry[2]
|
290
|
+
minWidth = entry[0] * entry[1] if minWidth < entry[0] * entry[1]
|
291
|
+
else
|
292
|
+
doNotAdjust = true
|
258
293
|
end
|
259
294
|
|
260
|
-
|
261
|
-
|
295
|
+
unless doNotAdjust
|
296
|
+
if minWidth > (rEnd - rStart + 1)
|
297
|
+
margin += (minWidth - (rEnd - rStart + 1)) / 2
|
298
|
+
end
|
299
|
+
|
300
|
+
rStart -= margin
|
301
|
+
rEnd += margin
|
302
|
+
|
303
|
+
# Save the adjusted dates to the columns Hash.
|
304
|
+
@columns[columnDef] = TableReportColumn.new(rStart, rEnd)
|
262
305
|
end
|
263
|
-
@start -= margin
|
264
|
-
@end += margin
|
265
306
|
end
|
266
307
|
|
267
308
|
# Generates cells for the table header. _columnDef_ is the
|
268
309
|
# TableColumnDefinition object that describes the column. Based on the id of
|
269
310
|
# the column different actions need to be taken to generate the header text.
|
270
311
|
def generateHeaderCell(columnDef)
|
312
|
+
rStart = @columns[columnDef].start
|
313
|
+
rEnd = @columns[columnDef].end
|
314
|
+
|
271
315
|
case columnDef.id
|
272
316
|
when 'chart'
|
273
317
|
# For the 'chart' column we generate a GanttChart object. The sizes are
|
@@ -275,7 +319,7 @@ class TaskJuggler
|
|
275
319
|
# table.
|
276
320
|
gantt = GanttChart.new(a('now'),
|
277
321
|
a('weekStartsMonday'), self)
|
278
|
-
gantt.generateByScale(
|
322
|
+
gantt.generateByScale(rStart, rEnd, columnDef.scale)
|
279
323
|
# The header consists of 2 lines separated by a 1 pixel boundary.
|
280
324
|
gantt.header.height = @table.headerLineHeight * 2 + 1
|
281
325
|
# The maximum width of the chart. In case it needs more space, a
|
@@ -288,23 +332,23 @@ class TaskJuggler
|
|
288
332
|
column.scrollbar = gantt.hasScrollbar?
|
289
333
|
@table.equiLines = true
|
290
334
|
when 'hourly'
|
291
|
-
genCalChartHeader(columnDef,
|
335
|
+
genCalChartHeader(columnDef, rStart.midnight, rEnd, :sameTimeNextHour,
|
292
336
|
:weekdayAndDate, :hour)
|
293
337
|
when 'daily'
|
294
|
-
genCalChartHeader(columnDef,
|
338
|
+
genCalChartHeader(columnDef, rStart.midnight, rEnd, :sameTimeNextDay,
|
295
339
|
:monthAndYear, :day)
|
296
340
|
when 'weekly'
|
297
341
|
genCalChartHeader(columnDef,
|
298
|
-
|
342
|
+
rStart.beginOfWeek(a('weekStartsMonday')), rEnd,
|
299
343
|
:sameTimeNextWeek, :monthAndYear, :day)
|
300
344
|
when 'monthly'
|
301
|
-
genCalChartHeader(columnDef,
|
302
|
-
:year, :shortMonthName)
|
345
|
+
genCalChartHeader(columnDef, rStart.beginOfMonth, rEnd,
|
346
|
+
:sameTimeNextMonth, :year, :shortMonthName)
|
303
347
|
when 'quarterly'
|
304
|
-
genCalChartHeader(columnDef,
|
348
|
+
genCalChartHeader(columnDef, rStart.beginOfQuarter, rEnd,
|
305
349
|
:sameTimeNextQuarter, :year, :quarterName)
|
306
350
|
when 'yearly'
|
307
|
-
genCalChartHeader(columnDef,
|
351
|
+
genCalChartHeader(columnDef, rStart.beginOfYear, rEnd, :sameTimeNextYear,
|
308
352
|
nil, :year)
|
309
353
|
else
|
310
354
|
# This is the most common case. It does not need any special treatment.
|
@@ -317,26 +361,57 @@ class TaskJuggler
|
|
317
361
|
end
|
318
362
|
end
|
319
363
|
|
364
|
+
# Generate a ReportTableLine for each of the accounts in _accountList_. If
|
365
|
+
# _scopeLine_ is defined, the generated account lines will be within the
|
366
|
+
# scope this resource line.
|
367
|
+
def generateAccountList(accountList, lineOffset, mode)
|
368
|
+
# Get the current Query from the report context and create a copy. We
|
369
|
+
# are going to modify it.
|
370
|
+
accountList.query = query = @project.reportContexts.last.query.dup
|
371
|
+
accountList.sort!
|
372
|
+
|
373
|
+
# The primary line counter. Is not used for enclosed lines.
|
374
|
+
no = lineOffset
|
375
|
+
# The scope line counter. It's reset for each new scope.
|
376
|
+
lineNo = lineOffset
|
377
|
+
# Init the variable to get a larger scope
|
378
|
+
line = nil
|
379
|
+
accountList.each do |account|
|
380
|
+
query.property = account
|
381
|
+
|
382
|
+
no += 1
|
383
|
+
Log.activity if lineNo % 10 == 0
|
384
|
+
lineNo += 1
|
385
|
+
a('scenarios').each do |scenarioIdx|
|
386
|
+
query.scenarioIdx = scenarioIdx
|
387
|
+
# Generate line for each account.
|
388
|
+
line = ReportTableLine.new(@table, account, nil)
|
389
|
+
|
390
|
+
line.no = no
|
391
|
+
line.lineNo = lineNo
|
392
|
+
line.subLineNo = @table.lines
|
393
|
+
setIndent(line, a('accountRoot'), accountList.treeMode?)
|
394
|
+
|
395
|
+
# Generate a cell for each column in this line.
|
396
|
+
a('columns').each do |columnDef|
|
397
|
+
query.attributeId = columnDef.id
|
398
|
+
next unless generateTableCell(line, columnDef, query)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
lineNo
|
403
|
+
end
|
404
|
+
|
320
405
|
# Generate a ReportTableLine for each of the tasks in _taskList_. In case
|
321
406
|
# _resourceList_ is not nil, it also generates the nested resource lines for
|
322
407
|
# each resource that is assigned to the particular task. If _scopeLine_
|
323
|
-
# is defined, the generated task lines will be within the scope this
|
324
|
-
# line.
|
408
|
+
# is defined, the generated task lines will be within the scope this
|
409
|
+
# resource line.
|
325
410
|
def generateTaskList(taskList, resourceList, scopeLine)
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
'timeFormat' => a('timeFormat'),
|
331
|
-
'currencyFormat' => a('currencyFormat'),
|
332
|
-
'start' => @start, 'end' => @end,
|
333
|
-
'hideJournalEntry' => a('hideJournalEntry'),
|
334
|
-
'journalMode' => a('journalMode'),
|
335
|
-
'journalAttributes' => a('journalAttributes'),
|
336
|
-
'sortJournalEntries' => a('sortJournalEntries'),
|
337
|
-
'costAccount' => a('costAccount'),
|
338
|
-
'revenueAccount' => a('revenueAccount') }
|
339
|
-
taskList.query = Query.new(queryAttrs)
|
411
|
+
# Get the current Query from the report context and create a copy. We
|
412
|
+
# are going to modify it.
|
413
|
+
taskList.query = query = @project.reportContexts.last.query.dup
|
414
|
+
query.scopeProperty = scopeLine ? scopeLine.property : nil
|
340
415
|
taskList.sort!
|
341
416
|
|
342
417
|
# The primary line counter. Is not used for enclosed lines.
|
@@ -348,7 +423,6 @@ class TaskJuggler
|
|
348
423
|
taskList.each do |task|
|
349
424
|
# Get the current Query from the report context and create a copy. We
|
350
425
|
# are going to modify it.
|
351
|
-
query = @project.reportContexts.last.query.dup
|
352
426
|
query.property = task
|
353
427
|
query.scopeProperty = scopeLine ? scopeLine.property : nil
|
354
428
|
|
@@ -368,7 +442,7 @@ class TaskJuggler
|
|
368
442
|
# Generate a cell for each column in this line.
|
369
443
|
a('columns').each do |columnDef|
|
370
444
|
query.attributeId = columnDef.id
|
371
|
-
next unless generateTableCell(line,
|
445
|
+
next unless generateTableCell(line, columnDef, query)
|
372
446
|
end
|
373
447
|
end
|
374
448
|
|
@@ -391,20 +465,10 @@ class TaskJuggler
|
|
391
465
|
# each task that the resource is assigned to. If _scopeLine_ is defined, the
|
392
466
|
# generated resource lines will be within the scope this task line.
|
393
467
|
def generateResourceList(resourceList, taskList, scopeLine)
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
'timeFormat' => a('timeFormat'),
|
399
|
-
'currencyFormat' => a('currencyFormat'),
|
400
|
-
'start' => @start, 'end' => @end,
|
401
|
-
'hideJournalEntry' => a('hideJournalEntry'),
|
402
|
-
'journalMode' => a('journalMode'),
|
403
|
-
'journalAttributes' => a('journalAttributes'),
|
404
|
-
'sortJournalEntries' => a('sortJournalEntries'),
|
405
|
-
'costAccount' => a('costAccount'),
|
406
|
-
'revenueAccount' => a('revenueAccount') }
|
407
|
-
resourceList.query = Query.new(queryAttrs)
|
468
|
+
# Get the current Query from the report context and create a copy. We
|
469
|
+
# are going to modify it.
|
470
|
+
resourceList.query = query = @project.reportContexts.last.query.dup
|
471
|
+
query.scopeProperty = scopeLine ? scopeLine.property : nil
|
408
472
|
resourceList.sort!
|
409
473
|
|
410
474
|
# The primary line counter. Is not used for enclosed lines.
|
@@ -416,7 +480,6 @@ class TaskJuggler
|
|
416
480
|
resourceList.each do |resource|
|
417
481
|
# Get the current Query from the report context and create a copy. We
|
418
482
|
# are going to modify it.
|
419
|
-
query = @project.reportContexts.last.query.dup
|
420
483
|
query.property = resource
|
421
484
|
query.scopeProperty = scopeLine ? scopeLine.property : nil
|
422
485
|
|
@@ -436,7 +499,7 @@ class TaskJuggler
|
|
436
499
|
# Generate a cell for each column in this line.
|
437
500
|
a('columns').each do |column|
|
438
501
|
query.attributeId = column.id
|
439
|
-
next unless generateTableCell(line,
|
502
|
+
next unless generateTableCell(line, column, query)
|
440
503
|
end
|
441
504
|
end
|
442
505
|
|
@@ -463,7 +526,8 @@ class TaskJuggler
|
|
463
526
|
# that is called to advance _t_ to the next table column interval.
|
464
527
|
# _name1Func_ and _name2Func_ are functions that return the upper and lower
|
465
528
|
# title of the particular column.
|
466
|
-
def genCalChartHeader(columnDef, t,
|
529
|
+
def genCalChartHeader(columnDef, t, rEnd, sameTimeNextFunc,
|
530
|
+
name1Func, name2Func)
|
467
531
|
tableColumn = ReportTableColumn.new(@table, columnDef, '')
|
468
532
|
|
469
533
|
# Calendar chars only work when all lines have same height.
|
@@ -483,14 +547,14 @@ class TaskJuggler
|
|
483
547
|
# iteration is done with 2 nested loops. The outer loops generates the
|
484
548
|
# intervals for the upper (larger) scale. The inner loop generates the
|
485
549
|
# lower (smaller) scale.
|
486
|
-
while t <
|
550
|
+
while t < rEnd
|
487
551
|
cellsInInterval = 0
|
488
552
|
# Label for upper scale. The yearly calendar only has a lower scale.
|
489
553
|
currentInterval = t.send(name1Func) if name1Func
|
490
554
|
firstColumn = nil
|
491
555
|
# The innter loops terminates when the label for the upper scale has
|
492
556
|
# changed to the next scale cell.
|
493
|
-
while t <
|
557
|
+
while t < rEnd && (name1Func.nil? ||
|
494
558
|
t.send(name1Func) == currentInterval)
|
495
559
|
# call TjTime::sameTimeNext... function to get the end of the column.
|
496
560
|
nextT = t.send(sameTimeNextFunc)
|
@@ -508,8 +572,11 @@ class TaskJuggler
|
|
508
572
|
column.cell1.hidden = true
|
509
573
|
end
|
510
574
|
column.cell2.text = t.send(name2Func).to_s
|
511
|
-
#
|
512
|
-
column.cell2.
|
575
|
+
# We assume an average of 7 pixel per character
|
576
|
+
width = 8 + 7 * column.cell2.text.length
|
577
|
+
# Ensure a minimum with of 28 to have good looking tables even with
|
578
|
+
# small column headers (like day of months numbers).
|
579
|
+
column.cell2.width = width <= 28 ? 28 : width
|
513
580
|
# Off-duty cells will have a different color than working time cells.
|
514
581
|
unless @project.hasWorkingTime(iv)
|
515
582
|
column.cell2.category = 'tabhead_offduty'
|
@@ -537,14 +604,15 @@ class TaskJuggler
|
|
537
604
|
# columns. In such a case many cells are generated with a single call of
|
538
605
|
# this method. The last kind of cell is actually not a cell. It just
|
539
606
|
# generates the chart objects that belong to the property in this line.
|
540
|
-
def generateTableCell(line,
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
607
|
+
def generateTableCell(line, columnDef, query)
|
608
|
+
# Adjust the Query to use column specific settings. We create a copy of
|
609
|
+
# the Query to avoid spoiling the original query with column specific
|
610
|
+
# settings.
|
611
|
+
query = query.dup
|
612
|
+
query.start = @columns[columnDef].start
|
613
|
+
query.end = @columns[columnDef].end
|
614
|
+
query.listType = columnDef.listType
|
615
|
+
query.listItem = columnDef.listItem
|
548
616
|
|
549
617
|
case columnDef.id
|
550
618
|
when 'chart'
|
@@ -562,26 +630,26 @@ class TaskJuggler
|
|
562
630
|
# The calendar cells can be all generated by the same function. But we
|
563
631
|
# need to use different parameters.
|
564
632
|
when 'hourly'
|
565
|
-
start =
|
633
|
+
start = query.start.midnight
|
566
634
|
sameTimeNextFunc = :sameTimeNextHour
|
567
635
|
when 'daily'
|
568
|
-
start =
|
636
|
+
start = query.start.midnight
|
569
637
|
sameTimeNextFunc = :sameTimeNextDay
|
570
638
|
when 'weekly'
|
571
|
-
start =
|
639
|
+
start = query.start.beginOfWeek(a('weekStartsMonday'))
|
572
640
|
sameTimeNextFunc = :sameTimeNextWeek
|
573
641
|
when 'monthly'
|
574
|
-
start =
|
642
|
+
start = query.start.beginOfMonth
|
575
643
|
sameTimeNextFunc = :sameTimeNextMonth
|
576
644
|
when 'quarterly'
|
577
|
-
start =
|
645
|
+
start = query.start.beginOfQuarter
|
578
646
|
sameTimeNextFunc = :sameTimeNextQuarter
|
579
647
|
when 'yearly'
|
580
|
-
start =
|
648
|
+
start = query.start.beginOfYear
|
581
649
|
sameTimeNextFunc = :sameTimeNextYear
|
582
650
|
else
|
583
651
|
if calculated?(columnDef.id)
|
584
|
-
return genCalculatedCell(query, line, columnDef
|
652
|
+
return genCalculatedCell(query, line, columnDef)
|
585
653
|
else
|
586
654
|
return genStandardCell(query, line, columnDef)
|
587
655
|
end
|
@@ -595,13 +663,15 @@ class TaskJuggler
|
|
595
663
|
|
596
664
|
PlaceHolderCell.new(line, tcLine)
|
597
665
|
# Depending on the property type we use different generator functions.
|
598
|
-
if property.is_a?(Task)
|
666
|
+
if query.property.is_a?(Task)
|
599
667
|
genCalChartTaskCell(query, tcLine, columnDef, start, sameTimeNextFunc)
|
600
|
-
elsif property.is_a?(Resource)
|
668
|
+
elsif query.property.is_a?(Resource)
|
601
669
|
genCalChartResourceCell(query, tcLine, columnDef, start,
|
602
670
|
sameTimeNextFunc)
|
671
|
+
elsif query.property.is_a?(Account)
|
672
|
+
genCalChartAccountCell(query, tcLine, columnDef, start, sameTimeNextFunc)
|
603
673
|
else
|
604
|
-
raise "Unknown property type #{property.class}"
|
674
|
+
raise "Unknown property type #{query.property.class}"
|
605
675
|
end
|
606
676
|
true
|
607
677
|
end
|
@@ -610,16 +680,14 @@ class TaskJuggler
|
|
610
680
|
# property that line is for. It returns true if the cell exists, false for a
|
611
681
|
# hidden cell.
|
612
682
|
def genStandardCell(query, line, columnDef)
|
613
|
-
query = query.dup
|
614
|
-
query.listType = columnDef.listType
|
615
|
-
query.listItem = columnDef.listItem
|
616
|
-
|
617
683
|
# Find out, what type of PropertyTreeNode we are dealing with.
|
618
684
|
property = line.property
|
619
685
|
if property.is_a?(Task)
|
620
686
|
propertyList = @project.tasks
|
621
687
|
elsif property.is_a?(Resource)
|
622
688
|
propertyList = @project.resources
|
689
|
+
elsif property.is_a?(Account)
|
690
|
+
propertyList = @project.accounts
|
623
691
|
else
|
624
692
|
raise "Unknown property type #{property.class}"
|
625
693
|
end
|
@@ -632,7 +700,7 @@ class TaskJuggler
|
|
632
700
|
return false
|
633
701
|
end
|
634
702
|
|
635
|
-
setStandardCellAttributes(cell, columnDef,
|
703
|
+
setStandardCellAttributes(query, cell, columnDef,
|
636
704
|
propertyList.attributeType(columnDef.id), line)
|
637
705
|
|
638
706
|
# If the user has requested a custom cell text, this will be used
|
@@ -653,13 +721,8 @@ class TaskJuggler
|
|
653
721
|
# or other sources of information. It returns true if the cell exists, false
|
654
722
|
# for a hidden cell. _query_ is the Query to get the cell value. _line_
|
655
723
|
# is the ReportTableLine of the cell. _columnDef_ is the
|
656
|
-
# TableColumnDefinition of the column.
|
657
|
-
|
658
|
-
def genCalculatedCell(query, line, columnDef, property)
|
659
|
-
query = query.dup
|
660
|
-
query.listType = columnDef.listType
|
661
|
-
query.listItem = columnDef.listItem
|
662
|
-
|
724
|
+
# TableColumnDefinition of the column.
|
725
|
+
def genCalculatedCell(query, line, columnDef)
|
663
726
|
# Create a new cell
|
664
727
|
cell = newCell(query, line)
|
665
728
|
|
@@ -668,7 +731,7 @@ class TaskJuggler
|
|
668
731
|
return false
|
669
732
|
end
|
670
733
|
|
671
|
-
setStandardCellAttributes(cell, columnDef, nil, line)
|
734
|
+
setStandardCellAttributes(query, cell, columnDef, nil, line)
|
672
735
|
|
673
736
|
if query.process
|
674
737
|
cell.text = (rti = query.to_rti) ? rti : query.to_s
|
@@ -677,15 +740,16 @@ class TaskJuggler
|
|
677
740
|
# Some columns need some extra care.
|
678
741
|
case columnDef.id
|
679
742
|
when 'alert'
|
680
|
-
id = @project
|
743
|
+
id = @project['alertLevels'][query.to_sort].id
|
681
744
|
cell.icon = "flag-#{id}"
|
682
|
-
cell.fontColor = @project
|
745
|
+
cell.fontColor = @project['alertLevels'][query.to_sort].color
|
683
746
|
when 'alerttrend'
|
684
747
|
icons = %w( up flat down )
|
685
748
|
cell.icon = "trend-#{icons[query.to_sort]}"
|
686
749
|
when 'line'
|
687
750
|
cell.text = line.lineNo.to_s
|
688
751
|
when 'name'
|
752
|
+
property = query.property
|
689
753
|
cell.icon =
|
690
754
|
if property.is_a?(Task)
|
691
755
|
if property.container?
|
@@ -722,6 +786,49 @@ class TaskJuggler
|
|
722
786
|
true
|
723
787
|
end
|
724
788
|
|
789
|
+
# Generate the cells for the account lines of a calendar column. These
|
790
|
+
# lines do not directly belong to the @table object but to an embedded
|
791
|
+
# ColumnTable object. Therefor a single @table column usually has many
|
792
|
+
# cells on each single line. _scenarioIdx_ is the index of the scenario
|
793
|
+
# that is reported in this line. _line_ is the @table line. _t_ is the
|
794
|
+
# start date for the calendar. _sameTimeNextFunc_ is the function that
|
795
|
+
# will move the date to the next cell.
|
796
|
+
def genCalChartAccountCell(query, line, columnDef, t, sameTimeNextFunc)
|
797
|
+
# We modify the start and end dates to match the cell boundaries. So
|
798
|
+
# we need to make sure we don't modify the original Query but our own
|
799
|
+
# copies.
|
800
|
+
query = query.dup
|
801
|
+
|
802
|
+
firstCell = nil
|
803
|
+
endDate = query.end
|
804
|
+
while t < endDate
|
805
|
+
# call TjTime::sameTimeNext... function
|
806
|
+
nextT = t.send(sameTimeNextFunc)
|
807
|
+
query.attributeId = 'balance'
|
808
|
+
query.start = t
|
809
|
+
query.end = nextT
|
810
|
+
query.process
|
811
|
+
|
812
|
+
# Create a new cell
|
813
|
+
cell = newCell(query, line)
|
814
|
+
|
815
|
+
cell.text = query.to_s
|
816
|
+
|
817
|
+
cdText = columnDef.cellText.getPattern(query)
|
818
|
+
cell.text = cdText if cdText
|
819
|
+
cell.showTooltipHint = false
|
820
|
+
|
821
|
+
setAccountCellBgColor(query, line, cell)
|
822
|
+
|
823
|
+
setCustomCellAttributes(cell, columnDef, query)
|
824
|
+
|
825
|
+
tryCellMerging(cell, line, firstCell)
|
826
|
+
|
827
|
+
t = nextT
|
828
|
+
firstCell = cell unless firstCell
|
829
|
+
end
|
830
|
+
end
|
831
|
+
|
725
832
|
# Generate the cells for the task lines of a calendar column. These lines do
|
726
833
|
# not directly belong to the @table object but to an embedded ColumnTable
|
727
834
|
# object. Therefor a single @table column usually has many cells on each
|
@@ -729,7 +836,7 @@ class TaskJuggler
|
|
729
836
|
# in this line. _line_ is the @table line. _t_ is the start date for the
|
730
837
|
# calendar. _sameTimeNextFunc_ is the function that will move the date to
|
731
838
|
# the next cell.
|
732
|
-
def genCalChartTaskCell(
|
839
|
+
def genCalChartTaskCell(query, line, columnDef, t, sameTimeNextFunc)
|
733
840
|
task = line.property
|
734
841
|
# Find out if we have an enclosing resource scope.
|
735
842
|
if line.scopeLine && line.scopeLine.property.is_a?(Resource)
|
@@ -740,17 +847,19 @@ class TaskJuggler
|
|
740
847
|
|
741
848
|
# Get the interval of the task. In case a date is invalid due to a
|
742
849
|
# scheduling problem, we use the full project interval.
|
743
|
-
taskStart = task['start',
|
744
|
-
taskEnd = task['end',
|
850
|
+
taskStart = task['start', query.scenarioIdx]
|
851
|
+
taskEnd = task['end', query.scenarioIdx]
|
745
852
|
taskIv = TimeInterval.new(taskStart.nil? ? @project['start'] : taskStart,
|
746
853
|
taskEnd.nil? ? @project['end'] : taskEnd)
|
747
854
|
|
855
|
+
# We modify the start and end dates to match the cell boundaries. So
|
856
|
+
# we need to make sure we don't modify the original Query but our own
|
857
|
+
# copies.
|
858
|
+
query = query.dup
|
859
|
+
|
748
860
|
firstCell = nil
|
749
|
-
|
750
|
-
|
751
|
-
# we need to make sure we don't modify the original Query but our own
|
752
|
-
# copies.
|
753
|
-
query = origQuery.dup
|
861
|
+
endDate = query.end
|
862
|
+
while t < endDate
|
754
863
|
# call TjTime::sameTimeNext... function
|
755
864
|
nextT = t.send(sameTimeNextFunc)
|
756
865
|
cellIv = TimeInterval.new(t, nextT)
|
@@ -768,7 +877,7 @@ class TaskJuggler
|
|
768
877
|
# Create a new cell
|
769
878
|
cell = newCell(query, line)
|
770
879
|
|
771
|
-
# To increase readability
|
880
|
+
# To increase readability show empty cells instead of 0.0 values.
|
772
881
|
cell.text = query.to_s if query.to_num != 0.0
|
773
882
|
else
|
774
883
|
raise "Unknown column content #{column.content}"
|
@@ -782,7 +891,6 @@ class TaskJuggler
|
|
782
891
|
if cellIv.overlaps?(taskIv)
|
783
892
|
# The cell is either a container or leaf task
|
784
893
|
cell.category = task.container? ? 'calconttask' : 'caltask'
|
785
|
-
setCustomCellAttributes(cell, columnDef, query)
|
786
894
|
elsif !@project.isWorkingTime(cellIv)
|
787
895
|
# The cell is a vacation cell.
|
788
896
|
cell.category = 'offduty'
|
@@ -792,6 +900,7 @@ class TaskJuggler
|
|
792
900
|
end
|
793
901
|
cell.category += line.property.get('index') % 2 == 1 ? '1' : '2'
|
794
902
|
|
903
|
+
setCustomCellAttributes(cell, columnDef, query)
|
795
904
|
tryCellMerging(cell, line, firstCell)
|
796
905
|
|
797
906
|
t = nextT
|
@@ -810,15 +919,15 @@ class TaskJuggler
|
|
810
919
|
# reported in this line. _line_ is the @table line. _t_ is the start date
|
811
920
|
# for the calendar. _sameTimeNextFunc_ is the function that will move the
|
812
921
|
# date to the next cell.
|
813
|
-
def genCalChartResourceCell(
|
922
|
+
def genCalChartResourceCell(query, line, columnDef, t,
|
814
923
|
sameTimeNextFunc)
|
815
924
|
# Find out if we have an enclosing task scope.
|
816
925
|
if line.scopeLine && line.scopeLine.property.is_a?(Task)
|
817
926
|
task = line.scopeLine.property
|
818
927
|
# Get the interval of the task. In case a date is invalid due to a
|
819
928
|
# scheduling problem, we use the full project interval.
|
820
|
-
taskStart = task['start',
|
821
|
-
taskEnd = task['end',
|
929
|
+
taskStart = task['start', query.scenarioIdx]
|
930
|
+
taskEnd = task['end', query.scenarioIdx]
|
822
931
|
taskIv = TimeInterval.new(taskStart.nil? ? @project['start'] :
|
823
932
|
taskStart,
|
824
933
|
taskEnd.nil? ? @project['end'] : taskEnd)
|
@@ -826,13 +935,14 @@ class TaskJuggler
|
|
826
935
|
task = nil
|
827
936
|
end
|
828
937
|
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
# copies.
|
834
|
-
query = origQuery.dup
|
938
|
+
# We modify the start and end dates to match the cell boundaries. So
|
939
|
+
# we need to make sure we don't modify the original Query but our own
|
940
|
+
# copies.
|
941
|
+
query = query.dup
|
835
942
|
|
943
|
+
firstCell = nil
|
944
|
+
endDate = query.end
|
945
|
+
while t < endDate
|
836
946
|
# Create a new cell
|
837
947
|
cell = newCell(query, line)
|
838
948
|
|
@@ -847,6 +957,7 @@ class TaskJuggler
|
|
847
957
|
query.process
|
848
958
|
workLoad = query.to_num
|
849
959
|
scaledWorkLoad = query.to_s
|
960
|
+
|
850
961
|
if task
|
851
962
|
# Get work load for the particular task.
|
852
963
|
query.scopeProperty = task
|
@@ -917,6 +1028,8 @@ class TaskJuggler
|
|
917
1028
|
end
|
918
1029
|
cell.category += line.property.get('index') % 2 == 1 ? '1' : '2'
|
919
1030
|
|
1031
|
+
setCustomCellAttributes(cell, columnDef, query)
|
1032
|
+
|
920
1033
|
tryCellMerging(cell, line, firstCell)
|
921
1034
|
|
922
1035
|
t = nextT
|
@@ -931,7 +1044,7 @@ class TaskJuggler
|
|
931
1044
|
|
932
1045
|
# This method takes care of often used cell attributes like indentation,
|
933
1046
|
# alignment and background color.
|
934
|
-
def setStandardCellAttributes(cell, columnDef, attributeType, line)
|
1047
|
+
def setStandardCellAttributes(query, cell, columnDef, attributeType, line)
|
935
1048
|
# Determine whether it should be indented
|
936
1049
|
if indent(columnDef.id, attributeType)
|
937
1050
|
cell.indent = line.indentation
|
@@ -942,11 +1055,13 @@ class TaskJuggler
|
|
942
1055
|
|
943
1056
|
# Set background color
|
944
1057
|
if line.property.is_a?(Task)
|
945
|
-
cell.category =
|
946
|
-
|
947
|
-
|
948
|
-
cell.category =
|
949
|
-
|
1058
|
+
cell.category = 'taskcell'
|
1059
|
+
cell.category += line.property.get('index') % 2 == 1 ? '1' : '2'
|
1060
|
+
elsif line.property.is_a?(Resource)
|
1061
|
+
cell.category = 'resourcecell'
|
1062
|
+
cell.category += line.property.get('index') % 2 == 1 ? '1' : '2'
|
1063
|
+
elsif line.property.is_a?(Account)
|
1064
|
+
setAccountCellBgColor(query, line, cell)
|
950
1065
|
end
|
951
1066
|
|
952
1067
|
# Set column width
|
@@ -1019,6 +1134,23 @@ class TaskJuggler
|
|
1019
1134
|
end
|
1020
1135
|
end
|
1021
1136
|
|
1137
|
+
def setAccountCellBgColor(query, line, cell)
|
1138
|
+
if query.costAccount &&
|
1139
|
+
(query.property.isChildOf?(query.costAccount) ||
|
1140
|
+
query.costAccount == query.property)
|
1141
|
+
prefix = 'cost'
|
1142
|
+
elsif query.revenueAccount &&
|
1143
|
+
(query.property.isChildOf?(query.revenueAccount) ||
|
1144
|
+
query.revenueAccount == query.property)
|
1145
|
+
prefix = 'revenue'
|
1146
|
+
else
|
1147
|
+
prefix = ''
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
cell.category = prefix + 'accountcell' +
|
1151
|
+
(line.property.get('index') % 2 == 1 ? '1' : '2')
|
1152
|
+
end
|
1153
|
+
|
1022
1154
|
# Make sure we have a valid cell text. If not, this is the result of an
|
1023
1155
|
# error. This could happen after scheduling errors.
|
1024
1156
|
def checkCellText(cell)
|