taskjuggler 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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)
|