taskjuggler 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/{tasks/missing.rake → .gemtest} +0 -0
- data/CHANGELOG +27 -0
- data/Rakefile +8 -9
- data/bin/tj3 +2 -1
- data/bin/tj3client +2 -1
- data/bin/tj3d +2 -1
- data/bin/tj3man +2 -1
- data/bin/tj3ss_receiver +2 -1
- data/bin/tj3ss_sender +2 -1
- data/bin/tj3ts_receiver +2 -1
- data/bin/tj3ts_sender +2 -1
- data/bin/tj3ts_summary +2 -1
- data/data/tjp.vim +425 -419
- data/examples/Fedora-20/f-20.tjp +2442 -0
- data/examples/Fedora-20/icons/fedoralogo.png +0 -0
- data/examples/Fedora-20/reports.tji +423 -0
- data/lib/header.tmpl +13 -0
- data/lib/taskjuggler/AppConfig.rb +5 -0
- data/lib/taskjuggler/Attributes.rb +22 -0
- data/lib/taskjuggler/Journal.rb +273 -10
- data/lib/taskjuggler/Log.rb +9 -8
- data/lib/taskjuggler/Project.rb +28 -60
- data/lib/taskjuggler/ProjectFileScanner.rb +2 -1
- data/lib/taskjuggler/PropertySet.rb +3 -0
- data/lib/taskjuggler/PropertyTreeNode.rb +4 -0
- data/lib/taskjuggler/Query.rb +2 -1
- data/lib/taskjuggler/Resource.rb +0 -103
- data/lib/taskjuggler/RichText/RTFQuery.rb +42 -4
- data/lib/taskjuggler/SheetHandlerBase.rb +0 -20
- data/lib/taskjuggler/SheetReceiver.rb +23 -21
- data/lib/taskjuggler/Task.rb +3 -5
- data/lib/taskjuggler/TaskJuggler.rb +4 -0
- data/lib/taskjuggler/TaskScenario.rb +81 -103
- data/lib/taskjuggler/TextParser/Scanner.rb +19 -18
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +180 -45
- data/lib/taskjuggler/UTF8String.rb +30 -0
- data/lib/taskjuggler/apps/Tj3.rb +1 -1
- data/lib/taskjuggler/apps/Tj3Man.rb +54 -2
- data/lib/taskjuggler/reports/ICalReport.rb +4 -4
- data/lib/taskjuggler/reports/NikuReport.rb +6 -0
- data/lib/taskjuggler/reports/Report.rb +5 -5
- data/lib/taskjuggler/reports/ReportContext.rb +4 -2
- data/lib/taskjuggler/reports/ResourceListRE.rb +10 -1
- data/lib/taskjuggler/reports/StatusSheetReport.rb +3 -0
- data/lib/taskjuggler/reports/TableReport.rb +8 -3
- data/lib/taskjuggler/reports/TimeSheetReport.rb +3 -0
- data/lib/updateheader.sh +15 -0
- data/manual/Installation +11 -22
- data/manual/Software +17 -3
- data/manual/html/Day_To_Day_Juggling.html +359 -0
- data/manual/html/Getting_Started.html +62 -0
- data/manual/html/How_To_Contribute.html +88 -0
- data/manual/html/Installation.html +172 -0
- data/manual/html/Intro.html +74 -0
- data/manual/html/Reporting_Bugs.html +47 -0
- data/manual/html/Rich_Text_Attributes.html +174 -0
- data/manual/html/Software.html +147 -0
- data/manual/html/TaskJuggler_2x_Migration.html +71 -0
- data/manual/html/TaskJuggler_Internals.html +61 -0
- data/manual/html/The_TaskJuggler_Syntax.html +89 -0
- data/manual/html/Tutorial.html +498 -0
- data/manual/html/account.html +152 -0
- data/manual/html/account.task.html +68 -0
- data/manual/html/accountprefix.html +67 -0
- data/manual/html/active.html +66 -0
- data/manual/html/adopt.task.html +73 -0
- data/manual/html/alert level.html +66 -0
- data/manual/html/alert.html +66 -0
- data/manual/html/allocate.html +92 -0
- data/manual/html/alphabet.html +33 -0
- data/manual/html/alternative.html +77 -0
- data/manual/html/author.html +69 -0
- data/manual/html/balance.html +73 -0
- data/manual/html/booking.resource.html +122 -0
- data/manual/html/booking.task.html +120 -0
- data/manual/html/caption.html +96 -0
- data/manual/html/cellcolor.column.html +71 -0
- data/manual/html/celltext.column.html +68 -0
- data/manual/html/center.html +67 -0
- data/manual/html/charge.html +89 -0
- data/manual/html/chargeset.html +73 -0
- data/manual/html/columnid.html +358 -0
- data/manual/html/columns.html +73 -0
- data/manual/html/complete.html +80 -0
- data/manual/html/copyright.html +97 -0
- data/manual/html/credit.html +117 -0
- data/{benchmarks → manual/html}/css/tjmanual.css +0 -0
- data/{benchmarks → manual/html}/css/tjreport.css +0 -0
- data/manual/html/currency.html +120 -0
- data/manual/html/currencyformat.html +99 -0
- data/manual/html/dailymax.html +144 -0
- data/manual/html/dailymin.html +132 -0
- data/manual/html/dailyworkinghours.html +90 -0
- data/manual/html/date.extend.html +77 -0
- data/manual/html/date.html +100 -0
- data/manual/html/definitions.html +94 -0
- data/manual/html/depends.html +110 -0
- data/manual/html/details.html +69 -0
- data/manual/html/disabled.html +85 -0
- data/manual/html/duration.html +133 -0
- data/manual/html/efficiency.html +93 -0
- data/manual/html/effort.html +134 -0
- data/manual/html/email.html +68 -0
- data/manual/html/enabled.html +69 -0
- data/manual/html/end.column.html +67 -0
- data/manual/html/end.html +87 -0
- data/manual/html/end.limit.html +69 -0
- data/manual/html/end.report.html +99 -0
- data/manual/html/end.timesheet.html +94 -0
- data/manual/html/endcredit.html +110 -0
- data/manual/html/epilog.html +72 -0
- data/manual/html/export.html +197 -0
- data/manual/html/extend.html +87 -0
- data/manual/html/fail.html +69 -0
- data/manual/html/fdl.html +430 -0
- data/manual/html/flags.account.html +66 -0
- data/manual/html/flags.html +66 -0
- data/manual/html/flags.journalentry.html +66 -0
- data/manual/html/flags.report.html +66 -0
- data/manual/html/flags.resource.html +68 -0
- data/manual/html/flags.statussheet.html +66 -0
- data/manual/html/flags.task.html +68 -0
- data/manual/html/flags.timesheet.html +66 -0
- data/manual/html/fontcolor.column.html +71 -0
- data/manual/html/footer.html +72 -0
- data/manual/html/formats.html +80 -0
- data/manual/html/functions.html +78 -0
- data/manual/html/gapduration.html +93 -0
- data/manual/html/gaplength.html +93 -0
- data/manual/html/halign.center.html +66 -0
- data/manual/html/halign.column.html +67 -0
- data/manual/html/halign.left.html +66 -0
- data/manual/html/halign.right.html +66 -0
- data/manual/html/hasalert.html +71 -0
- data/manual/html/header.html +72 -0
- data/manual/html/headline.html +69 -0
- data/manual/html/hidejournalentry.html +69 -0
- data/manual/html/hidereport.html +67 -0
- data/manual/html/hideresource.html +73 -0
- data/manual/html/hidetask.html +73 -0
- data/manual/html/icalreport.html +137 -0
- data/manual/html/include.macro.html +70 -0
- data/manual/html/include.project.html +71 -0
- data/manual/html/include.properties.html +168 -0
- data/manual/html/index.html +18 -0
- data/manual/html/inherit.extend.html +68 -0
- data/manual/html/interval1.html +99 -0
- data/manual/html/interval2.html +98 -0
- data/manual/html/interval3.html +99 -0
- data/manual/html/interval4.html +100 -0
- data/manual/html/isactive.html +67 -0
- data/manual/html/ischildof.html +67 -0
- data/manual/html/isdependencyof.html +75 -0
- data/manual/html/isdutyof.html +71 -0
- data/manual/html/isfeatureof.html +71 -0
- data/manual/html/isleaf.html +66 -0
- data/manual/html/ismilestone.html +67 -0
- data/manual/html/isongoing.html +67 -0
- data/manual/html/isresource.html +66 -0
- data/manual/html/istask.html +66 -0
- data/manual/html/journalattributes.html +107 -0
- data/manual/html/journalentry.html +83 -0
- data/manual/html/journalmode.html +83 -0
- data/manual/html/left.html +66 -0
- data/manual/html/length.html +104 -0
- data/manual/html/limits.allocate.html +72 -0
- data/manual/html/limits.html +72 -0
- data/manual/html/limits.resource.html +80 -0
- data/manual/html/limits.task.html +113 -0
- data/manual/html/listitem.column.html +66 -0
- data/manual/html/listtype.column.html +79 -0
- data/manual/html/loadunit.html +99 -0
- data/manual/html/logicalexpression.html +110 -0
- data/manual/html/logicalflagexpression.html +82 -0
- data/manual/html/macro.html +103 -0
- data/manual/html/managers.html +109 -0
- data/manual/html/mandatory.html +66 -0
- data/manual/html/maxend.html +69 -0
- data/manual/html/maximum.html +99 -0
- data/manual/html/maxstart.html +69 -0
- data/manual/html/milestone.html +71 -0
- data/manual/html/minend.html +69 -0
- data/manual/html/minimum.html +99 -0
- data/manual/html/minstart.html +69 -0
- data/manual/html/monthlymax.html +99 -0
- data/manual/html/monthlymin.html +99 -0
- data/manual/html/navbar.html +513 -0
- data/manual/html/navigator.html +70 -0
- data/manual/html/newtask.html +83 -0
- data/manual/html/nikureport.html +216 -0
- data/manual/html/note.task.html +68 -0
- data/manual/html/now.html +67 -0
- data/manual/html/numberformat.html +85 -0
- data/manual/html/onend.html +68 -0
- data/manual/html/onstart.html +68 -0
- data/manual/html/opennodes.html +66 -0
- data/manual/html/overtime.booking.html +76 -0
- data/manual/html/period.column.html +67 -0
- data/manual/html/period.limit.html +69 -0
- data/manual/html/period.report.html +69 -0
- data/manual/html/period.task.html +69 -0
- data/manual/html/persistent.html +66 -0
- data/manual/html/precedes.html +86 -0
- data/manual/html/priority.html +114 -0
- data/manual/html/priority.timesheet.html +68 -0
- data/manual/html/project.html +88 -0
- data/manual/html/projectid.html +66 -0
- data/manual/html/projectid.task.html +68 -0
- data/manual/html/projectids.html +66 -0
- data/manual/html/projection.html +75 -0
- data/manual/html/prolog.html +72 -0
- data/manual/html/properties.html +64 -0
- data/manual/html/purge.html +69 -0
- data/manual/html/rate.html +66 -0
- data/manual/html/rate.resource.html +68 -0
- data/manual/html/reference.extend.html +77 -0
- data/manual/html/remaining.html +117 -0
- data/manual/html/replace.html +66 -0
- data/manual/html/report.html +333 -0
- data/manual/html/reportprefix.html +67 -0
- data/manual/html/resource.html +194 -0
- data/manual/html/resourceattributes.html +83 -0
- data/manual/html/resourceprefix.html +67 -0
- data/manual/html/resourcereport.html +69 -0
- data/manual/html/resourceroot.html +90 -0
- data/manual/html/resources.limit.html +82 -0
- data/manual/html/responsible.html +69 -0
- data/manual/html/richtext.extend.html +78 -0
- data/manual/html/right.html +66 -0
- data/manual/html/rollupresource.html +92 -0
- data/manual/html/rolluptask.html +69 -0
- data/manual/html/scale.column.html +87 -0
- data/manual/html/scenario.html +123 -0
- data/manual/html/scenario.ical.html +67 -0
- data/manual/html/scenarios.export.html +66 -0
- data/manual/html/scenarios.html +66 -0
- data/manual/html/scenariospecific.extend.html +68 -0
- data/manual/html/scheduled.html +68 -0
- data/manual/html/scheduling.html +74 -0
- data/manual/html/select.html +86 -0
- data/manual/html/selfcontained.html +66 -0
- data/manual/html/shift.html +128 -0
- data/manual/html/shift.resource.html +74 -0
- data/manual/html/shift.task.html +74 -0
- data/manual/html/shift.timesheet.html +70 -0
- data/manual/html/shifts.allocate.html +71 -0
- data/manual/html/shifts.resource.html +73 -0
- data/manual/html/shifts.task.html +73 -0
- data/manual/html/shorttimeformat.html +67 -0
- data/manual/html/sloppy.booking.html +77 -0
- data/manual/html/sloppy.projection.html +66 -0
- data/manual/html/sortjournalentries.html +81 -0
- data/manual/html/sortresources.html +73 -0
- data/manual/html/sorttasks.html +73 -0
- data/manual/html/start.column.html +67 -0
- data/manual/html/start.html +78 -0
- data/manual/html/start.limit.html +69 -0
- data/manual/html/start.report.html +69 -0
- data/manual/html/startcredit.html +68 -0
- data/manual/html/status.statussheet.html +73 -0
- data/manual/html/status.timesheet.html +91 -0
- data/manual/html/statussheet.html +124 -0
- data/manual/html/statussheetreport.html +125 -0
- data/manual/html/strict.projection.html +66 -0
- data/manual/html/summary.html +69 -0
- data/manual/html/supplement.html +108 -0
- data/manual/html/supplement.resource.html +195 -0
- data/manual/html/supplement.task.html +329 -0
- data/manual/html/tagfile.html +73 -0
- data/manual/html/task.html +320 -0
- data/manual/html/task.statussheet.html +74 -0
- data/manual/html/task.timesheet.html +89 -0
- data/manual/html/taskattributes.html +115 -0
- data/manual/html/taskprefix.html +67 -0
- data/manual/html/taskreport.html +69 -0
- data/manual/html/taskroot.html +103 -0
- data/manual/html/text.extend.html +77 -0
- data/manual/html/textreport.html +66 -0
- data/manual/html/timeformat.html +160 -0
- data/manual/html/timeoff.nikureport.html +71 -0
- data/manual/html/timesheet.html +129 -0
- data/manual/html/timesheetreport.html +107 -0
- data/manual/html/timezone.export.html +66 -0
- data/manual/html/timezone.html +72 -0
- data/manual/html/timezone.report.html +66 -0
- data/manual/html/timezone.shift.html +70 -0
- data/manual/html/timingresolution.html +71 -0
- data/manual/html/title.column.html +67 -0
- data/manual/html/title.html +68 -0
- data/manual/html/toc.html +1330 -0
- data/manual/html/tooltip.column.html +72 -0
- data/manual/html/trackingscenario.html +80 -0
- data/manual/html/treelevel.html +66 -0
- data/manual/html/vacation.html +71 -0
- data/manual/html/vacation.resource.html +73 -0
- data/manual/html/vacation.shift.html +71 -0
- data/manual/html/warn.html +69 -0
- data/manual/html/weeklymax.html +99 -0
- data/manual/html/weeklymin.html +99 -0
- data/manual/html/weekstartsmonday.html +66 -0
- data/manual/html/weekstartssunday.html +66 -0
- data/manual/html/width.column.html +66 -0
- data/manual/html/work.html +105 -0
- data/manual/html/workinghours.project.html +102 -0
- data/manual/html/workinghours.resource.html +79 -0
- data/manual/html/workinghours.shift.html +81 -0
- data/manual/html/yearlyworkingdays.html +70 -0
- data/spec/StatusSheets_spec.rb +0 -6
- data/spec/TimeSheets_spec.rb +0 -6
- data/spec/Tj3Daemon_spec.rb +2 -0
- data/spec/support/DaemonControl.rb +10 -0
- data/taskjuggler.gemspec +71 -0
- data/tasks/changelog.rake +2 -2
- data/tasks/gem.rake +50 -21
- data/tasks/manual.rake +1 -1
- data/tasks/rdoc.rake +5 -12
- data/tasks/spec.rake +1 -1
- data/tasks/test.rake +5 -8
- data/test/ReferenceGenerator.rb +91 -0
- data/test/TestSuite/CSV-Reports/refs/resourcereport.csv +4 -4
- data/test/TestSuite/ReportGenerator/Correct/Journal.tjp +21 -0
- data/test/TestSuite/ReportGenerator/Correct/JournalMode.tjp +124 -0
- data/test/TestSuite/ReportGenerator/Correct/refs/Alerts-1.csv +124 -124
- data/test/TestSuite/ReportGenerator/Correct/refs/Journal-1.csv +1 -7
- data/test/TestSuite/ReportGenerator/Correct/refs/Journal-2.csv +7 -3
- data/test/TestSuite/ReportGenerator/Correct/refs/JournalMode-1.csv +79 -0
- data/test/TestSuite/ReportGenerator/Correct/refs/JournalMode-2.csv +208 -0
- data/test/TjpGen.rb +152 -0
- metadata +1290 -741
- data/benchmarks/666tasks.tjp +0 -3183
- data/benchmarks/allocate.tjp +0 -30
- data/benchmarks/allocatedSlots.tjp +0 -1602
- data/benchmarks/booking.tjp +0 -76
- data/benchmarks/depends.tjp +0 -113
- data/benchmarks/gantt.tjp +0 -57
- data/benchmarks/htmltaskreport.tjp +0 -71
- data/benchmarks/icons/details.png +0 -0
- data/benchmarks/icons/flag-green.png +0 -0
- data/benchmarks/icons/flag-red.png +0 -0
- data/benchmarks/icons/flag-yellow.png +0 -0
- data/benchmarks/icons/resource.png +0 -0
- data/benchmarks/icons/resourcegroup.png +0 -0
- data/benchmarks/icons/task.png +0 -0
- data/benchmarks/icons/taskgroup.png +0 -0
- data/benchmarks/icons/trend-down.png +0 -0
- data/benchmarks/icons/trend-flat.png +0 -0
- data/benchmarks/icons/trend-up.png +0 -0
- data/benchmarks/runbench.rb +0 -30
- data/benchmarks/scripts/wz_tooltip.js +0 -1301
- data/gem_spec.rb +0 -37
- data/lib/exchangebug.rb +0 -42
- data/lib/ruby-signal-bug.rb +0 -55
- data/prj_cfg.rb +0 -50
- data/tasks/csts.rake +0 -72
- data/tasks/rcov.rake +0 -14
- data/tasks/rexml_fix.rb +0 -16
- data/tasks/rexml_fix_19.rb +0 -49
- data/tasks/show.rake +0 -21
- data/tasks/stats.rake +0 -25
- data/test/TestSuite/Export-Reports/refs/DST.tjp +0 -60
- data/test/TestSuite/Export-Reports/refs/ReleasePlan.tjp +0 -80
- data/test/TestSuite/Export-Reports/tp.tjp +0 -49
- data/test/TestSuite/HTML-Reports/Alerts.html +0 -424
- data/test/TestSuite/HTML-Reports/TimeSheet.html +0 -79
- data/test/TestSuite/HTML-Reports/css/tjmanual.css +0 -86
- data/test/TestSuite/HTML-Reports/css/tjreport.css +0 -413
- data/test/TestSuite/HTML-Reports/icons/details.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/flag-green.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/flag-red.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/flag-yellow.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/resource.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/resourcegroup.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/task.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/taskgroup.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/trend-down.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/trend-flat.png +0 -0
- data/test/TestSuite/HTML-Reports/icons/trend-up.png +0 -0
- data/test/TestSuite/HTML-Reports/reference.html +0 -51
- data/test/TestSuite/HTML-Reports/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/ReportGenerator/Correct/css/tjmanual.css +0 -86
- data/test/TestSuite/ReportGenerator/Correct/css/tjreport.css +0 -413
- data/test/TestSuite/ReportGenerator/Correct/icons/details.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/resource.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/task.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/trend-down.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/trend-flat.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/trend-up.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/opennodes.tjp +0 -26
- data/test/TestSuite/ReportGenerator/Correct/refs/opennodes-1.csv +0 -2
- data/test/TestSuite/ReportGenerator/Correct/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/Scheduler/Correct/Allocate.html +0 -1075
- data/test/TestSuite/Scheduler/Correct/Duration.html +0 -610
- data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +0 -85
- data/test/TestSuite/Scheduler/Correct/css/tjreport.css +0 -413
- data/test/TestSuite/Scheduler/Correct/icons/details.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/resource.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/task.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-down.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-flat.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-up.png +0 -0
- data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/StatusSheetTemplates/project.tji +0 -35
- data/test/TestSuite/StatusSheetTemplates/project.tjp +0 -56
- data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/missing-reports +0 -2
- data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/resource1_2002-03-01.tji +0 -0
- data/test/TestSuite/StatusSheets/boss.tji +0 -45
- data/test/TestSuite/StatusSheets/boss_mail +0 -51
- data/test/TestSuite/StatusSheets/dev2_mail +0 -37
- data/test/TestSuite/StatusSheets/project.tjp +0 -275
- data/test/TestSuite/StatusSheets/run +0 -54
- data/test/TestSuite/Syntax/Correct/DST.tjp +0 -11
- data/test/TestSuite/Syntax/Correct/ReleasePlan.tjp +0 -32
- data/test/TestSuite/Syntax/Correct/css/tjmanual.css +0 -86
- data/test/TestSuite/Syntax/Correct/css/tjreport.css +0 -413
- data/test/TestSuite/Syntax/Correct/icons/details.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/resource.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/task.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/trend-down.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/trend-flat.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/trend-up.png +0 -0
- data/test/TestSuite/Syntax/Correct/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/TimeSheets/dev2_mail1 +0 -84
- data/test/TestSuite/TimeSheets/dev2_mail2 +0 -87
- data/test/TestSuite/TimeSheets/project.tjp +0 -271
- data/test/TestSuite/TimeSheets/receiver.log.mod +0 -1056
- data/test/TestSuite/TimeSheets/run +0 -76
- data/test/TestSuite/TimeSheets/uu.txt +0 -29
@@ -382,7 +382,8 @@ class TaskJuggler
|
|
382
382
|
end
|
383
383
|
|
384
384
|
unless scanner.eos?
|
385
|
-
|
385
|
+
error('junk_at_eom',
|
386
|
+
"Junk found at end of macro: #{scanner.post_match}")
|
386
387
|
end
|
387
388
|
|
388
389
|
# Expand the macro and inject it into the scanner.
|
data/lib/taskjuggler/Query.rb
CHANGED
@@ -38,7 +38,8 @@ class TaskJuggler
|
|
38
38
|
attributeId scenario scenarioIdx
|
39
39
|
loadUnit numberFormat currencyFormat timeFormat
|
40
40
|
listItem listType hideJournalEntry
|
41
|
-
|
41
|
+
journalMode journalAttributes sortJournalEntries
|
42
|
+
costAccount revenueAccount selfContained )
|
42
43
|
@@ps.each do |p|
|
43
44
|
attr_accessor p.to_sym
|
44
45
|
end
|
data/lib/taskjuggler/Resource.rb
CHANGED
@@ -41,115 +41,12 @@ class TaskJuggler
|
|
41
41
|
@data[scenarioIdx].method(func).call(*args)
|
42
42
|
end
|
43
43
|
|
44
|
-
def query_journal(query)
|
45
|
-
journalText(query, true)
|
46
|
-
end
|
47
|
-
|
48
44
|
def query_dashboard(query)
|
49
45
|
dashboard(query)
|
50
46
|
end
|
51
47
|
|
52
48
|
private
|
53
49
|
|
54
|
-
# Create a blog-style list of all alert messages that match the Query.
|
55
|
-
def journalText(query, longVersion)
|
56
|
-
# The components of the message are either UTF-8 text or RichText. For
|
57
|
-
# the RichText components, we use the originally provided markup since
|
58
|
-
# we compose the result as RichText markup first.
|
59
|
-
rText = ''
|
60
|
-
list = @project['journal'].entriesByResource(self, query.start, query.end,
|
61
|
-
query.hideJournalEntry)
|
62
|
-
# Sort all entries in buckets by their alert level.
|
63
|
-
numberOfLevels = project['alertLevels'].length
|
64
|
-
listByLevel = []
|
65
|
-
numberOfLevels.times { |i| listByLevel[i] = [] }
|
66
|
-
list.each do |entry|
|
67
|
-
listByLevel[entry.alertLevel] << entry
|
68
|
-
end
|
69
|
-
(numberOfLevels - 1).downto(0) do |level|
|
70
|
-
levelList = listByLevel[level]
|
71
|
-
levelRecord = @project['alertLevels'][level]
|
72
|
-
if query.selfContained
|
73
|
-
alertName = "<nowiki>[</nowiki><fcol:#{levelRecord[0]}>" +
|
74
|
-
"#{levelRecord[1]}</fcol><nowiki>]</nowiki>"
|
75
|
-
else
|
76
|
-
alertName = "[[File:icons/flag-#{levelRecord[0]}.png|" +
|
77
|
-
"alt=[#{levelRecord[1]}]|text-bottom]]"
|
78
|
-
end
|
79
|
-
levelList.each do |entry|
|
80
|
-
tsRecord = entry.timeSheetRecord
|
81
|
-
|
82
|
-
if entry.property.is_a?(Task)
|
83
|
-
rText += "=== #{alertName} <nowiki>#{entry.property.name}" +
|
84
|
-
"</nowiki> (ID: #{entry.property.fullId}) ===\n\n"
|
85
|
-
unless entry.flags.empty?
|
86
|
-
rText += "'''Flags:''' #{entry.flags.join(', ')}\n\n"
|
87
|
-
end
|
88
|
-
if tsRecord
|
89
|
-
rText += "'''Work:''' #{tsRecord.actualWorkPercent.to_i}% "
|
90
|
-
if tsRecord.actualWorkPercent != tsRecord.planWorkPercent
|
91
|
-
rText += "(#{tsRecord.planWorkPercent.to_i}%) "
|
92
|
-
end
|
93
|
-
if tsRecord.remaining
|
94
|
-
rText += "'''Remaining:''' #{tsRecord.actualRemaining}d "
|
95
|
-
if tsRecord.actualRemaining != tsRecord.planRemaining
|
96
|
-
rText += "(#{tsRecord.planRemaining}d) "
|
97
|
-
end
|
98
|
-
else
|
99
|
-
rText += "'''End:''' " +
|
100
|
-
"#{tsRecord.actualEnd.to_s(query.timeFormat)} "
|
101
|
-
if tsRecord.actualEnd != tsRecord.planEnd
|
102
|
-
rText += "(#{tsRecord.planEnd.to_s(query.timeFormat)}) "
|
103
|
-
end
|
104
|
-
end
|
105
|
-
rText += "\n\n"
|
106
|
-
end
|
107
|
-
elsif !(tsRecord = entry.timeSheetRecord).nil? &&
|
108
|
-
entry.timeSheetRecord.task.is_a?(String)
|
109
|
-
rText += "== #{alertName} <nowiki>[New Task] #{tsRecord.name} " +
|
110
|
-
"</nowiki> "+
|
111
|
-
"(ID: #{tsRecord.task}) ==\n\n"
|
112
|
-
if tsRecord
|
113
|
-
rText += "'''Work:''' #{tsRecord.actualWorkPercent}% "
|
114
|
-
if tsRecord.remaining
|
115
|
-
rText += "'''Remaining:''' #{tsRecord.actualRemaining}d "
|
116
|
-
else
|
117
|
-
rText += "'''End:''' " +
|
118
|
-
"#{tsRecord.actualEnd.to_s(query.timeFormat)} "
|
119
|
-
end
|
120
|
-
rText += "\n\n"
|
121
|
-
end
|
122
|
-
else
|
123
|
-
rText += "== #{alertName} Personal Notes ==\n\n"
|
124
|
-
end
|
125
|
-
unless entry.headline.empty?
|
126
|
-
rText += "'''<nowiki>#{entry.headline}</nowiki>'''\n\n"
|
127
|
-
end
|
128
|
-
if entry.summary
|
129
|
-
rText += entry.summary.richText.inputText + "\n\n"
|
130
|
-
end
|
131
|
-
if longVersion && entry.details
|
132
|
-
rText += entry.details.richText.inputText + "\n\n"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Now convert the RichText markup String into RichTextIntermediate
|
138
|
-
# format.
|
139
|
-
unless (rti = RichText.new(rText, RTFHandlers.create(@project),
|
140
|
-
@project.messageHandler).
|
141
|
-
generateIntermediateFormat)
|
142
|
-
@project.messageHandler.warning(
|
143
|
-
'res_journal_text', 'Syntax error in journal text')
|
144
|
-
return nil
|
145
|
-
end
|
146
|
-
# No section numbers, please!
|
147
|
-
rti.sectionNumbers = false
|
148
|
-
# We use a special class to allow CSS formating.
|
149
|
-
rti.cssClass = 'tj_journal'
|
150
|
-
query.rti = rti
|
151
|
-
end
|
152
|
-
|
153
50
|
# Create a dashboard-like list of all task that have a current alert
|
154
51
|
# status.
|
155
52
|
def dashboard(query)
|
@@ -69,9 +69,12 @@ class TaskJuggler
|
|
69
69
|
raise "No Query has been registered for this RichText yet!"
|
70
70
|
end
|
71
71
|
|
72
|
+
query = @query.dup
|
73
|
+
|
72
74
|
# Check the user provided arguments. Only the following list is allowed.
|
73
|
-
validArgs = %w(
|
74
|
-
|
75
|
+
validArgs = %w( attribute currencyformat end family journalattributes
|
76
|
+
journalmode loadunit numberformat property scenario
|
77
|
+
scopeproperty start timeformat )
|
75
78
|
expandedArgs = {}
|
76
79
|
args.each do |arg, value|
|
77
80
|
unless validArgs.include?(arg)
|
@@ -91,8 +94,6 @@ class TaskJuggler
|
|
91
94
|
"provide a family type as well.")
|
92
95
|
end
|
93
96
|
|
94
|
-
query = @query.dup
|
95
|
-
|
96
97
|
# Every provided query parameter will overwrite the corresponding value
|
97
98
|
# in the Query that was provided by the ReportContext. The name of the
|
98
99
|
# arguments don't always exactly match the Query variables Let's start
|
@@ -115,11 +116,14 @@ class TaskJuggler
|
|
115
116
|
if expandedArgs['currencyformat']
|
116
117
|
query.currencyFormat = expandedArgs['currencyformat']
|
117
118
|
end
|
119
|
+
query.project = @project
|
118
120
|
|
119
121
|
# And now the slighly more complicated ones.
|
120
122
|
setScenarioIdx(query, expandedArgs)
|
121
123
|
setPropertyType(query, expandedArgs)
|
122
124
|
setLoadUnit(query, expandedArgs)
|
125
|
+
setJournalMode(query, expandedArgs)
|
126
|
+
setJournalAttributes(query, expandedArgs)
|
123
127
|
|
124
128
|
# Now that we have put together the query, we can process it and return
|
125
129
|
# the query object for result extraction.
|
@@ -177,6 +181,40 @@ class TaskJuggler
|
|
177
181
|
query.scenarioIdx = 0 unless query.scenarioIdx
|
178
182
|
end
|
179
183
|
|
184
|
+
def setJournalMode(query, args)
|
185
|
+
if (mode = args['journalmode'])
|
186
|
+
validModes = %w( journal journal_sub status_up status_down alerts_down )
|
187
|
+
unless validModes.include?(mode)
|
188
|
+
error('rtfq_bad_journalmode',
|
189
|
+
"Unknown journalmode #{mode}. Must be one of " +
|
190
|
+
"#{validModes.join(', ')}.")
|
191
|
+
end
|
192
|
+
query.journalMode = mode.intern
|
193
|
+
elsif !query.journalMode
|
194
|
+
query.journalMode = :journal
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def setJournalAttributes(query, args)
|
199
|
+
if (attrListStr = args['journalattributes'])
|
200
|
+
attrs = attrListStr.split(', ').map { |a| a.delete(' ') }
|
201
|
+
query.journalAttributes = []
|
202
|
+
validAttrs = %w( author date details flags headline property propertyid
|
203
|
+
summary timesheet )
|
204
|
+
attrs.each do |attr|
|
205
|
+
if validAttrs.include?(attr)
|
206
|
+
query.journalAttributes << attr
|
207
|
+
else
|
208
|
+
error('rtfq_bad_journalattr',
|
209
|
+
"Unknown journalattribute #{attr}. Must be one of " +
|
210
|
+
"#{validAttrs.join(', ')}.")
|
211
|
+
end
|
212
|
+
end
|
213
|
+
elsif !query.journalAttributes
|
214
|
+
query.journalAttributes = %w( date summary details )
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
180
218
|
end
|
181
219
|
|
182
220
|
end
|
@@ -85,26 +85,6 @@ class TaskJuggler
|
|
85
85
|
text
|
86
86
|
end
|
87
87
|
|
88
|
-
# Convert all CR+LF and CR line breaks into LF line breaks.
|
89
|
-
def fixLineBreaks(text)
|
90
|
-
out = ''
|
91
|
-
cr = false
|
92
|
-
text.each_utf8_char do |c|
|
93
|
-
if c == "\r"
|
94
|
-
# We don't know yet if it's a CR or CR+LF.
|
95
|
-
cr = true
|
96
|
-
else
|
97
|
-
if cr
|
98
|
-
# If we only found a CR. Replace it with a LF.
|
99
|
-
out << "\n" if c != "\n"
|
100
|
-
cr = false
|
101
|
-
end
|
102
|
-
out << c
|
103
|
-
end
|
104
|
-
end
|
105
|
-
out
|
106
|
-
end
|
107
|
-
|
108
88
|
def setWorkingDir
|
109
89
|
# Make sure the user has provided a properly setup config file.
|
110
90
|
error('\'smtpServer\' not configured') unless @smtpServer
|
@@ -80,31 +80,27 @@ class TaskJuggler
|
|
80
80
|
|
81
81
|
createDirectories
|
82
82
|
|
83
|
-
# Read the RFC 822 compliant mail from STDIN.
|
84
|
-
rawMail = $stdin.read
|
85
|
-
|
86
|
-
# To get line-accurate error reports for encoding errors, we scan the
|
87
|
-
# email for obvious ecoding errors and try to get a sender fallback
|
88
|
-
# address. This will not find encoding problems inside encoded mime
|
89
|
-
# parts.
|
90
|
-
fromLine = nil
|
91
83
|
begin
|
84
|
+
# Read the RFC 822 compliant mail from STDIN.
|
85
|
+
rawMail = $stdin.read
|
86
|
+
rawMail = rawMail.forceUTF8Encoding
|
87
|
+
|
88
|
+
mail = Mail.new(rawMail)
|
89
|
+
rescue
|
90
|
+
# In certain cases, Mail will fail to create the Mail object. Since we
|
91
|
+
# don't have the email sender yet, we have to try to extract it
|
92
|
+
# ourself.
|
93
|
+
fromLine = nil
|
92
94
|
rawMail.each_line do |line|
|
93
95
|
unless fromLine
|
94
|
-
matches = line.
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
# Try the encoding. If it fails, we'll get an exception.
|
100
|
-
line.encode!('UTF-8')
|
101
|
-
rescue
|
102
|
-
raise "Encoding error in line: #{line.encode('UTF-8', :invalid)}"
|
96
|
+
matches = line.match('^From: .*')
|
97
|
+
if matches
|
98
|
+
fromLine = matches[0]
|
99
|
+
break
|
100
|
+
end
|
103
101
|
end
|
104
102
|
end
|
105
103
|
|
106
|
-
mail = Mail.new(rawMail)
|
107
|
-
rescue
|
108
104
|
# Try to extract the mail sender the dirty way so we can at least send
|
109
105
|
# a response to the submitter.
|
110
106
|
@submitter = fromLine[6..-1] if fromLine && fromLine.is_a?(String)
|
@@ -150,8 +146,14 @@ EOT
|
|
150
146
|
|
151
147
|
# Isolate the actual syntax from _sheet_ and process it.
|
152
148
|
def processSheet(sheet)
|
153
|
-
@sheet =
|
154
|
-
|
149
|
+
@sheet = @sheetWasAttached ? cutOut(sheet) : sheet
|
150
|
+
|
151
|
+
begin
|
152
|
+
@sheet = @sheet.forceUTF8Encoding
|
153
|
+
rescue
|
154
|
+
error($!)
|
155
|
+
end
|
156
|
+
|
155
157
|
# A valid sheet must have the poper header line.
|
156
158
|
if @sheetHeader.match(@sheet)
|
157
159
|
checkSignature(@sheet)
|
data/lib/taskjuggler/Task.rb
CHANGED
@@ -32,10 +32,6 @@ class TaskJuggler
|
|
32
32
|
@data[scenarioIdx].readyForScheduling?
|
33
33
|
end
|
34
34
|
|
35
|
-
def query_journal(query)
|
36
|
-
journalText(query, true, false)
|
37
|
-
end
|
38
|
-
|
39
35
|
def query_journal_sub(query)
|
40
36
|
journalText(query, true, true)
|
41
37
|
end
|
@@ -55,7 +51,9 @@ class TaskJuggler
|
|
55
51
|
list = @project['journal'].entriesByTask(self, query.start, query.end,
|
56
52
|
query.hideJournalEntry)
|
57
53
|
end
|
58
|
-
list.
|
54
|
+
list.setSorting([ [ :alert, -1 ], [ :date, -1 ], [ :seqno, 1 ] ])
|
55
|
+
list.sort!
|
56
|
+
list.each do |entry|
|
59
57
|
tsRecord = entry.timeSheetRecord
|
60
58
|
|
61
59
|
if entry.property.is_a?(Task)
|
@@ -303,6 +303,10 @@ class TaskJuggler
|
|
303
303
|
'scenarioIdx' => @project['trackingScenarioIdx'],
|
304
304
|
'start' => ts.interval.start,
|
305
305
|
'end' => ts.interval.end,
|
306
|
+
'journalMode' => :journal,
|
307
|
+
'journalAttributes' => %w( alert property headline flags
|
308
|
+
timesheet summary details ),
|
309
|
+
'sortJournalEntries' => [ [ :seqno, 1 ] ],
|
306
310
|
'timeFormat' => '%Y-%m-%d',
|
307
311
|
'selfContained' => true }
|
308
312
|
query = Query.new(queryAttrs)
|
@@ -29,7 +29,7 @@ class TaskJuggler
|
|
29
29
|
%w( allocate assignedresources booking charge chargeset complete
|
30
30
|
criticalness depends duration effort end forward length
|
31
31
|
maxend maxstart minend minstart milestone pathcriticalness
|
32
|
-
precedes scheduled shifts start status ).each do |attr|
|
32
|
+
precedes priority scheduled shifts start status ).each do |attr|
|
33
33
|
@property[attr, @scenarioIdx]
|
34
34
|
end
|
35
35
|
|
@@ -80,7 +80,7 @@ class TaskJuggler
|
|
80
80
|
if @start && @end && @effort == 0 && @length == 0 && @duration == 0 &&
|
81
81
|
@allocate.empty?
|
82
82
|
@scheduled = true
|
83
|
-
Log
|
83
|
+
Log.msg { "Task #{@property.fullId}: #{period_to_s}" }
|
84
84
|
end
|
85
85
|
|
86
86
|
# Collect the limits of this task and all parent tasks into a single
|
@@ -153,19 +153,19 @@ class TaskJuggler
|
|
153
153
|
def propagateInitialValues
|
154
154
|
unless @startPropagated
|
155
155
|
if @start
|
156
|
-
propagateDate(@start, false)
|
156
|
+
propagateDate(@start, false, true)
|
157
157
|
elsif @property.parent.nil? &&
|
158
158
|
@property.canInheritDate?(@scenarioIdx, false)
|
159
|
-
propagateDate(@project['start'], false)
|
159
|
+
propagateDate(@project['start'], false, true)
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
163
|
unless @endPropagated
|
164
164
|
if @end
|
165
|
-
propagateDate(@end, true)
|
165
|
+
propagateDate(@end, true, true)
|
166
166
|
elsif @property.parent.nil? &&
|
167
167
|
@property.canInheritDate?(@scenarioIdx, true)
|
168
|
-
propagateDate(@project['end'], true)
|
168
|
+
propagateDate(@project['end'], true, true)
|
169
169
|
end
|
170
170
|
end
|
171
171
|
end
|
@@ -895,6 +895,8 @@ class TaskJuggler
|
|
895
895
|
# Check if the task has already been scheduled e. g. by propagateDate().
|
896
896
|
return true if @scheduled
|
897
897
|
|
898
|
+
logTag = "schedule_#{@property.id}"
|
899
|
+
Log.enter(logTag, "Scheduling task #{@property.id}")
|
898
900
|
# Compute the date of the next slot this task wants to have scheduled.
|
899
901
|
# This must either be the first slot ever or it must be directly
|
900
902
|
# adjecent to the previous slot. If this task has not yet been scheduled
|
@@ -927,16 +929,21 @@ class TaskJuggler
|
|
927
929
|
@currentSlotIdx += delta
|
928
930
|
if @currentSlotIdx < lowerLimit || upperLimit < @currentSlotIdx
|
929
931
|
markAsRunaway
|
932
|
+
Log.exit(logTag, "Scheduling of task #{@property.id} failed")
|
930
933
|
return false
|
931
934
|
end
|
932
935
|
end
|
933
936
|
|
937
|
+
Log.exit(logTag, "Scheduling of task #{@property.id} completed")
|
934
938
|
true
|
935
939
|
end
|
936
940
|
|
937
941
|
# Set a new start or end date and propagate the value to all other
|
938
942
|
# task ends that have a direct dependency to this end of the task.
|
939
943
|
def propagateDate(date, atEnd, ignoreEffort = false)
|
944
|
+
logTag = "propagateDate_#{@property.id}_#{atEnd ? 'end' : 'start'}"
|
945
|
+
Log.enter(logTag, "Propagating #{atEnd ? 'end' : 'start'} date " +
|
946
|
+
"to task #{@property.id}")
|
940
947
|
thisEnd = atEnd ? 'end' : 'start'
|
941
948
|
otherEnd = atEnd ? 'start' : 'end'
|
942
949
|
#puts "Propagating #{thisEnd} date #{date} of #{@property.fullId} " +
|
@@ -954,7 +961,7 @@ class TaskJuggler
|
|
954
961
|
# are only set in scheduleContainer().
|
955
962
|
if @property.leaf?
|
956
963
|
instance_variable_set(('@' + thisEnd).intern, date)
|
957
|
-
Log
|
964
|
+
Log.msg { "Task #{@property.fullId}: #{period_to_s}" }
|
958
965
|
end
|
959
966
|
|
960
967
|
if @milestone
|
@@ -963,12 +970,12 @@ class TaskJuggler
|
|
963
970
|
if a(otherEnd).nil?
|
964
971
|
propagateDate(a(thisEnd), !atEnd)
|
965
972
|
end
|
966
|
-
Log
|
973
|
+
Log.msg { "Milestone #{@property.fullId}: #{period_to_s}" }
|
967
974
|
elsif !@scheduled && @start && @end &&
|
968
975
|
!(@length == 0 && @duration == 0 && @effort == 0 &&
|
969
976
|
!@allocate.empty?)
|
970
977
|
@scheduled = true
|
971
|
-
Log
|
978
|
+
Log.msg { "Task #{@property.fullId} has been scheduled" }
|
972
979
|
end
|
973
980
|
|
974
981
|
# Propagate date to all dependent tasks. Don't do this for start
|
@@ -1010,9 +1017,11 @@ class TaskJuggler
|
|
1010
1017
|
@property.parents.each do |parent|
|
1011
1018
|
parent.scheduleContainer(@scenarioIdx)
|
1012
1019
|
end
|
1020
|
+
Log.exit(logTag, "Finished propagation of " +
|
1021
|
+
"#{atEnd ? 'end' : 'start'} date " +
|
1022
|
+
"to task #{@property.id}")
|
1013
1023
|
end
|
1014
1024
|
|
1015
|
-
|
1016
1025
|
# This function determines if a task can inherit the start or end date
|
1017
1026
|
# from a parent task or the project time frame. +atEnd+ specifies whether
|
1018
1027
|
# the check should be done for the task end (true) or task start (false).
|
@@ -1034,13 +1043,15 @@ class TaskJuggler
|
|
1034
1043
|
thisEnd, thatEnd = atEnd ? [ 'end', 'start' ] : [ 'start', 'end' ]
|
1035
1044
|
# Return false if we already have a date for this end or if we have a
|
1036
1045
|
# strong dependency for this end.
|
1037
|
-
return false if
|
1046
|
+
return false if instance_variable_get('@' + thisEnd) ||
|
1047
|
+
hasStrongDeps?(atEnd)
|
1038
1048
|
|
1039
1049
|
# Containter task can inherit the date if they have no dependencies at
|
1040
1050
|
# this end.
|
1041
1051
|
return true if @property.container?
|
1042
1052
|
|
1043
|
-
hasThatSpec =
|
1053
|
+
hasThatSpec = !instance_variable_get('@' + thatEnd).nil? ||
|
1054
|
+
hasStrongDeps?(!atEnd)
|
1044
1055
|
hasDurationSpec = hasDurationSpec?
|
1045
1056
|
|
1046
1057
|
# Check for tasks that have no start and end spec, no duration spec but
|
@@ -1054,8 +1065,8 @@ class TaskJuggler
|
|
1054
1065
|
return hasThatSpec
|
1055
1066
|
else
|
1056
1067
|
# the scheduling direction is pointing towards this end
|
1057
|
-
return
|
1058
|
-
@booking.empty? #&& @allocate.empty?
|
1068
|
+
return !instance_variable_get('@' + thatEnd).nil? &&
|
1069
|
+
!hasDurationSpec && @booking.empty? #&& @allocate.empty?
|
1059
1070
|
end
|
1060
1071
|
end
|
1061
1072
|
|
@@ -1097,7 +1108,7 @@ class TaskJuggler
|
|
1097
1108
|
raise "Start (#{@start}) and end (#{@end}) must be set"
|
1098
1109
|
end
|
1099
1110
|
@scheduled = true
|
1100
|
-
Log
|
1111
|
+
Log.msg { "Container task #{@property.fullId} completed: #{period_to_s}" }
|
1101
1112
|
|
1102
1113
|
# If we have modified the start or end date, we need to communicate this
|
1103
1114
|
# new date to surrounding tasks.
|
@@ -1327,6 +1338,22 @@ class TaskJuggler
|
|
1327
1338
|
query.assignList(list)
|
1328
1339
|
end
|
1329
1340
|
|
1341
|
+
def query_maxend(query)
|
1342
|
+
queryDateLimit(query, @maxend)
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
def query_minend(query)
|
1346
|
+
queryDateLimit(query, @minend)
|
1347
|
+
end
|
1348
|
+
|
1349
|
+
def query_maxstart(query)
|
1350
|
+
queryDateLimit(query, @maxstart)
|
1351
|
+
end
|
1352
|
+
|
1353
|
+
def query_minstart(query)
|
1354
|
+
queryDateLimit(query, @minstart)
|
1355
|
+
end
|
1356
|
+
|
1330
1357
|
def query_precursors(query)
|
1331
1358
|
list = []
|
1332
1359
|
|
@@ -1744,15 +1771,15 @@ class TaskJuggler
|
|
1744
1771
|
if @effort > 0 && @assignedresources.empty?
|
1745
1772
|
if @forward
|
1746
1773
|
@start = @project.idxToDate(@currentSlotIdx)
|
1747
|
-
Log
|
1748
|
-
|
1774
|
+
Log.msg { "Task #{@property.fullId} first assignment: " +
|
1775
|
+
"#{period_to_s}" }
|
1749
1776
|
@startsuccs.each do |task, onEnd|
|
1750
1777
|
task.propagateDate(@scenarioIdx, @start, false, true)
|
1751
1778
|
end
|
1752
1779
|
else
|
1753
1780
|
@end = @project.idxToDate(@currentSlotIdx + 1)
|
1754
|
-
Log
|
1755
|
-
|
1781
|
+
Log.msg { "Task #{@property.fullId} last assignment: " +
|
1782
|
+
"#{period_to_s}" }
|
1756
1783
|
@endpreds.each do |task, onEnd|
|
1757
1784
|
task.propagateDate(@scenarioIdx, @end, true, true)
|
1758
1785
|
end
|
@@ -1843,8 +1870,7 @@ class TaskJuggler
|
|
1843
1870
|
firstSlotDate = @project.idxToDate(firstSlotIdx)
|
1844
1871
|
if @start.nil? || firstSlotDate > @start
|
1845
1872
|
@start = firstSlotDate
|
1846
|
-
Log
|
1847
|
-
"#{@start} -> #{@end}"
|
1873
|
+
Log.msg { "Task #{@property.fullId} first booking: #{period_to_s}" }
|
1848
1874
|
end
|
1849
1875
|
end
|
1850
1876
|
|
@@ -1965,82 +1991,18 @@ class TaskJuggler
|
|
1965
1991
|
false
|
1966
1992
|
end
|
1967
1993
|
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
#
|
1978
|
-
# +--- SS -> S> : Weak
|
1979
|
-
# |-+ SS -> S< : Weak
|
1980
|
-
# +-|- SP -> S> : Strong
|
1981
|
-
# | +--- SP -> S< : Strong
|
1982
|
-
# +-|
|
1983
|
-
# +---
|
1984
|
-
#
|
1985
|
-
#
|
1986
|
-
# T2 depends on T1 end
|
1987
|
-
# T1 precedes T2 start
|
1988
|
-
#
|
1989
|
-
# ---+ ES -> S> : Weak
|
1990
|
-
# |-+ ES -> S< : Strong
|
1991
|
-
# ---+ | SP -> E> : Strong
|
1992
|
-
# | +--- SP -> E< : Weak
|
1993
|
-
# +-|
|
1994
|
-
# +---
|
1995
|
-
#
|
1996
|
-
#
|
1997
|
-
# T1 precedes T2 end
|
1998
|
-
#
|
1999
|
-
# ---+ ES -> E> : Strong
|
2000
|
-
# +-| ES -> E< : Strong
|
2001
|
-
# -|-+ EP -> E> : Weak
|
2002
|
-
# ---+ | EP -> E< : Weak
|
2003
|
-
# |-+
|
2004
|
-
# ---+
|
2005
|
-
#
|
2006
|
-
# All other combinations are illegal and should be caught earlier. So,
|
2007
|
-
# illegal values can be considered don't care values.
|
2008
|
-
#
|
2009
|
-
# f/t S> S< E> E<
|
2010
|
-
# SP S S S W Row 1
|
2011
|
-
# SS W W x x Row 2
|
2012
|
-
# EP x x W W Row 3
|
2013
|
-
# ES W S S S Row 4
|
2014
|
-
#
|
2015
|
-
# If the other end of the dependency already has a date, it's a strong
|
2016
|
-
# dependency no matter how it was set.
|
2017
|
-
unless atEnd
|
2018
|
-
# Row 1
|
2019
|
-
@startpreds.each do |task, onEnd|
|
2020
|
-
if (onEnd && (task['forward', @scenarioIdx] ||
|
2021
|
-
task['end', @scenarioIdx])) || !onEnd
|
2022
|
-
return true
|
2023
|
-
end
|
2024
|
-
end
|
2025
|
-
# Row 2
|
2026
|
-
@startsuccs.each do |task, onEnd|
|
2027
|
-
return true if task[onEnd ? 'end' : 'start', @scenarioIdx]
|
2028
|
-
end
|
1994
|
+
# Return true if the task has a 'strong' dependency at the start if
|
1995
|
+
# _atEnd_ is false or at the end. A 'strong' dependency is an outer
|
1996
|
+
# dependency. At the start a predecessor is strong, and the end a
|
1997
|
+
# successor. start successors or end predecessors are considered weak
|
1998
|
+
# dependencies since this task will always have to get the date first and
|
1999
|
+
# then pass it on to the inner dependencies.
|
2000
|
+
def hasStrongDeps?(atEnd)
|
2001
|
+
if atEnd
|
2002
|
+
return !@endsuccs.empty?
|
2029
2003
|
else
|
2030
|
-
|
2031
|
-
@endpreds.each do |task, onEnd|
|
2032
|
-
return true if task[onEnd ? 'end' : 'start', @scenarioIdx]
|
2033
|
-
end
|
2034
|
-
# Row 4
|
2035
|
-
@endsuccs.each do |task, onEnd|
|
2036
|
-
if (!onEnd && (!task['forward', @scenarioIdx] ||
|
2037
|
-
task['start', @scenarioIdx])) || onEnd
|
2038
|
-
return true
|
2039
|
-
end
|
2040
|
-
end
|
2004
|
+
return !@startpreds.empty?
|
2041
2005
|
end
|
2042
|
-
|
2043
|
-
false
|
2044
2006
|
end
|
2045
2007
|
|
2046
2008
|
def markAsRunaway
|
@@ -2150,7 +2112,7 @@ class TaskJuggler
|
|
2150
2112
|
|
2151
2113
|
# Looks like it is ok to propagate the date.
|
2152
2114
|
task.propagateDate(@scenarioIdx, nDate, atEnd)
|
2153
|
-
#
|
2115
|
+
#puts "Propagate #{atEnd ? 'end' : 'start'} to dep. #{task.fullId} done"
|
2154
2116
|
end
|
2155
2117
|
|
2156
2118
|
# This is a helper function for calcPathCriticalness(). It computes the
|
@@ -2202,7 +2164,13 @@ class TaskJuggler
|
|
2202
2164
|
else
|
2203
2165
|
# The task is in progress. Calculate the current completion
|
2204
2166
|
# degree.
|
2205
|
-
if
|
2167
|
+
if @end <= @project['now']
|
2168
|
+
# The task has ended already. It's 100% complete.
|
2169
|
+
completion = 100.0
|
2170
|
+
elsif @project['now'] <= @start
|
2171
|
+
# The task has not started yet. Its' 0% complete.
|
2172
|
+
completion = 0.0
|
2173
|
+
elsif !property.leaf?
|
2206
2174
|
# For container task the completion degree is the average of the
|
2207
2175
|
# sub tasks.
|
2208
2176
|
completion = 0.0
|
@@ -2211,12 +2179,6 @@ class TaskJuggler
|
|
2211
2179
|
completion += comp
|
2212
2180
|
end
|
2213
2181
|
completion /= @property.children.length
|
2214
|
-
elsif @end <= @project['now']
|
2215
|
-
# The task has ended already. It's 100% complete.
|
2216
|
-
completion = 100.0
|
2217
|
-
elsif @project['now'] <= @start
|
2218
|
-
# The task has not started yet. Its' 0% complete.
|
2219
|
-
completion = 0.0
|
2220
2182
|
elsif @effort > 0
|
2221
2183
|
# Effort based leaf tasks. The completion degree is the percentage
|
2222
2184
|
# of effort that has been done already.
|
@@ -2420,6 +2382,22 @@ class TaskJuggler
|
|
2420
2382
|
@property['booking', @property.project.scenarioIdx(scenario)]
|
2421
2383
|
end
|
2422
2384
|
|
2385
|
+
# Date limits may be nil and this is not an error. TjTime.to_s() would
|
2386
|
+
# report it as such if we don't use this wrapper method.
|
2387
|
+
def queryDateLimit(query, date)
|
2388
|
+
if date
|
2389
|
+
query.sortable = query.numerical = date
|
2390
|
+
query.string = date.to_s(query.timeFormat)
|
2391
|
+
else
|
2392
|
+
query.sortable = query.numerical = -1
|
2393
|
+
query.string = ''
|
2394
|
+
end
|
2395
|
+
end
|
2396
|
+
|
2397
|
+
def period_to_s
|
2398
|
+
"#{@start ? @start.to_s : '<?>'} -> #{@end ? @end.to_s : '<?>'}"
|
2399
|
+
end
|
2400
|
+
|
2423
2401
|
end
|
2424
2402
|
|
2425
2403
|
end
|