taskjuggler 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +44 -0
- data/bin/tj3webd +4 -0
- data/data/css/tjreport.css +14 -5
- data/data/tjp.vim +22 -7
- data/examples/Fedora-20/reports.tji +2 -4
- data/examples/Scrum/Product Burndown.csv +26 -0
- data/examples/Scrum/Sprint 1 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 2 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 3 Burndown.csv +26 -0
- data/examples/Scrum/scrum.tjp +141 -0
- data/examples/Tutorial/tutorial.tjp +13 -7
- data/lib/taskjuggler/Attributes.rb +2 -3
- data/lib/taskjuggler/HTMLDocument.rb +25 -18
- data/lib/taskjuggler/Journal.rb +85 -65
- data/lib/taskjuggler/KeywordDocumentation.rb +25 -13
- data/lib/taskjuggler/LeaveList.rb +1 -1
- data/lib/taskjuggler/Limits.rb +3 -5
- data/lib/taskjuggler/MessageHandler.rb +173 -19
- data/lib/taskjuggler/Painter.rb +75 -0
- data/lib/taskjuggler/Painter/BasicShapes.rb +76 -0
- data/lib/taskjuggler/Painter/Color.rb +273 -0
- data/lib/taskjuggler/Painter/Element.rb +56 -0
- data/lib/taskjuggler/Painter/FontData.rb +221 -0
- data/lib/taskjuggler/Painter/FontMetrics.rb +125 -0
- data/lib/taskjuggler/Painter/FontMetricsData.rb +151 -0
- data/lib/taskjuggler/Painter/Group.rb +77 -0
- data/lib/taskjuggler/Painter/Points.rb +47 -0
- data/lib/taskjuggler/Painter/Primitives.rb +100 -0
- data/lib/taskjuggler/Painter/SVGSupport.rb +36 -0
- data/lib/taskjuggler/Painter/Text.rb +36 -0
- data/lib/taskjuggler/Project.rb +46 -29
- data/lib/taskjuggler/ProjectFileParser.rb +24 -22
- data/lib/taskjuggler/ProjectFileScanner.rb +2 -2
- data/lib/taskjuggler/PropertyTreeNode.rb +26 -34
- data/lib/taskjuggler/Query.rb +8 -5
- data/lib/taskjuggler/RealFormat.rb +3 -0
- data/lib/taskjuggler/Resource.rb +3 -5
- data/lib/taskjuggler/ResourceScenario.rb +19 -7
- data/lib/taskjuggler/RichText.rb +4 -6
- data/lib/taskjuggler/RichText/FunctionExample.rb +1 -1
- data/lib/taskjuggler/RichText/FunctionHandler.rb +5 -6
- data/lib/taskjuggler/RichText/Parser.rb +4 -6
- data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
- data/lib/taskjuggler/RichText/RTFQuery.rb +2 -3
- data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -2
- data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
- data/lib/taskjuggler/RichText/Scanner.rb +6 -6
- data/lib/taskjuggler/RichText/Snip.rb +1 -2
- data/lib/taskjuggler/RuntimeConfig.rb +9 -6
- data/lib/taskjuggler/ScenarioData.rb +4 -3
- data/lib/taskjuggler/Scoreboard.rb +6 -0
- data/lib/taskjuggler/SheetHandlerBase.rb +25 -8
- data/lib/taskjuggler/SimpleQueryExpander.rb +14 -5
- data/lib/taskjuggler/SyntaxReference.rb +1 -2
- data/lib/taskjuggler/TableColumnSorter.rb +84 -0
- data/lib/taskjuggler/Task.rb +3 -5
- data/lib/taskjuggler/TaskJuggler.rb +36 -29
- data/lib/taskjuggler/TaskScenario.rb +154 -66
- data/lib/taskjuggler/TextParser.rb +24 -17
- data/lib/taskjuggler/TextParser/Scanner.rb +16 -11
- data/lib/taskjuggler/TextParser/SourceFileInfo.rb +20 -15
- data/lib/taskjuggler/TimeSheets.rb +6 -12
- data/lib/taskjuggler/Tj3AppBase.rb +35 -16
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +239 -49
- data/lib/taskjuggler/XMLElement.rb +9 -2
- data/lib/taskjuggler/apps/Tj3.rb +43 -37
- data/lib/taskjuggler/apps/Tj3Client.rb +62 -112
- data/lib/taskjuggler/apps/Tj3Daemon.rb +66 -29
- data/lib/taskjuggler/apps/Tj3Man.rb +5 -5
- data/lib/taskjuggler/apps/Tj3SsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3SsSender.rb +13 -16
- data/lib/taskjuggler/apps/Tj3TsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3TsSender.rb +12 -15
- data/lib/taskjuggler/apps/Tj3TsSummary.rb +12 -15
- data/lib/taskjuggler/apps/Tj3WebD.rb +99 -0
- data/lib/taskjuggler/daemon/Daemon.rb +50 -10
- data/lib/taskjuggler/daemon/DaemonConnector.rb +127 -0
- data/lib/taskjuggler/daemon/ProcessIntercom.rb +36 -21
- data/lib/taskjuggler/daemon/ProjectBroker.rb +122 -112
- data/lib/taskjuggler/daemon/ProjectServer.rb +78 -46
- data/lib/taskjuggler/daemon/ReportServer.rb +52 -28
- data/lib/taskjuggler/daemon/ReportServlet.rb +92 -21
- data/lib/taskjuggler/daemon/WebServer.rb +75 -22
- data/lib/taskjuggler/daemon/WelcomePage.rb +1 -0
- data/lib/taskjuggler/reports/AccountListRE.rb +3 -3
- data/lib/taskjuggler/reports/CSVFile.rb +9 -2
- data/lib/taskjuggler/reports/ChartPlotter.rb +453 -0
- data/lib/taskjuggler/reports/Navigator.rb +1 -0
- data/lib/taskjuggler/reports/NikuReport.rb +4 -4
- data/lib/taskjuggler/reports/Report.rb +6 -18
- data/lib/taskjuggler/reports/ReportBase.rb +9 -9
- data/lib/taskjuggler/reports/ReportContext.rb +2 -2
- data/lib/taskjuggler/reports/StatusSheetReport.rb +6 -6
- data/lib/taskjuggler/reports/TableReport.rb +24 -15
- data/lib/taskjuggler/reports/TimeSheetReport.rb +5 -5
- data/lib/taskjuggler/reports/TraceReport.rb +251 -0
- data/lib/tj3webd.rb +17 -0
- data/manual/Day_To_Day_Juggling +10 -3
- data/manual/Installation +38 -19
- data/manual/Software +25 -19
- data/manual/Tutorial +119 -110
- data/manual/html/Day_To_Day_Juggling.html +7 -5
- data/manual/html/Getting_Started.html +4 -4
- data/manual/html/How_To_Contribute.html +4 -4
- data/manual/html/Installation.html +19 -11
- data/manual/html/Intro.html +4 -4
- data/manual/html/Reporting_Bugs.html +4 -4
- data/manual/html/Rich_Text_Attributes.html +4 -4
- data/manual/html/Software.html +15 -11
- data/manual/html/TaskJuggler_2x_Migration.html +4 -4
- data/manual/html/TaskJuggler_Internals.html +4 -4
- data/manual/html/The_TaskJuggler_Syntax.html +4 -4
- data/manual/html/Tutorial.html +41 -32
- data/manual/html/account.html +4 -4
- data/manual/html/account.task.html +4 -4
- data/manual/html/accountprefix.html +4 -4
- data/manual/html/accountreport.html +27 -9
- data/manual/html/accountroot.html +5 -5
- data/manual/html/active.html +4 -4
- data/manual/html/adopt.task.html +4 -4
- data/manual/html/aggregate.html +4 -4
- data/manual/html/alert.html +4 -4
- data/manual/html/alertlevels.html +4 -4
- data/manual/html/allocate.html +5 -5
- data/manual/html/alphabet.html +4 -4
- data/manual/html/alternative.html +4 -4
- data/manual/html/author.html +4 -4
- data/manual/html/balance.html +5 -5
- data/manual/html/booking.resource.html +4 -4
- data/manual/html/booking.task.html +4 -4
- data/manual/html/caption.html +5 -5
- data/manual/html/cellcolor.column.html +43 -8
- data/manual/html/celltext.column.html +4 -4
- data/manual/html/center.html +5 -5
- data/manual/html/charge.html +4 -4
- data/manual/html/chargeset.html +4 -4
- data/manual/html/columnid.html +27 -15
- data/manual/html/columns.html +5 -5
- data/manual/html/complete.html +4 -4
- data/manual/html/copyright.html +4 -4
- data/manual/html/credits.html +4 -4
- data/manual/html/css/tjreport.css +14 -5
- data/manual/html/currency.html +4 -4
- data/manual/html/currencyformat.html +5 -5
- data/manual/html/dailymax.html +5 -5
- data/manual/html/dailymin.html +5 -5
- data/manual/html/dailyworkinghours.html +4 -4
- data/manual/html/date.extend.html +4 -4
- data/manual/html/date.html +5 -5
- data/manual/html/definitions.html +4 -4
- data/manual/html/depends.html +4 -4
- data/manual/html/details.html +4 -4
- data/manual/html/disabled.html +4 -4
- data/manual/html/duration.html +4 -4
- data/manual/html/efficiency.html +4 -4
- data/manual/html/effort.html +4 -4
- data/manual/html/email.html +4 -4
- data/manual/html/enabled.html +4 -4
- data/manual/html/end.column.html +4 -4
- data/manual/html/end.html +4 -4
- data/manual/html/end.limit.html +4 -4
- data/manual/html/end.report.html +5 -5
- data/manual/html/end.timesheet.html +4 -4
- data/manual/html/endcredit.html +4 -4
- data/manual/html/epilog.html +5 -5
- data/manual/html/export.html +4 -4
- data/manual/html/extend.html +4 -4
- data/manual/html/fail.html +43 -8
- data/manual/html/fdl.html +4 -4
- data/manual/html/flags.account.html +4 -4
- data/manual/html/flags.html +4 -4
- data/manual/html/flags.journalentry.html +4 -4
- data/manual/html/flags.report.html +5 -5
- data/manual/html/flags.resource.html +4 -4
- data/manual/html/flags.statussheet.html +4 -4
- data/manual/html/flags.task.html +4 -4
- data/manual/html/flags.timesheet.html +4 -4
- data/manual/html/fontcolor.column.html +43 -8
- data/manual/html/footer.html +5 -5
- data/manual/html/formats.html +5 -5
- data/manual/html/functions.html +4 -4
- data/manual/html/gapduration.html +4 -4
- data/manual/html/gaplength.html +4 -4
- data/manual/html/halign.center.html +4 -4
- data/manual/html/halign.column.html +43 -8
- data/manual/html/halign.left.html +4 -4
- data/manual/html/halign.right.html +4 -4
- data/manual/html/hasalert.html +4 -4
- data/manual/html/header.html +5 -5
- data/manual/html/headline.html +7 -7
- data/manual/html/height.html +72 -0
- data/manual/html/hideaccount.html +46 -11
- data/manual/html/hidejournalentry.html +5 -5
- data/manual/html/hidereport.html +43 -8
- data/manual/html/hideresource.html +44 -9
- data/manual/html/hidetask.html +44 -9
- data/manual/html/icalreport.html +4 -4
- data/manual/html/include.macro.html +4 -4
- data/manual/html/include.project.html +4 -4
- data/manual/html/include.properties.html +4 -4
- data/manual/html/index.html +2 -1
- data/manual/html/inherit.extend.html +4 -4
- data/manual/html/interval1.html +4 -4
- data/manual/html/interval2.html +4 -4
- data/manual/html/interval3.html +4 -4
- data/manual/html/interval4.html +4 -4
- data/manual/html/isactive.html +4 -4
- data/manual/html/ischildof.html +4 -4
- data/manual/html/isdependencyof.html +4 -4
- data/manual/html/isdutyof.html +4 -4
- data/manual/html/isfeatureof.html +4 -4
- data/manual/html/isleaf.html +4 -4
- data/manual/html/ismilestone.html +4 -4
- data/manual/html/isongoing.html +4 -4
- data/manual/html/isresource.html +4 -4
- data/manual/html/isresponsibilityof.html +4 -4
- data/manual/html/istask.html +4 -4
- data/manual/html/journalattributes.html +11 -7
- data/manual/html/journalentry.html +4 -4
- data/manual/html/journalmode.html +5 -5
- data/manual/html/leaveallowance.html +5 -5
- data/manual/html/leaves.html +5 -6
- data/manual/html/left.html +5 -5
- data/manual/html/length.html +4 -4
- data/manual/html/limits.allocate.html +4 -4
- data/manual/html/limits.html +4 -4
- data/manual/html/limits.resource.html +4 -4
- data/manual/html/limits.task.html +4 -4
- data/manual/html/listitem.column.html +4 -4
- data/manual/html/listtype.column.html +4 -4
- data/manual/html/loadunit.html +5 -5
- data/manual/html/logicalexpression.html +8 -44
- data/manual/html/logicalflagexpression.html +4 -4
- data/manual/html/macro.html +4 -4
- data/manual/html/managers.html +4 -4
- data/manual/html/mandatory.html +4 -4
- data/manual/html/maxend.html +4 -4
- data/manual/html/maximum.html +5 -5
- data/manual/html/maxstart.html +4 -4
- data/manual/html/milestone.html +4 -4
- data/manual/html/minend.html +4 -4
- data/manual/html/minimum.html +5 -5
- data/manual/html/minstart.html +4 -4
- data/manual/html/monthlymax.html +5 -5
- data/manual/html/monthlymin.html +5 -5
- data/manual/html/navbar.html +10 -4
- data/manual/html/navigator.html +4 -4
- data/manual/html/newtask.html +4 -4
- data/manual/html/nikureport.html +4 -4
- data/manual/html/note.task.html +4 -4
- data/manual/html/now.html +4 -4
- data/manual/html/numberformat.html +5 -5
- data/manual/html/onend.html +4 -4
- data/manual/html/onstart.html +4 -4
- data/manual/html/opennodes.html +5 -5
- data/manual/html/overtime.booking.html +4 -4
- data/manual/html/period.column.html +4 -4
- data/manual/html/period.limit.html +4 -4
- data/manual/html/period.report.html +5 -5
- data/manual/html/period.task.html +4 -4
- data/manual/html/persistent.html +4 -4
- data/manual/html/precedes.html +4 -4
- data/manual/html/priority.html +4 -4
- data/manual/html/priority.timesheet.html +4 -4
- data/manual/html/project.html +4 -4
- data/manual/html/projectid.html +4 -4
- data/manual/html/projectid.task.html +4 -4
- data/manual/html/projectids.html +4 -4
- data/manual/html/projection.html +5 -7
- data/manual/html/prolog.html +5 -5
- data/manual/html/properties.html +11 -5
- data/manual/html/purge.html +5 -5
- data/manual/html/rate.html +4 -4
- data/manual/html/rate.resource.html +4 -4
- data/manual/html/reference.extend.html +4 -4
- data/manual/html/remaining.html +4 -4
- data/manual/html/replace.html +4 -4
- data/manual/html/reportprefix.html +4 -4
- data/manual/html/resource.html +4 -10
- data/manual/html/resourceattributes.html +4 -4
- data/manual/html/resourceprefix.html +4 -4
- data/manual/html/resourcereport.html +28 -10
- data/manual/html/resourceroot.html +5 -5
- data/manual/html/resources.limit.html +4 -4
- data/manual/html/responsible.html +4 -4
- data/manual/html/richtext.extend.html +4 -4
- data/manual/html/right.html +5 -5
- data/manual/html/rollupaccount.html +44 -9
- data/manual/html/rollupresource.html +44 -9
- data/manual/html/rolluptask.html +44 -9
- data/manual/html/scale.column.html +4 -4
- data/manual/html/scenario.html +4 -22
- data/manual/html/scenario.ical.html +4 -4
- data/manual/html/scenarios.export.html +4 -4
- data/manual/html/scenarios.html +5 -5
- data/manual/html/scenariospecific.extend.html +4 -4
- data/manual/html/scheduled.html +4 -4
- data/manual/html/scheduling.html +4 -4
- data/manual/html/select.html +4 -4
- data/manual/html/selfcontained.html +5 -5
- data/manual/html/shift.allocate.html +4 -4
- data/manual/html/shift.html +4 -4
- data/manual/html/shift.resource.html +5 -5
- data/manual/html/shift.task.html +4 -4
- data/manual/html/shift.timesheet.html +4 -4
- data/manual/html/shifts.allocate.html +4 -4
- data/manual/html/shifts.resource.html +4 -4
- data/manual/html/shifts.task.html +4 -4
- data/manual/html/shorttimeformat.html +4 -4
- data/manual/html/sloppy.booking.html +4 -4
- data/manual/html/sloppy.projection.html +5 -5
- data/manual/html/sortaccounts.html +5 -5
- data/manual/html/sortjournalentries.html +5 -5
- data/manual/html/sortresources.html +5 -5
- data/manual/html/sorttasks.html +5 -5
- data/manual/html/start.column.html +4 -4
- data/manual/html/start.html +4 -4
- data/manual/html/start.limit.html +4 -4
- data/manual/html/start.report.html +5 -5
- data/manual/html/startcredit.html +4 -4
- data/manual/html/status.statussheet.html +4 -4
- data/manual/html/status.timesheet.html +4 -4
- data/manual/html/statussheet.html +4 -4
- data/manual/html/statussheetreport.html +4 -4
- data/manual/html/strict.projection.html +5 -5
- data/manual/html/summary.html +4 -4
- data/manual/html/supplement.html +4 -4
- data/manual/html/supplement.resource.html +4 -10
- data/manual/html/supplement.task.html +4 -28
- data/manual/html/tagfile.html +4 -4
- data/manual/html/task.html +4 -28
- data/manual/html/task.statussheet.html +4 -4
- data/manual/html/task.timesheet.html +4 -4
- data/manual/html/taskattributes.html +4 -4
- data/manual/html/taskprefix.html +4 -4
- data/manual/html/taskreport.html +28 -10
- data/manual/html/taskroot.html +5 -5
- data/manual/html/text.extend.html +4 -4
- data/manual/html/textreport.html +27 -9
- data/manual/html/timeformat.html +5 -5
- data/manual/html/timeoff.nikureport.html +4 -4
- data/manual/html/timesheet.html +4 -4
- data/manual/html/timesheetreport.html +23 -5
- data/manual/html/timezone.export.html +4 -4
- data/manual/html/timezone.html +4 -4
- data/manual/html/timezone.report.html +5 -5
- data/manual/html/timezone.shift.html +4 -4
- data/manual/html/timingresolution.html +4 -4
- data/manual/html/title.column.html +4 -4
- data/manual/html/title.html +5 -5
- data/manual/html/toc.html +207 -179
- data/manual/html/tooltip.column.html +45 -10
- data/manual/html/tracereport.html +405 -0
- data/manual/html/trackingscenario.html +6 -6
- data/manual/html/treelevel.html +4 -4
- data/manual/html/vacation.html +4 -4
- data/manual/html/vacation.resource.html +4 -4
- data/manual/html/vacation.shift.html +4 -4
- data/manual/html/warn.html +43 -8
- data/manual/html/weeklymax.html +5 -5
- data/manual/html/weeklymin.html +5 -5
- data/manual/html/weekstartsmonday.html +4 -4
- data/manual/html/weekstartssunday.html +6 -6
- data/manual/html/width.column.html +6 -6
- data/manual/html/width.html +72 -0
- data/manual/html/work.html +4 -4
- data/manual/html/workinghours.project.html +4 -4
- data/manual/html/workinghours.resource.html +4 -4
- data/manual/html/workinghours.shift.html +4 -4
- data/manual/html/yearlyworkingdays.html +4 -4
- data/spec/Color_spec.rb +60 -0
- data/spec/ProjectBroker_spec.rb +3 -2
- data/spec/StatusSheets_spec.rb +5 -4
- data/spec/TableColumnSorter_spec.rb +78 -0
- data/spec/TimeSheets_spec.rb +6 -2
- data/spec/Tj3Daemon_spec.rb +2 -2
- data/spec/TraceReport_spec.rb +117 -0
- data/taskjuggler.gemspec +1 -1
- data/test/MessageChecker.rb +3 -1
- data/test/ReferenceGenerator.rb +1 -1
- data/test/TestSuite/CSV-Reports/Leave.tjp +1 -1
- data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +3 -0
- data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +9 -0
- data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +19 -16
- data/test/TestSuite/CSV-Reports/refs/weekly.csv +1 -0
- data/test/TestSuite/Export-Reports/refs/LogicalExpression.tjp +14 -2
- data/test/TestSuite/Export-Reports/refs/tutorial.tjp +98 -86
- data/test/TestSuite/Scheduler/Correct/Leaves.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/Leave.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +9 -1
- data/test/TestSuite/Syntax/Correct/TraceReport.tjp +10 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +10 -4
- data/test/test_CSV-Reports.rb +3 -3
- data/test/test_Export-Reports.rb +91 -86
- data/test/test_Journal.rb +15 -12
- data/test/test_Limits.rb +3 -3
- data/test/test_Project.rb +1 -2
- data/test/test_ProjectFileScanner.rb +1 -1
- data/test/test_PropertySet.rb +1 -1
- data/test/test_Query.rb +5 -6
- data/test/test_ReportGenerator.rb +15 -7
- data/test/test_RichText.rb +4 -3
- data/test/test_Scheduler.rb +19 -7
- data/test/test_ShiftAssignments.rb +2 -2
- data/test/test_SimpleQueryExpander.rb +29 -2
- data/test/test_Syntax.rb +14 -5
- metadata +49 -10
- data/lib/taskjuggler/LogFile.rb +0 -73
@@ -306,8 +306,8 @@ EOT
|
|
306
306
|
'journalMode' => a('journalMode'),
|
307
307
|
'journalAttributes' => a('journalAttributes'),
|
308
308
|
'sortJournalEntries' => a('sortJournalEntries'),
|
309
|
-
'costAccount' => a('
|
310
|
-
'revenueAccount' => a('
|
309
|
+
'costAccount' => a('costaccount'),
|
310
|
+
'revenueAccount' => a('revenueaccount') }
|
311
311
|
query = Query.new(queryAttrs)
|
312
312
|
|
313
313
|
# Calculate the number of working days in the report interval.
|
@@ -440,8 +440,8 @@ EOT
|
|
440
440
|
'journalMode' => a('journalMode'),
|
441
441
|
'journalAttributes' => a('journalAttributes'),
|
442
442
|
'sortJournalEntries' => a('sortJournalEntries'),
|
443
|
-
'costAccount' => a('
|
444
|
-
'revenueAccount' => a('
|
443
|
+
'costAccount' => a('costaccount'),
|
444
|
+
'revenueAccount' => a('revenueaccount') }
|
445
445
|
query = Query.new(queryAttrs)
|
446
446
|
|
447
447
|
timeOffId = @report.get('timeOffId')
|
@@ -18,6 +18,7 @@ require 'taskjuggler/reports/AccountListRE'
|
|
18
18
|
require 'taskjuggler/reports/TextReport'
|
19
19
|
require 'taskjuggler/reports/TaskListRE'
|
20
20
|
require 'taskjuggler/reports/ResourceListRE'
|
21
|
+
require 'taskjuggler/reports/TraceReport'
|
21
22
|
require 'taskjuggler/reports/TagFile'
|
22
23
|
require 'taskjuggler/reports/TjpExportRE'
|
23
24
|
require 'taskjuggler/reports/StatusSheetReport'
|
@@ -45,6 +46,7 @@ class TaskJuggler
|
|
45
46
|
# Create a new report object.
|
46
47
|
def initialize(project, id, name, parent)
|
47
48
|
super(project.reports, id, name, parent)
|
49
|
+
@messageHandler = MessageHandlerInstance.instance
|
48
50
|
checkFileName(name)
|
49
51
|
project.addReport(self)
|
50
52
|
|
@@ -129,6 +131,8 @@ class TaskJuggler
|
|
129
131
|
@content = TextReport.new(self)
|
130
132
|
when :taskreport
|
131
133
|
@content = TaskListRE.new(self)
|
134
|
+
when :tracereport
|
135
|
+
@content = TraceReport.new(self)
|
132
136
|
when :statusSheet
|
133
137
|
@content = StatusSheetReport.new(self)
|
134
138
|
when :timeSheet
|
@@ -154,22 +158,6 @@ class TaskJuggler
|
|
154
158
|
@project.reportContexts.first.report.get('interactive')
|
155
159
|
end
|
156
160
|
|
157
|
-
def error(id, message)
|
158
|
-
if message && !message.empty?
|
159
|
-
@project.messageHandler.error(id, message, @sourceFileInfo)
|
160
|
-
else
|
161
|
-
# We have no message, so the error has already been reported to the
|
162
|
-
# MessageHandler. Just trigger another exception to signal the error.
|
163
|
-
raise TjException
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def warning(id, message)
|
168
|
-
if message && !message.empty?
|
169
|
-
@project.messageHandler.warning(id, message, @sourceFileInfo)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
161
|
private
|
174
162
|
# Convenience function to access a report attribute
|
175
163
|
def a(attribute)
|
@@ -187,7 +175,7 @@ class TaskJuggler
|
|
187
175
|
return nil
|
188
176
|
end
|
189
177
|
|
190
|
-
html = HTMLDocument.new
|
178
|
+
html = HTMLDocument.new
|
191
179
|
head = html.generateHead(@project['name'] + " - #{get('title') || @name}",
|
192
180
|
'description' => 'TaskJuggler Report',
|
193
181
|
'keywords' => 'taskjuggler, project, management')
|
@@ -347,7 +335,7 @@ EOT
|
|
347
335
|
begin
|
348
336
|
f = @name == '.' ? $stdout :
|
349
337
|
File.new(((@name[0] == '/' ? '' : @project.outputDir) +
|
350
|
-
@name + '.
|
338
|
+
@name + '.ics').untaint, 'w')
|
351
339
|
f.puts "#{@content.to_iCal}"
|
352
340
|
rescue IOError, SystemCallError
|
353
341
|
error('write_ical', "Cannot write to file #{@name}.\n#{$!}")
|
@@ -48,25 +48,25 @@ class TaskJuggler
|
|
48
48
|
|
49
49
|
# Take the complete account list and remove all accounts that are matching
|
50
50
|
# the hide expression, the rollup Expression or are not a descendent of
|
51
|
-
#
|
51
|
+
# accountroot.
|
52
52
|
def filterAccountList(list_, hideExpr, rollupExpr, openNodes)
|
53
53
|
list = PropertyList.new(list_)
|
54
|
-
if (
|
55
|
-
# Remove all accounts that are not descendents of the
|
56
|
-
list.delete_if { |account| !account.isChildOf?(
|
54
|
+
if (accountroot = a('accountroot'))
|
55
|
+
# Remove all accounts that are not descendents of the accountroot.
|
56
|
+
list.delete_if { |account| !account.isChildOf?(accountroot) }
|
57
57
|
end
|
58
58
|
|
59
59
|
standardFilterOps(list, hideExpr, rollupExpr, openNodes, nil,
|
60
|
-
|
60
|
+
accountroot)
|
61
61
|
end
|
62
62
|
|
63
63
|
# Take the complete task list and remove all tasks that are matching the
|
64
64
|
# hide expression, the rollup Expression or are not a descendent of
|
65
|
-
#
|
65
|
+
# taskroot. In case resource is not nil, a task is only included if
|
66
66
|
# the resource is allocated to it in any of the reported scenarios.
|
67
67
|
def filterTaskList(list_, resource, hideExpr, rollupExpr, openNodes)
|
68
68
|
list = PropertyList.new(list_)
|
69
|
-
if (taskRoot = a('
|
69
|
+
if (taskRoot = a('taskroot'))
|
70
70
|
# Remove all tasks that are not descendents of the taskRoot.
|
71
71
|
list.delete_if { |task| !task.isChildOf?(taskRoot) }
|
72
72
|
end
|
@@ -94,11 +94,11 @@ class TaskJuggler
|
|
94
94
|
|
95
95
|
# Take the complete resource list and remove all resources that are matching
|
96
96
|
# the hide expression, the rollup Expression or are not a descendent of
|
97
|
-
#
|
97
|
+
# resourceroot. In case task is not nil, a resource is only included if
|
98
98
|
# it is assigned to the task in any of the reported scenarios.
|
99
99
|
def filterResourceList(list_, task, hideExpr, rollupExpr, openNodes)
|
100
100
|
list = PropertyList.new(list_)
|
101
|
-
if (resourceRoot = a('
|
101
|
+
if (resourceRoot = a('resourceroot'))
|
102
102
|
# Remove all resources that are not descendents of the resourceRoot.
|
103
103
|
list.delete_if { |resource| !resource.isChildOf?(resourceRoot) }
|
104
104
|
end
|
@@ -38,8 +38,8 @@ class TaskJuggler
|
|
38
38
|
'journalMode' => @report.get('journalMode'),
|
39
39
|
'journalAttributes' => @report.get('journalAttributes'),
|
40
40
|
'sortJournalEntries' => @report.get('sortJournalEntries'),
|
41
|
-
'costAccount' => @report.get('
|
42
|
-
'revenueAccount' => @report.get('
|
41
|
+
'costAccount' => @report.get('costaccount'),
|
42
|
+
'revenueAccount' => @report.get('revenueaccount')
|
43
43
|
}
|
44
44
|
@query = Query.new(queryAttrs)
|
45
45
|
if (@parent = @project.reportContexts.last)
|
@@ -82,17 +82,17 @@ class TaskJuggler
|
|
82
82
|
queryAttrs = { 'project' => @project,
|
83
83
|
'scopeProperty' => nil,
|
84
84
|
'scenarioIdx' => scenarioIdx,
|
85
|
-
'loadUnit' =>
|
86
|
-
'numberFormat' =>
|
87
|
-
'timeFormat' =>
|
85
|
+
'loadUnit' => :days,
|
86
|
+
'numberFormat' => RealFormat.new([ '-', '', '', '.', 1]),
|
87
|
+
'timeFormat' => "%Y-%m-%d",
|
88
88
|
'currencyFormat' => a('currencyFormat'),
|
89
89
|
'start' => a('start'), 'end' => a('end'),
|
90
90
|
'hideJournalEntry' => a('hideJournalEntry'),
|
91
91
|
'journalMode' => a('journalMode'),
|
92
92
|
'journalAttributes' => a('journalAttributes'),
|
93
93
|
'sortJournalEntries' => a('sortJournalEntries'),
|
94
|
-
'costAccount' => a('
|
95
|
-
'revenueAccount' => a('
|
94
|
+
'costAccount' => a('costaccount'),
|
95
|
+
'revenueAccount' => a('revenueaccount') }
|
96
96
|
resourceList.query = Query.new(queryAttrs)
|
97
97
|
resourceList.sort!
|
98
98
|
|
@@ -129,7 +129,7 @@ class TaskJuggler
|
|
129
129
|
# all it's sub tasks.
|
130
130
|
entries = @project['journal'].
|
131
131
|
currentEntriesR(a('end'), task, 0, a('start') + 1,
|
132
|
-
resourceList.query
|
132
|
+
resourceList.query)
|
133
133
|
next if entries.empty?
|
134
134
|
|
135
135
|
manager.responsibilities << ManagerResponsibilities.new(task, entries)
|
@@ -29,14 +29,16 @@ class TaskJuggler
|
|
29
29
|
|
30
30
|
@@propertiesById = {
|
31
31
|
# ID Header Indent Align Scen Spec.
|
32
|
+
'activetasks' => [ 'Active Tasks', true, :right, true ],
|
32
33
|
'annualleave' => [ 'Annual Leave', true, :right, true ],
|
33
|
-
'annualleavebalance'=> [ 'Annual Leave Balance', false,
|
34
|
+
'annualleavebalance'=> [ 'Annual Leave Balance', false, :right, true ],
|
34
35
|
'alert' => [ 'Alert', true, :left, false ],
|
35
36
|
'alertmessages' => [ 'Alert Messages', false, :left, false ],
|
36
37
|
'alertsummaries' => [ 'Alert Summaries', false, :left, false ],
|
37
38
|
'alerttrend' => [ 'Alert Trend', false, :left, false ],
|
38
39
|
'balance' => [ 'Balance', true, :right, true ],
|
39
40
|
'bsi' => [ 'BSI', false, :left, false ],
|
41
|
+
'closedtasks' => [ 'Closed Tasks', true, :right, true ],
|
40
42
|
'complete' => [ 'Completion', false, :right, true ],
|
41
43
|
'cost' => [ 'Cost', true, :right, true ],
|
42
44
|
'duration' => [ 'Duration', true, :right, true ],
|
@@ -57,6 +59,7 @@ class TaskJuggler
|
|
57
59
|
'line' => [ 'Line No.', false, :right, false ],
|
58
60
|
'name' => [ 'Name', true, :left, false ],
|
59
61
|
'no' => [ 'No.', false, :right, false ],
|
62
|
+
'opentasks' => [ 'Open Tasks', true, :right, true ],
|
60
63
|
'precursors' => [ 'Precursors', false, :left, true ],
|
61
64
|
'rate' => [ 'Rate', true, :right, true ],
|
62
65
|
'resources' => [ 'Resources', false, :left, true ],
|
@@ -208,33 +211,37 @@ class TaskJuggler
|
|
208
211
|
# If we have user specified dates for the report period or the column
|
209
212
|
# period, we don't adjust the period. This flag is used to mark if we
|
210
213
|
# have user-provided values.
|
211
|
-
|
214
|
+
doNotAdjustStart = false
|
215
|
+
doNotAdjustEnd = false
|
212
216
|
|
213
217
|
# Determine the start date for the column.
|
214
218
|
if columnDef.start
|
215
219
|
# We have a user-specified, column specific start date.
|
216
220
|
rStart = columnDef.start
|
217
|
-
|
221
|
+
doNotAdjustStart = true
|
218
222
|
else
|
219
223
|
# Use the report start date.
|
220
224
|
rStart = a('start')
|
221
|
-
|
225
|
+
doNotAdjustStart = true if rStart != @project['start']
|
222
226
|
end
|
223
227
|
|
224
228
|
if columnDef.end
|
225
229
|
rEnd = columnDef.end
|
226
|
-
|
230
|
+
doNotAdjustEnd = true
|
227
231
|
else
|
228
232
|
rEnd = a('end')
|
229
|
-
|
233
|
+
doNotAdjustEnd = true if rEnd != @project['end']
|
230
234
|
end
|
235
|
+
origStart = rStart
|
236
|
+
origEnd = rEnd
|
231
237
|
|
232
238
|
# Save the unadjusted dates to the columns Hash.
|
233
239
|
@columns[columnDef] = TableReportColumn.new(rStart, rEnd)
|
234
240
|
|
235
241
|
# If the task list is empty or the user has provided a custom start or
|
236
242
|
# end date, we don't touch the report period.
|
237
|
-
return if tasks.empty? || scenarios.empty? ||
|
243
|
+
return if tasks.empty? || scenarios.empty? ||
|
244
|
+
(doNotAdjustStart && doNotAdjustEnd)
|
238
245
|
|
239
246
|
# Find the start date of the earliest tasks included in the report and
|
240
247
|
# the end date of the last included tasks.
|
@@ -289,19 +296,21 @@ class TaskJuggler
|
|
289
296
|
margin = entry[0] * entry[2]
|
290
297
|
minWidth = entry[0] * entry[1] if minWidth < entry[0] * entry[1]
|
291
298
|
else
|
292
|
-
|
299
|
+
doNotAdjustStart = doNotAdjustEnd = true
|
293
300
|
end
|
294
301
|
|
295
|
-
unless
|
302
|
+
unless doNotAdjustStart && doNotAdjustEnd
|
296
303
|
if minWidth > (rEnd - rStart + 1)
|
297
|
-
margin
|
304
|
+
margin = (minWidth - (rEnd - rStart + 1)) / 2
|
298
305
|
end
|
299
306
|
|
300
307
|
rStart -= margin
|
301
308
|
rEnd += margin
|
302
309
|
|
303
310
|
# Save the adjusted dates to the columns Hash.
|
304
|
-
@columns[columnDef] = TableReportColumn.new(
|
311
|
+
@columns[columnDef] = TableReportColumn.new(
|
312
|
+
doNotAdjustStart ? origStart : rStart,
|
313
|
+
doNotAdjustEnd ? origEnd : rEnd)
|
305
314
|
end
|
306
315
|
end
|
307
316
|
|
@@ -390,7 +399,7 @@ class TaskJuggler
|
|
390
399
|
line.no = no
|
391
400
|
line.lineNo = lineNo
|
392
401
|
line.subLineNo = @table.lines
|
393
|
-
setIndent(line, a('
|
402
|
+
setIndent(line, a('accountroot'), accountList.treeMode?)
|
394
403
|
|
395
404
|
# Generate a cell for each column in this line.
|
396
405
|
a('columns').each do |columnDef|
|
@@ -437,7 +446,7 @@ class TaskJuggler
|
|
437
446
|
line.no = no unless scopeLine
|
438
447
|
line.lineNo = lineNo
|
439
448
|
line.subLineNo = @table.lines
|
440
|
-
setIndent(line, a('
|
449
|
+
setIndent(line, a('taskroot'), taskList.treeMode?)
|
441
450
|
|
442
451
|
# Generate a cell for each column in this line.
|
443
452
|
a('columns').each do |columnDef|
|
@@ -494,7 +503,7 @@ class TaskJuggler
|
|
494
503
|
line.no = no unless scopeLine
|
495
504
|
line.lineNo = lineNo
|
496
505
|
line.subLineNo = @table.lines
|
497
|
-
setIndent(line, a('
|
506
|
+
setIndent(line, a('resourceroot'), resourceList.treeMode?)
|
498
507
|
|
499
508
|
# Generate a cell for each column in this line.
|
500
509
|
a('columns').each do |column|
|
@@ -953,7 +962,7 @@ class TaskJuggler
|
|
953
962
|
query.scopeProperty = nil
|
954
963
|
query.attributeId = 'effort'
|
955
964
|
query.startIdx = @project.dateToIdx(t)
|
956
|
-
query.endIdx = @project.dateToIdx(nextT)
|
965
|
+
query.endIdx = @project.dateToIdx(nextT)
|
957
966
|
query.process
|
958
967
|
workLoad = query.to_num
|
959
968
|
scaledWorkLoad = query.to_s
|
@@ -187,17 +187,17 @@ EOT
|
|
187
187
|
queryAttrs = { 'project' => @project,
|
188
188
|
'scopeProperty' => nil,
|
189
189
|
'scenarioIdx' => scenarioIdx,
|
190
|
-
'loadUnit' =>
|
191
|
-
'numberFormat' =>
|
192
|
-
'timeFormat' =>
|
190
|
+
'loadUnit' => :days,
|
191
|
+
'numberFormat' => RealFormat.new([ '-', '', '', '.', 1]),
|
192
|
+
'timeFormat' => "%Y-%m-%d",
|
193
193
|
'currencyFormat' => a('currencyFormat'),
|
194
194
|
'start' => from, 'end' => to,
|
195
195
|
'hideJournalEntry' => a('hideJournalEntry'),
|
196
196
|
'journalMode' => a('journalMode'),
|
197
197
|
'journalAttributes' => a('journalAttributes'),
|
198
198
|
'sortJournalEntries' => a('sortJournalEntries'),
|
199
|
-
'costAccount' => a('
|
200
|
-
'revenueAccount' => a('
|
199
|
+
'costAccount' => a('costaccount'),
|
200
|
+
'revenueAccount' => a('revenueaccount') }
|
201
201
|
resourceList.query = Query.new(queryAttrs)
|
202
202
|
resourceList.sort!
|
203
203
|
|
@@ -0,0 +1,251 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = TraceReport.rb -- The TaskJuggler III Project Management Software
|
5
|
+
#
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
|
+
# by Chris Schlaeger <chris@linux.com>
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify
|
10
|
+
# it under the terms of version 2 of the GNU General Public License as
|
11
|
+
# published by the Free Software Foundation.
|
12
|
+
#
|
13
|
+
|
14
|
+
require 'taskjuggler/reports/ReportBase'
|
15
|
+
require 'taskjuggler/reports/CSVFile'
|
16
|
+
require 'taskjuggler/reports/ChartPlotter'
|
17
|
+
require 'taskjuggler/TableColumnSorter'
|
18
|
+
require 'taskjuggler/MessageHandler'
|
19
|
+
|
20
|
+
class TaskJuggler
|
21
|
+
|
22
|
+
# The trace report is used to periodically snapshot a specific list of
|
23
|
+
# property attributes and add them to a CSV file.
|
24
|
+
class TraceReport < ReportBase
|
25
|
+
|
26
|
+
include MessageHandler
|
27
|
+
|
28
|
+
# Create a new object and set some default values.
|
29
|
+
def initialize(report)
|
30
|
+
super
|
31
|
+
@table = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# Generate the table in the intermediate format.
|
35
|
+
def generateIntermediateFormat
|
36
|
+
super
|
37
|
+
|
38
|
+
queryAttrs = { 'project' => @project,
|
39
|
+
'scopeProperty' => nil,
|
40
|
+
'loadUnit' => a('loadUnit'),
|
41
|
+
'numberFormat' => a('numberFormat'),
|
42
|
+
# We use a hardcoded %Y-%m-%d format for tracereports.
|
43
|
+
'timeFormat' => "%Y-%m-%d",
|
44
|
+
'currencyFormat' => a('currencyFormat'),
|
45
|
+
'start' => a('start'), 'end' => a('end'),
|
46
|
+
'hideJournalEntry' => a('hideJournalEntry'),
|
47
|
+
'journalMode' => a('journalMode'),
|
48
|
+
'journalAttributes' => a('journalAttributes'),
|
49
|
+
'sortJournalEntries' => a('sortJournalEntries'),
|
50
|
+
'costAccount' => a('costaccount'),
|
51
|
+
'revenueAccount' => a('revenueaccount') }
|
52
|
+
query = Query.new(queryAttrs)
|
53
|
+
|
54
|
+
# Prepare the account list.
|
55
|
+
accountList = PropertyList.new(@project.accounts)
|
56
|
+
accountList.setSorting(a('sortAccounts'))
|
57
|
+
accountList.query = query
|
58
|
+
accountList = filterAccountList(accountList, a('hideAccount'),
|
59
|
+
a('rollupAccount'), a('openNodes'))
|
60
|
+
accountList.sort!
|
61
|
+
|
62
|
+
# Prepare the resource list.
|
63
|
+
resourceList = PropertyList.new(@project.resources)
|
64
|
+
resourceList.setSorting(a('sortResources'))
|
65
|
+
resourceList.query = query
|
66
|
+
resourceList = filterTaskList(resourceList, nil, a('hideResource'),
|
67
|
+
a('rollupResource'), a('openNodes'))
|
68
|
+
resourceList.sort!
|
69
|
+
|
70
|
+
# Prepare the task list.
|
71
|
+
taskList = PropertyList.new(@project.tasks)
|
72
|
+
taskList.includeAdopted
|
73
|
+
taskList.setSorting(a('sortTasks'))
|
74
|
+
taskList.query = query
|
75
|
+
taskList = filterTaskList(taskList, nil, a('hideTask'), a('rollupTask'),
|
76
|
+
a('openNodes'))
|
77
|
+
taskList.sort!
|
78
|
+
|
79
|
+
@fileName = ((@report.name[0] == '/' ? '' : @project.outputDir) +
|
80
|
+
@report.name + '.csv').untaint
|
81
|
+
|
82
|
+
# Generate the table header.
|
83
|
+
headers = [ 'Date' ] +
|
84
|
+
generatePropertyListHeader(accountList, query) +
|
85
|
+
generatePropertyListHeader(resourceList, query) +
|
86
|
+
generatePropertyListHeader(taskList, query)
|
87
|
+
|
88
|
+
discontinuedColumns = 0
|
89
|
+
if File.exists?(@fileName)
|
90
|
+
begin
|
91
|
+
@table = CSVFile.new.read(@fileName)
|
92
|
+
rescue
|
93
|
+
error('tr_cannot_read_csv',
|
94
|
+
"Cannot read CSV file #{@fileName}: #{$!}")
|
95
|
+
end
|
96
|
+
|
97
|
+
if @table[0] != headers
|
98
|
+
# Some columns have changed. We move all discontinued columns to the
|
99
|
+
# last columns and rearrange the others according to the new
|
100
|
+
# headers. New columns will be filled with nil in previous rows.
|
101
|
+
sorter = TableColumnSorter.new(@table)
|
102
|
+
@table = sorter.sort(headers)
|
103
|
+
discontinuedColumns = sorter.discontinuedColumns
|
104
|
+
end
|
105
|
+
else
|
106
|
+
@table = [ headers ]
|
107
|
+
end
|
108
|
+
|
109
|
+
# Convert empty strings into nil objects and dates in %Y-%m-%d format
|
110
|
+
# into TjTime objects.
|
111
|
+
@table.each do |line|
|
112
|
+
line.length.times do |i|
|
113
|
+
if line[i] == ''
|
114
|
+
line[i] = nil
|
115
|
+
elsif line[i].is_a?(String) && /\d{4}-\d{2}-\d{2}/ =~ line[i]
|
116
|
+
line[i] = TjTime.new(line[i])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
query = @project.reportContexts.last.query.dup
|
122
|
+
dateTag = @project['now'].midnight
|
123
|
+
|
124
|
+
idx = @table.index { |line| line[0] == dateTag }
|
125
|
+
discColumnValues = discontinuedColumns > 0 ?
|
126
|
+
Array.new(discontinuedColumns, nil) : []
|
127
|
+
if idx
|
128
|
+
# We already have an entry for the current date. All old values of
|
129
|
+
# this line will be overwritten with the current values. The old
|
130
|
+
# values in the discontinued columns will be kept.
|
131
|
+
if discontinuedColumns > 0
|
132
|
+
discColumnValues = @table[idx][headers.length..-1]
|
133
|
+
end
|
134
|
+
@table[idx] = []
|
135
|
+
else
|
136
|
+
# Append a new line of values to the table.
|
137
|
+
@table << []
|
138
|
+
idx = -1
|
139
|
+
end
|
140
|
+
# The first entry is always the current date.
|
141
|
+
@table[idx] << dateTag
|
142
|
+
|
143
|
+
# Now add the new values to the line
|
144
|
+
generatePropertyListValues(idx, accountList, query)
|
145
|
+
generatePropertyListValues(idx, resourceList, query)
|
146
|
+
generatePropertyListValues(idx, taskList, query)
|
147
|
+
|
148
|
+
# Fill the discontinued columns with old values or nil.
|
149
|
+
@table[idx] += discColumnValues
|
150
|
+
|
151
|
+
# Sort the table by ascending first column dates. We need to ensure that
|
152
|
+
# the header remains the first line in the table.
|
153
|
+
@table.sort! { |l1, l2| l1[0].is_a?(String) ? -1 :
|
154
|
+
(l2[0].is_a?(String) ? 1 : l1[0] <=> l2[0]) }
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_html
|
158
|
+
html = []
|
159
|
+
html << rt_to_html('header')
|
160
|
+
|
161
|
+
begin
|
162
|
+
plotter = ChartPlotter.new(a('width'), a('height'), @table)
|
163
|
+
plotter.generate
|
164
|
+
html << plotter.to_svg
|
165
|
+
rescue ChartPlotterError => exception
|
166
|
+
warning('chartPlotterError', exception.message, @report.sourceFileInfo)
|
167
|
+
end
|
168
|
+
|
169
|
+
html << rt_to_html('footer')
|
170
|
+
|
171
|
+
html
|
172
|
+
end
|
173
|
+
|
174
|
+
def to_csv
|
175
|
+
# Convert all TjTime values into String with format %Y-%m-%d and nil
|
176
|
+
# objects into empty Strings.
|
177
|
+
@table.each do |line|
|
178
|
+
line.length.times do |i|
|
179
|
+
if line[i].nil?
|
180
|
+
line[i] = ''
|
181
|
+
elsif line[i].is_a?(TjTime)
|
182
|
+
line[i] = line[i].to_s('%Y-%m-%d')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
@table
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def generatePropertyListHeader(propertyList, query)
|
193
|
+
headers = []
|
194
|
+
query = query.dup
|
195
|
+
a('columns').each do |columnDescr|
|
196
|
+
query.attributeId = columnDescr.id
|
197
|
+
a('scenarios').each do |scenarioIdx|
|
198
|
+
query.scenarioIdx = scenarioIdx
|
199
|
+
propertyList.each do |property|
|
200
|
+
query.property = property
|
201
|
+
|
202
|
+
#adjustColumnPeriod(columnDescr, propertyList, a.get('scenarios'))
|
203
|
+
header = SimpleQueryExpander.new(columnDescr.title, query,
|
204
|
+
@report.sourceFileInfo).expand
|
205
|
+
|
206
|
+
if headers.include?(header)
|
207
|
+
error('trace_columns_not_uniq',
|
208
|
+
"The column title '#{header}' is already used " +
|
209
|
+
"by a previous column. Column titles must be " +
|
210
|
+
"unique!")
|
211
|
+
end
|
212
|
+
|
213
|
+
headers << header
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
headers
|
218
|
+
end
|
219
|
+
|
220
|
+
def generatePropertyListValues(idx, propertyList, query)
|
221
|
+
@report.get('columns').each do |columnDescr|
|
222
|
+
query.attributeId = columnDescr.id
|
223
|
+
|
224
|
+
a('scenarios').each do |scenarioIdx|
|
225
|
+
query.scenarioIdx = scenarioIdx
|
226
|
+
|
227
|
+
propertyList.each do |property|
|
228
|
+
query.property = property
|
229
|
+
|
230
|
+
query.process
|
231
|
+
@table[idx] << query.result
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def columnTitle(property, scenarioIdx, columnDescr)
|
238
|
+
title = columnDescr.title.dup
|
239
|
+
# The title can be parameterized by including mini-queries for the ID
|
240
|
+
# or the name of the property, the scenario id or the attribute ID.
|
241
|
+
title.gsub!(/<-id->/, property.fullId)
|
242
|
+
title.gsub!(/<-scenario->/, @project.scenario(scenarioIdx).id)
|
243
|
+
title.gsub!(/<-name->/, property.name)
|
244
|
+
title.gsub!(/<-attribute->/, columnDescr.id)
|
245
|
+
title
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|