taskjuggler 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (410) hide show
  1. data/CHANGELOG +44 -0
  2. data/bin/tj3webd +4 -0
  3. data/data/css/tjreport.css +14 -5
  4. data/data/tjp.vim +22 -7
  5. data/examples/Fedora-20/reports.tji +2 -4
  6. data/examples/Scrum/Product Burndown.csv +26 -0
  7. data/examples/Scrum/Sprint 1 Burndown.csv +26 -0
  8. data/examples/Scrum/Sprint 2 Burndown.csv +26 -0
  9. data/examples/Scrum/Sprint 3 Burndown.csv +26 -0
  10. data/examples/Scrum/scrum.tjp +141 -0
  11. data/examples/Tutorial/tutorial.tjp +13 -7
  12. data/lib/taskjuggler/Attributes.rb +2 -3
  13. data/lib/taskjuggler/HTMLDocument.rb +25 -18
  14. data/lib/taskjuggler/Journal.rb +85 -65
  15. data/lib/taskjuggler/KeywordDocumentation.rb +25 -13
  16. data/lib/taskjuggler/LeaveList.rb +1 -1
  17. data/lib/taskjuggler/Limits.rb +3 -5
  18. data/lib/taskjuggler/MessageHandler.rb +173 -19
  19. data/lib/taskjuggler/Painter.rb +75 -0
  20. data/lib/taskjuggler/Painter/BasicShapes.rb +76 -0
  21. data/lib/taskjuggler/Painter/Color.rb +273 -0
  22. data/lib/taskjuggler/Painter/Element.rb +56 -0
  23. data/lib/taskjuggler/Painter/FontData.rb +221 -0
  24. data/lib/taskjuggler/Painter/FontMetrics.rb +125 -0
  25. data/lib/taskjuggler/Painter/FontMetricsData.rb +151 -0
  26. data/lib/taskjuggler/Painter/Group.rb +77 -0
  27. data/lib/taskjuggler/Painter/Points.rb +47 -0
  28. data/lib/taskjuggler/Painter/Primitives.rb +100 -0
  29. data/lib/taskjuggler/Painter/SVGSupport.rb +36 -0
  30. data/lib/taskjuggler/Painter/Text.rb +36 -0
  31. data/lib/taskjuggler/Project.rb +46 -29
  32. data/lib/taskjuggler/ProjectFileParser.rb +24 -22
  33. data/lib/taskjuggler/ProjectFileScanner.rb +2 -2
  34. data/lib/taskjuggler/PropertyTreeNode.rb +26 -34
  35. data/lib/taskjuggler/Query.rb +8 -5
  36. data/lib/taskjuggler/RealFormat.rb +3 -0
  37. data/lib/taskjuggler/Resource.rb +3 -5
  38. data/lib/taskjuggler/ResourceScenario.rb +19 -7
  39. data/lib/taskjuggler/RichText.rb +4 -6
  40. data/lib/taskjuggler/RichText/FunctionExample.rb +1 -1
  41. data/lib/taskjuggler/RichText/FunctionHandler.rb +5 -6
  42. data/lib/taskjuggler/RichText/Parser.rb +4 -6
  43. data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
  44. data/lib/taskjuggler/RichText/RTFQuery.rb +2 -3
  45. data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
  46. data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -2
  47. data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
  48. data/lib/taskjuggler/RichText/Scanner.rb +6 -6
  49. data/lib/taskjuggler/RichText/Snip.rb +1 -2
  50. data/lib/taskjuggler/RuntimeConfig.rb +9 -6
  51. data/lib/taskjuggler/ScenarioData.rb +4 -3
  52. data/lib/taskjuggler/Scoreboard.rb +6 -0
  53. data/lib/taskjuggler/SheetHandlerBase.rb +25 -8
  54. data/lib/taskjuggler/SimpleQueryExpander.rb +14 -5
  55. data/lib/taskjuggler/SyntaxReference.rb +1 -2
  56. data/lib/taskjuggler/TableColumnSorter.rb +84 -0
  57. data/lib/taskjuggler/Task.rb +3 -5
  58. data/lib/taskjuggler/TaskJuggler.rb +36 -29
  59. data/lib/taskjuggler/TaskScenario.rb +154 -66
  60. data/lib/taskjuggler/TextParser.rb +24 -17
  61. data/lib/taskjuggler/TextParser/Scanner.rb +16 -11
  62. data/lib/taskjuggler/TextParser/SourceFileInfo.rb +20 -15
  63. data/lib/taskjuggler/TimeSheets.rb +6 -12
  64. data/lib/taskjuggler/Tj3AppBase.rb +35 -16
  65. data/lib/taskjuggler/Tj3Config.rb +1 -1
  66. data/lib/taskjuggler/TjpSyntaxRules.rb +239 -49
  67. data/lib/taskjuggler/XMLElement.rb +9 -2
  68. data/lib/taskjuggler/apps/Tj3.rb +43 -37
  69. data/lib/taskjuggler/apps/Tj3Client.rb +62 -112
  70. data/lib/taskjuggler/apps/Tj3Daemon.rb +66 -29
  71. data/lib/taskjuggler/apps/Tj3Man.rb +5 -5
  72. data/lib/taskjuggler/apps/Tj3SsReceiver.rb +10 -13
  73. data/lib/taskjuggler/apps/Tj3SsSender.rb +13 -16
  74. data/lib/taskjuggler/apps/Tj3TsReceiver.rb +10 -13
  75. data/lib/taskjuggler/apps/Tj3TsSender.rb +12 -15
  76. data/lib/taskjuggler/apps/Tj3TsSummary.rb +12 -15
  77. data/lib/taskjuggler/apps/Tj3WebD.rb +99 -0
  78. data/lib/taskjuggler/daemon/Daemon.rb +50 -10
  79. data/lib/taskjuggler/daemon/DaemonConnector.rb +127 -0
  80. data/lib/taskjuggler/daemon/ProcessIntercom.rb +36 -21
  81. data/lib/taskjuggler/daemon/ProjectBroker.rb +122 -112
  82. data/lib/taskjuggler/daemon/ProjectServer.rb +78 -46
  83. data/lib/taskjuggler/daemon/ReportServer.rb +52 -28
  84. data/lib/taskjuggler/daemon/ReportServlet.rb +92 -21
  85. data/lib/taskjuggler/daemon/WebServer.rb +75 -22
  86. data/lib/taskjuggler/daemon/WelcomePage.rb +1 -0
  87. data/lib/taskjuggler/reports/AccountListRE.rb +3 -3
  88. data/lib/taskjuggler/reports/CSVFile.rb +9 -2
  89. data/lib/taskjuggler/reports/ChartPlotter.rb +453 -0
  90. data/lib/taskjuggler/reports/Navigator.rb +1 -0
  91. data/lib/taskjuggler/reports/NikuReport.rb +4 -4
  92. data/lib/taskjuggler/reports/Report.rb +6 -18
  93. data/lib/taskjuggler/reports/ReportBase.rb +9 -9
  94. data/lib/taskjuggler/reports/ReportContext.rb +2 -2
  95. data/lib/taskjuggler/reports/StatusSheetReport.rb +6 -6
  96. data/lib/taskjuggler/reports/TableReport.rb +24 -15
  97. data/lib/taskjuggler/reports/TimeSheetReport.rb +5 -5
  98. data/lib/taskjuggler/reports/TraceReport.rb +251 -0
  99. data/lib/tj3webd.rb +17 -0
  100. data/manual/Day_To_Day_Juggling +10 -3
  101. data/manual/Installation +38 -19
  102. data/manual/Software +25 -19
  103. data/manual/Tutorial +119 -110
  104. data/manual/html/Day_To_Day_Juggling.html +7 -5
  105. data/manual/html/Getting_Started.html +4 -4
  106. data/manual/html/How_To_Contribute.html +4 -4
  107. data/manual/html/Installation.html +19 -11
  108. data/manual/html/Intro.html +4 -4
  109. data/manual/html/Reporting_Bugs.html +4 -4
  110. data/manual/html/Rich_Text_Attributes.html +4 -4
  111. data/manual/html/Software.html +15 -11
  112. data/manual/html/TaskJuggler_2x_Migration.html +4 -4
  113. data/manual/html/TaskJuggler_Internals.html +4 -4
  114. data/manual/html/The_TaskJuggler_Syntax.html +4 -4
  115. data/manual/html/Tutorial.html +41 -32
  116. data/manual/html/account.html +4 -4
  117. data/manual/html/account.task.html +4 -4
  118. data/manual/html/accountprefix.html +4 -4
  119. data/manual/html/accountreport.html +27 -9
  120. data/manual/html/accountroot.html +5 -5
  121. data/manual/html/active.html +4 -4
  122. data/manual/html/adopt.task.html +4 -4
  123. data/manual/html/aggregate.html +4 -4
  124. data/manual/html/alert.html +4 -4
  125. data/manual/html/alertlevels.html +4 -4
  126. data/manual/html/allocate.html +5 -5
  127. data/manual/html/alphabet.html +4 -4
  128. data/manual/html/alternative.html +4 -4
  129. data/manual/html/author.html +4 -4
  130. data/manual/html/balance.html +5 -5
  131. data/manual/html/booking.resource.html +4 -4
  132. data/manual/html/booking.task.html +4 -4
  133. data/manual/html/caption.html +5 -5
  134. data/manual/html/cellcolor.column.html +43 -8
  135. data/manual/html/celltext.column.html +4 -4
  136. data/manual/html/center.html +5 -5
  137. data/manual/html/charge.html +4 -4
  138. data/manual/html/chargeset.html +4 -4
  139. data/manual/html/columnid.html +27 -15
  140. data/manual/html/columns.html +5 -5
  141. data/manual/html/complete.html +4 -4
  142. data/manual/html/copyright.html +4 -4
  143. data/manual/html/credits.html +4 -4
  144. data/manual/html/css/tjreport.css +14 -5
  145. data/manual/html/currency.html +4 -4
  146. data/manual/html/currencyformat.html +5 -5
  147. data/manual/html/dailymax.html +5 -5
  148. data/manual/html/dailymin.html +5 -5
  149. data/manual/html/dailyworkinghours.html +4 -4
  150. data/manual/html/date.extend.html +4 -4
  151. data/manual/html/date.html +5 -5
  152. data/manual/html/definitions.html +4 -4
  153. data/manual/html/depends.html +4 -4
  154. data/manual/html/details.html +4 -4
  155. data/manual/html/disabled.html +4 -4
  156. data/manual/html/duration.html +4 -4
  157. data/manual/html/efficiency.html +4 -4
  158. data/manual/html/effort.html +4 -4
  159. data/manual/html/email.html +4 -4
  160. data/manual/html/enabled.html +4 -4
  161. data/manual/html/end.column.html +4 -4
  162. data/manual/html/end.html +4 -4
  163. data/manual/html/end.limit.html +4 -4
  164. data/manual/html/end.report.html +5 -5
  165. data/manual/html/end.timesheet.html +4 -4
  166. data/manual/html/endcredit.html +4 -4
  167. data/manual/html/epilog.html +5 -5
  168. data/manual/html/export.html +4 -4
  169. data/manual/html/extend.html +4 -4
  170. data/manual/html/fail.html +43 -8
  171. data/manual/html/fdl.html +4 -4
  172. data/manual/html/flags.account.html +4 -4
  173. data/manual/html/flags.html +4 -4
  174. data/manual/html/flags.journalentry.html +4 -4
  175. data/manual/html/flags.report.html +5 -5
  176. data/manual/html/flags.resource.html +4 -4
  177. data/manual/html/flags.statussheet.html +4 -4
  178. data/manual/html/flags.task.html +4 -4
  179. data/manual/html/flags.timesheet.html +4 -4
  180. data/manual/html/fontcolor.column.html +43 -8
  181. data/manual/html/footer.html +5 -5
  182. data/manual/html/formats.html +5 -5
  183. data/manual/html/functions.html +4 -4
  184. data/manual/html/gapduration.html +4 -4
  185. data/manual/html/gaplength.html +4 -4
  186. data/manual/html/halign.center.html +4 -4
  187. data/manual/html/halign.column.html +43 -8
  188. data/manual/html/halign.left.html +4 -4
  189. data/manual/html/halign.right.html +4 -4
  190. data/manual/html/hasalert.html +4 -4
  191. data/manual/html/header.html +5 -5
  192. data/manual/html/headline.html +7 -7
  193. data/manual/html/height.html +72 -0
  194. data/manual/html/hideaccount.html +46 -11
  195. data/manual/html/hidejournalentry.html +5 -5
  196. data/manual/html/hidereport.html +43 -8
  197. data/manual/html/hideresource.html +44 -9
  198. data/manual/html/hidetask.html +44 -9
  199. data/manual/html/icalreport.html +4 -4
  200. data/manual/html/include.macro.html +4 -4
  201. data/manual/html/include.project.html +4 -4
  202. data/manual/html/include.properties.html +4 -4
  203. data/manual/html/index.html +2 -1
  204. data/manual/html/inherit.extend.html +4 -4
  205. data/manual/html/interval1.html +4 -4
  206. data/manual/html/interval2.html +4 -4
  207. data/manual/html/interval3.html +4 -4
  208. data/manual/html/interval4.html +4 -4
  209. data/manual/html/isactive.html +4 -4
  210. data/manual/html/ischildof.html +4 -4
  211. data/manual/html/isdependencyof.html +4 -4
  212. data/manual/html/isdutyof.html +4 -4
  213. data/manual/html/isfeatureof.html +4 -4
  214. data/manual/html/isleaf.html +4 -4
  215. data/manual/html/ismilestone.html +4 -4
  216. data/manual/html/isongoing.html +4 -4
  217. data/manual/html/isresource.html +4 -4
  218. data/manual/html/isresponsibilityof.html +4 -4
  219. data/manual/html/istask.html +4 -4
  220. data/manual/html/journalattributes.html +11 -7
  221. data/manual/html/journalentry.html +4 -4
  222. data/manual/html/journalmode.html +5 -5
  223. data/manual/html/leaveallowance.html +5 -5
  224. data/manual/html/leaves.html +5 -6
  225. data/manual/html/left.html +5 -5
  226. data/manual/html/length.html +4 -4
  227. data/manual/html/limits.allocate.html +4 -4
  228. data/manual/html/limits.html +4 -4
  229. data/manual/html/limits.resource.html +4 -4
  230. data/manual/html/limits.task.html +4 -4
  231. data/manual/html/listitem.column.html +4 -4
  232. data/manual/html/listtype.column.html +4 -4
  233. data/manual/html/loadunit.html +5 -5
  234. data/manual/html/logicalexpression.html +8 -44
  235. data/manual/html/logicalflagexpression.html +4 -4
  236. data/manual/html/macro.html +4 -4
  237. data/manual/html/managers.html +4 -4
  238. data/manual/html/mandatory.html +4 -4
  239. data/manual/html/maxend.html +4 -4
  240. data/manual/html/maximum.html +5 -5
  241. data/manual/html/maxstart.html +4 -4
  242. data/manual/html/milestone.html +4 -4
  243. data/manual/html/minend.html +4 -4
  244. data/manual/html/minimum.html +5 -5
  245. data/manual/html/minstart.html +4 -4
  246. data/manual/html/monthlymax.html +5 -5
  247. data/manual/html/monthlymin.html +5 -5
  248. data/manual/html/navbar.html +10 -4
  249. data/manual/html/navigator.html +4 -4
  250. data/manual/html/newtask.html +4 -4
  251. data/manual/html/nikureport.html +4 -4
  252. data/manual/html/note.task.html +4 -4
  253. data/manual/html/now.html +4 -4
  254. data/manual/html/numberformat.html +5 -5
  255. data/manual/html/onend.html +4 -4
  256. data/manual/html/onstart.html +4 -4
  257. data/manual/html/opennodes.html +5 -5
  258. data/manual/html/overtime.booking.html +4 -4
  259. data/manual/html/period.column.html +4 -4
  260. data/manual/html/period.limit.html +4 -4
  261. data/manual/html/period.report.html +5 -5
  262. data/manual/html/period.task.html +4 -4
  263. data/manual/html/persistent.html +4 -4
  264. data/manual/html/precedes.html +4 -4
  265. data/manual/html/priority.html +4 -4
  266. data/manual/html/priority.timesheet.html +4 -4
  267. data/manual/html/project.html +4 -4
  268. data/manual/html/projectid.html +4 -4
  269. data/manual/html/projectid.task.html +4 -4
  270. data/manual/html/projectids.html +4 -4
  271. data/manual/html/projection.html +5 -7
  272. data/manual/html/prolog.html +5 -5
  273. data/manual/html/properties.html +11 -5
  274. data/manual/html/purge.html +5 -5
  275. data/manual/html/rate.html +4 -4
  276. data/manual/html/rate.resource.html +4 -4
  277. data/manual/html/reference.extend.html +4 -4
  278. data/manual/html/remaining.html +4 -4
  279. data/manual/html/replace.html +4 -4
  280. data/manual/html/reportprefix.html +4 -4
  281. data/manual/html/resource.html +4 -10
  282. data/manual/html/resourceattributes.html +4 -4
  283. data/manual/html/resourceprefix.html +4 -4
  284. data/manual/html/resourcereport.html +28 -10
  285. data/manual/html/resourceroot.html +5 -5
  286. data/manual/html/resources.limit.html +4 -4
  287. data/manual/html/responsible.html +4 -4
  288. data/manual/html/richtext.extend.html +4 -4
  289. data/manual/html/right.html +5 -5
  290. data/manual/html/rollupaccount.html +44 -9
  291. data/manual/html/rollupresource.html +44 -9
  292. data/manual/html/rolluptask.html +44 -9
  293. data/manual/html/scale.column.html +4 -4
  294. data/manual/html/scenario.html +4 -22
  295. data/manual/html/scenario.ical.html +4 -4
  296. data/manual/html/scenarios.export.html +4 -4
  297. data/manual/html/scenarios.html +5 -5
  298. data/manual/html/scenariospecific.extend.html +4 -4
  299. data/manual/html/scheduled.html +4 -4
  300. data/manual/html/scheduling.html +4 -4
  301. data/manual/html/select.html +4 -4
  302. data/manual/html/selfcontained.html +5 -5
  303. data/manual/html/shift.allocate.html +4 -4
  304. data/manual/html/shift.html +4 -4
  305. data/manual/html/shift.resource.html +5 -5
  306. data/manual/html/shift.task.html +4 -4
  307. data/manual/html/shift.timesheet.html +4 -4
  308. data/manual/html/shifts.allocate.html +4 -4
  309. data/manual/html/shifts.resource.html +4 -4
  310. data/manual/html/shifts.task.html +4 -4
  311. data/manual/html/shorttimeformat.html +4 -4
  312. data/manual/html/sloppy.booking.html +4 -4
  313. data/manual/html/sloppy.projection.html +5 -5
  314. data/manual/html/sortaccounts.html +5 -5
  315. data/manual/html/sortjournalentries.html +5 -5
  316. data/manual/html/sortresources.html +5 -5
  317. data/manual/html/sorttasks.html +5 -5
  318. data/manual/html/start.column.html +4 -4
  319. data/manual/html/start.html +4 -4
  320. data/manual/html/start.limit.html +4 -4
  321. data/manual/html/start.report.html +5 -5
  322. data/manual/html/startcredit.html +4 -4
  323. data/manual/html/status.statussheet.html +4 -4
  324. data/manual/html/status.timesheet.html +4 -4
  325. data/manual/html/statussheet.html +4 -4
  326. data/manual/html/statussheetreport.html +4 -4
  327. data/manual/html/strict.projection.html +5 -5
  328. data/manual/html/summary.html +4 -4
  329. data/manual/html/supplement.html +4 -4
  330. data/manual/html/supplement.resource.html +4 -10
  331. data/manual/html/supplement.task.html +4 -28
  332. data/manual/html/tagfile.html +4 -4
  333. data/manual/html/task.html +4 -28
  334. data/manual/html/task.statussheet.html +4 -4
  335. data/manual/html/task.timesheet.html +4 -4
  336. data/manual/html/taskattributes.html +4 -4
  337. data/manual/html/taskprefix.html +4 -4
  338. data/manual/html/taskreport.html +28 -10
  339. data/manual/html/taskroot.html +5 -5
  340. data/manual/html/text.extend.html +4 -4
  341. data/manual/html/textreport.html +27 -9
  342. data/manual/html/timeformat.html +5 -5
  343. data/manual/html/timeoff.nikureport.html +4 -4
  344. data/manual/html/timesheet.html +4 -4
  345. data/manual/html/timesheetreport.html +23 -5
  346. data/manual/html/timezone.export.html +4 -4
  347. data/manual/html/timezone.html +4 -4
  348. data/manual/html/timezone.report.html +5 -5
  349. data/manual/html/timezone.shift.html +4 -4
  350. data/manual/html/timingresolution.html +4 -4
  351. data/manual/html/title.column.html +4 -4
  352. data/manual/html/title.html +5 -5
  353. data/manual/html/toc.html +207 -179
  354. data/manual/html/tooltip.column.html +45 -10
  355. data/manual/html/tracereport.html +405 -0
  356. data/manual/html/trackingscenario.html +6 -6
  357. data/manual/html/treelevel.html +4 -4
  358. data/manual/html/vacation.html +4 -4
  359. data/manual/html/vacation.resource.html +4 -4
  360. data/manual/html/vacation.shift.html +4 -4
  361. data/manual/html/warn.html +43 -8
  362. data/manual/html/weeklymax.html +5 -5
  363. data/manual/html/weeklymin.html +5 -5
  364. data/manual/html/weekstartsmonday.html +4 -4
  365. data/manual/html/weekstartssunday.html +6 -6
  366. data/manual/html/width.column.html +6 -6
  367. data/manual/html/width.html +72 -0
  368. data/manual/html/work.html +4 -4
  369. data/manual/html/workinghours.project.html +4 -4
  370. data/manual/html/workinghours.resource.html +4 -4
  371. data/manual/html/workinghours.shift.html +4 -4
  372. data/manual/html/yearlyworkingdays.html +4 -4
  373. data/spec/Color_spec.rb +60 -0
  374. data/spec/ProjectBroker_spec.rb +3 -2
  375. data/spec/StatusSheets_spec.rb +5 -4
  376. data/spec/TableColumnSorter_spec.rb +78 -0
  377. data/spec/TimeSheets_spec.rb +6 -2
  378. data/spec/Tj3Daemon_spec.rb +2 -2
  379. data/spec/TraceReport_spec.rb +117 -0
  380. data/taskjuggler.gemspec +1 -1
  381. data/test/MessageChecker.rb +3 -1
  382. data/test/ReferenceGenerator.rb +1 -1
  383. data/test/TestSuite/CSV-Reports/Leave.tjp +1 -1
  384. data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +3 -0
  385. data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +9 -0
  386. data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +19 -16
  387. data/test/TestSuite/CSV-Reports/refs/weekly.csv +1 -0
  388. data/test/TestSuite/Export-Reports/refs/LogicalExpression.tjp +14 -2
  389. data/test/TestSuite/Export-Reports/refs/tutorial.tjp +98 -86
  390. data/test/TestSuite/Scheduler/Correct/Leaves.tjp +25 -0
  391. data/test/TestSuite/Syntax/Correct/Leave.tjp +1 -1
  392. data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +9 -1
  393. data/test/TestSuite/Syntax/Correct/TraceReport.tjp +10 -0
  394. data/test/TestSuite/Syntax/Correct/tutorial.tjp +10 -4
  395. data/test/test_CSV-Reports.rb +3 -3
  396. data/test/test_Export-Reports.rb +91 -86
  397. data/test/test_Journal.rb +15 -12
  398. data/test/test_Limits.rb +3 -3
  399. data/test/test_Project.rb +1 -2
  400. data/test/test_ProjectFileScanner.rb +1 -1
  401. data/test/test_PropertySet.rb +1 -1
  402. data/test/test_Query.rb +5 -6
  403. data/test/test_ReportGenerator.rb +15 -7
  404. data/test/test_RichText.rb +4 -3
  405. data/test/test_Scheduler.rb +19 -7
  406. data/test/test_ShiftAssignments.rb +2 -2
  407. data/test/test_SimpleQueryExpander.rb +29 -2
  408. data/test/test_Syntax.rb +14 -5
  409. metadata +49 -10
  410. data/lib/taskjuggler/LogFile.rb +0 -73
@@ -51,8 +51,9 @@ class TaskJuggler::TextParser
51
51
 
52
52
  attr_reader :fileName, :macroStack
53
53
 
54
- def initialize(log)
54
+ def initialize(log, textScanner)
55
55
  @log = log
56
+ @textScanner = textScanner
56
57
  @fileName = nil
57
58
  @stream = nil
58
59
  @line = nil
@@ -63,6 +64,10 @@ class TaskJuggler::TextParser
63
64
  @nextMacroEnd = nil
64
65
  end
65
66
 
67
+ def error(id, message)
68
+ @textScanner.error(id, message)
69
+ end
70
+
66
71
  def close
67
72
  @stream = nil
68
73
  end
@@ -160,8 +165,8 @@ class TaskJuggler::TextParser
160
165
 
161
166
  attr_reader :fileName
162
167
 
163
- def initialize(fileName, log)
164
- super(log)
168
+ def initialize(fileName, log, textScanner)
169
+ super(log, textScanner)
165
170
  @fileName = fileName.dup.untaint
166
171
  data = (fileName == '.' ? $stdin : File.new(@fileName, 'r')).read
167
172
  begin
@@ -183,8 +188,8 @@ class TaskJuggler::TextParser
183
188
  # Specialized version of StreamHandle for operations on Strings.
184
189
  class BufferStreamHandle < StreamHandle
185
190
 
186
- def initialize(buffer, log)
187
- super(log)
191
+ def initialize(buffer, log, textScanner)
192
+ super(log, textScanner)
188
193
  begin
189
194
  @stream = StringIO.new(buffer.forceUTF8Encoding)
190
195
  rescue
@@ -199,9 +204,9 @@ class TaskJuggler::TextParser
199
204
  # either contains the name of the file to start with or the text itself.
200
205
  # _messageHandler_ is a MessageHandler that is used for error messages.
201
206
  # _log_ is a Log to report progress and status.
202
- def initialize(masterFile, messageHandler, log, tokenPatterns, defaultMode)
207
+ def initialize(masterFile, log, tokenPatterns, defaultMode)
203
208
  @masterFile = masterFile
204
- @messageHandler = messageHandler
209
+ @messageHandler = TaskJuggler::MessageHandlerInstance.instance
205
210
  @log = log
206
211
  # This table contains all macros that may be expanded when found in the
207
212
  # text.
@@ -279,11 +284,11 @@ class TaskJuggler::TextParser
279
284
  def open(fileNameIsBuffer = false)
280
285
  @fileNameIsBuffer = fileNameIsBuffer
281
286
  if fileNameIsBuffer
282
- @fileStack = [ [ @cf = BufferStreamHandle.new(@masterFile, @log),
287
+ @fileStack = [ [ @cf = BufferStreamHandle.new(@masterFile, @log, self),
283
288
  nil, nil ] ]
284
289
  else
285
290
  begin
286
- @fileStack = [ [ @cf = FileStreamHandle.new(@masterFile, @log),
291
+ @fileStack = [ [ @cf = FileStreamHandle.new(@masterFile, @log, self),
287
292
  nil, nil ] ]
288
293
  rescue IOError, SystemCallError
289
294
  error('open_file', "Cannot open file #{@masterFile}: #{$!}")
@@ -332,8 +337,8 @@ class TaskJuggler::TextParser
332
337
 
333
338
  # Open the new file and push the handle on the @fileStack.
334
339
  begin
335
- @fileStack << [ (@cf = FileStreamHandle.new(includeFileName, @log)),
336
- nil, block ]
340
+ @fileStack << [ (@cf = FileStreamHandle.new(includeFileName, @log,
341
+ self)), nil, block ]
337
342
  @log.msg { "Parsing file #{includeFileName}" }
338
343
  rescue StandardError
339
344
  error('bad_include', "Cannot open include file #{includeFileName}", sfi)
@@ -11,25 +11,30 @@
11
11
  # published by the Free Software Foundation.
12
12
  #
13
13
 
14
- class TaskJuggler::TextParser
14
+ class TaskJuggler
15
15
 
16
- # Simple class that holds the info about a source file reference.
17
- class SourceFileInfo
16
+ class TextParser
18
17
 
19
- attr_reader :fileName, :lineNo, :columnNo
18
+ # Simple class that holds the info about a source file reference.
19
+ class SourceFileInfo
20
20
 
21
- # Create a new SourceFileInfo object. _file_ is the name of the file. _line_
22
- # is the line in this file, _col_ is the column number in the line.
23
- def initialize(file, line, col)
24
- @fileName = file
25
- @lineNo = line
26
- @columnNo = col
27
- end
21
+ attr_reader :fileName, :lineNo, :columnNo
22
+
23
+ # Create a new SourceFileInfo object. _file_ is the name of the file.
24
+ # _line_ is the line in this file, _col_ is the column number in the
25
+ # line.
26
+ def initialize(file, line, col)
27
+ @fileName = file
28
+ @lineNo = line
29
+ @columnNo = col
30
+ end
31
+
32
+ # Return the info in the common "filename:line:" format.
33
+ def to_s
34
+ # The column is not reported for now.
35
+ "#{@fileName}:#{@lineNo}:"
36
+ end
28
37
 
29
- # Return the info in the common "filename:line:" format.
30
- def to_s
31
- # The column is not reported for now.
32
- "#{@fileName}:#{@lineNo}:"
33
38
  end
34
39
 
35
40
  end
@@ -20,6 +20,8 @@ class TaskJuggler
20
20
  # work during the reporting time frame.
21
21
  class TimeSheetRecord
22
22
 
23
+ include MessageHandler
24
+
23
25
  attr_reader :task, :work
24
26
  attr_accessor :sourceFileInfo, :remaining, :expectedEnd, :status,
25
27
  :priority, :name
@@ -233,14 +235,6 @@ class TaskJuggler
233
235
 
234
236
  private
235
237
 
236
- def error(id, text)
237
- @timeSheet.error(id, text, @sourceFileInfo)
238
- end
239
-
240
- def warning(id, text)
241
- @timeSheet.warning(id, text, @sourceFileInfo)
242
- end
243
-
244
238
  end
245
239
 
246
240
  # The TimeSheet class stores the work related bits of a time sheet. For each
@@ -264,6 +258,7 @@ class TaskJuggler
264
258
  @percentageUsed = false
265
259
  # The TimeSheetRecord list.
266
260
  @records = []
261
+ @messageHandler = MessageHandlerInstance.instance
267
262
  end
268
263
 
269
264
  # Add a new TimeSheetRecord to the list.
@@ -368,13 +363,12 @@ class TaskJuggler
368
363
  end
369
364
 
370
365
  def error(id, text, sourceFileInfo = nil)
371
- @resource.project.messageHandler.error(
372
- id, text, sourceFileInfo || @sourceFileInfo, nil, @resource)
366
+ @messageHandler.error(id, text, sourceFileInfo || @sourceFileInfo,
367
+ nil, @resource)
373
368
  end
374
369
 
375
370
  def warning(id, text, sourceFileInfo = nil)
376
- @resource.project.messageHandler.warning(id, text, sourceFileInfo, nil,
377
- @resource)
371
+ @messageHandler.warning(id, text, sourceFileInfo, nil, @resource)
378
372
  end
379
373
 
380
374
  private
@@ -18,15 +18,15 @@ require 'taskjuggler/Tj3Config'
18
18
  require 'taskjuggler/RuntimeConfig'
19
19
  require 'taskjuggler/TjTime'
20
20
  require 'taskjuggler/TextFormatter'
21
+ require 'taskjuggler/MessageHandler'
21
22
  require 'taskjuggler/Log'
22
23
 
23
24
  class TaskJuggler
24
25
 
25
- class TjRuntimeError < RuntimeError
26
- end
27
-
28
26
  class Tj3AppBase
29
27
 
28
+ include MessageHandler
29
+
30
30
  def initialize
31
31
  # Indent and width of options. The deriving class may has to change
32
32
  # this.
@@ -42,6 +42,9 @@ class TaskJuggler
42
42
  # the terminal output. Additionally, we have the --no-color option to
43
43
  # force colors off in case this does not work properly.
44
44
  Term::ANSIColor.coloring = STDOUT.tty?
45
+
46
+ # Make sure the MessageHandler is set to default values.
47
+ MessageHandlerInstance.instance.reset
45
48
  end
46
49
 
47
50
  def processArguments(argv)
@@ -66,6 +69,7 @@ class TaskJuggler
66
69
  @opts.on('--silent',
67
70
  format("Don't show program and progress information")) do
68
71
  @silent = true
72
+ MessageHandlerInstance.instance.outputLevel = :warning
69
73
  TaskJuggler::Log.silent = true
70
74
  end
71
75
  @opts.on('--no-color',
@@ -97,7 +101,7 @@ EOT
97
101
  files = @opts.parse(argv)
98
102
  rescue OptionParser::ParseError => msg
99
103
  puts @opts.to_s + "\n"
100
- error(msg.message, 2)
104
+ error('tj3app_bad_cmd_options', msg.message)
101
105
  end
102
106
 
103
107
  files
@@ -106,15 +110,21 @@ EOT
106
110
  def main(argv = ARGV)
107
111
  if Gem::Version.new(RUBY_VERSION.dup) <
108
112
  Gem::Version.new(@mininumRubyVersion)
109
- error('This program requires at least Ruby version ' +
113
+ error('tj3app_ruby_version',
114
+ 'This program requires at least Ruby version ' +
110
115
  "#{@mininumRubyVersion}!")
111
116
  end
112
117
 
113
118
  # Install signal handler to exit gracefully on CTRL-C.
114
119
  intHandler = Kernel.trap('INT') do
115
- error("Aborting on user request!")
120
+ begin
121
+ fatal('tj3app_user_abort', "Aborting on user request!")
122
+ rescue RuntimeError
123
+ exit 1
124
+ end
116
125
  end
117
126
 
127
+ retVal = 0
118
128
  begin
119
129
  args = processArguments(argv)
120
130
 
@@ -132,19 +142,33 @@ EOT
132
142
 
133
143
  @rc = RuntimeConfig.new(AppConfig.packageName, @configFile)
134
144
 
135
- appMain(args)
145
+ begin
146
+ MessageHandlerInstance.instance.trapSetup = true
147
+ retVal = appMain(args)
148
+ MessageHandlerInstance.instance.trapSetup = false
149
+ rescue TjRuntimeError
150
+ # We have hit a sitatuation that we can't recover from. A message
151
+ # was severed via the MessageHandler to inform the user and we now
152
+ # abort the program.
153
+ return 1
154
+ end
155
+
136
156
  rescue Exception => e
137
157
  if e.is_a?(SystemExit) || e.is_a?(Interrupt)
138
158
  # Don't show backtrace on user interrupt unless we are in debug mode.
139
159
  $stderr.puts e.backtrace.join("\n") if $DEBUG
140
160
  1
141
161
  else
142
- error("Ups, you have triggered a bug in #{AppConfig.softwareName}!\n" +
143
- "#{e}\n" +
144
- e.backtrace.join("\n") +
145
- "Please see the user manual on how to get this bug fixed!")
162
+ fatal('crash_trap', "#{e}\n#{e.backtrace.join("\n")}\n\n" +
163
+ "#{'*' * 79}\nYou have triggered a bug in " +
164
+ "#{AppConfig.softwareName} version #{AppConfig.version}!\n" +
165
+ "Please see the user manual on how to get this bug fixed!\n" +
166
+ "#{'*' * 79}\n")
146
167
  end
147
168
  end
169
+
170
+ # Exit value in case everything was fine.
171
+ retVal
148
172
  end
149
173
 
150
174
  private
@@ -153,11 +177,6 @@ EOT
153
177
  exit 0
154
178
  end
155
179
 
156
- def error(message, exitVal = 1)
157
- $stderr.puts "\nERROR: #{message}"
158
- exit exitVal
159
- end
160
-
161
180
  def format(str, indent = nil)
162
181
  indent = @optsSummaryWidth + @optsSummaryIndent + 1 unless indent
163
182
  TextFormatter.new(79, indent).format(str)[indent..-1]
@@ -14,7 +14,7 @@
14
14
  require 'taskjuggler/UTF8String'
15
15
  require 'taskjuggler/AppConfig'
16
16
 
17
- AppConfig.version = '3.1.0'
17
+ AppConfig.version = '3.2.0'
18
18
  AppConfig.packageName = 'taskjuggler'
19
19
  AppConfig.softwareName = 'TaskJuggler'
20
20
  AppConfig.packageInfo = 'A Project Management Software'
@@ -109,7 +109,8 @@ EOT
109
109
  })
110
110
  level(:beta)
111
111
  doc('accountreport', <<'EOT'
112
- The report lists accounts and their respective values in a table. The report can operate in two modes:
112
+ The report lists accounts and their respective values in a table. The report
113
+ can operate in two modes:
113
114
 
114
115
  # Balance mode: If a [[balance]] has been set, the report will include the
115
116
  defined cost and revenue accounts as well as all their sub accounts. To reduce
@@ -416,6 +417,15 @@ EOT
416
417
  })
417
418
  end
418
419
 
420
+ def rule_allOrNone
421
+ pattern(%w( _all ), lambda {
422
+ 1
423
+ })
424
+ pattern(%w( _none ), lambda {
425
+ 0
426
+ })
427
+ end
428
+
419
429
  def rule_argument
420
430
  singlePattern('$ABSOLUTE_ID')
421
431
  singlePattern('!date')
@@ -695,9 +705,7 @@ EOT
695
705
 
696
706
  def rule_columnId
697
707
  pattern(%w( !reportableAttributes ), lambda {
698
- title = TableReport.defaultColumnTitle(@val[0]) ||
699
- @project.attributeName(@val[0])
700
- @column = TableColumnDefinition.new(@val[0], title)
708
+ @column = TableColumnDefinition.new(@val[0], columnTitle(@val[0]))
701
709
  })
702
710
  doc('columnid', <<'EOT'
703
711
  This is a comprehensive list of all pre-defined [[columns]]. In addition to
@@ -896,7 +904,9 @@ EOT
896
904
  @val[0]
897
905
  })
898
906
  doc('date', <<'EOT'
899
- A DATE is an ISO-compliant date in the format
907
+ A DATE is date and time specification similar to the ISO 8601 date format.
908
+ Instead of the hard to read ISO notation with a ''''T'''' between the date and
909
+ time sections, we simply use the more intuitive and easier to read dash:
900
910
  ''''<nowiki>YYYY-MM-DD[-hh:mm[:ss]][-TIMEZONE]</nowiki>''''. Hour, minutes,
901
911
  seconds, and the ''''TIMEZONE'''' are optional. If not specified, the values
902
912
  are set to 0. ''''TIMEZONE'''' must be an offset to GMT or UTC, specified as
@@ -908,7 +918,10 @@ given interval from a fixed date.
908
918
 
909
919
  %{2009-11-01 + 8m}
910
920
 
911
- This will result in an actual date of around 2009-07-01. Keep in mind that due to the varying lengths of months TaskJuggler cannot add exactly 8 calendar months. The date calculation functionality makes most sense when used with macros.
921
+ This will result in an actual date of around 2009-07-01. Keep in mind that due
922
+ to the varying lengths of months TaskJuggler cannot add exactly 8 calendar
923
+ months. The date calculation functionality makes most sense when used with
924
+ macros.
912
925
 
913
926
  %{${now} - 2w}
914
927
 
@@ -1952,7 +1965,8 @@ the journal report.
1952
1965
  EOT
1953
1966
  )
1954
1967
  allOrNothingListRule('journalReportAttributesList',
1955
- { 'author' => 'Include the author if known',
1968
+ { 'alert' => 'Include the alert status',
1969
+ 'author' => 'Include the author if known',
1956
1970
  'date' => 'Include the date',
1957
1971
  'details' => 'Include the details',
1958
1972
  'flags' => 'Include the flags',
@@ -2187,7 +2201,6 @@ periods that are partially outside of the project period only the part inside
2187
2201
  the project period will be considered.
2188
2202
  EOT
2189
2203
  )
2190
- level(:beta)
2191
2204
  example('Leave')
2192
2205
  end
2193
2206
 
@@ -2441,6 +2454,9 @@ EOT
2441
2454
  pattern(%w( !operation ), lambda {
2442
2455
  LogicalExpression.new(@val[0], sourceFileInfo)
2443
2456
  })
2457
+ pattern(%w( _@ !allOrNone ), lambda {
2458
+ LogicalOperation.new(@val[1])
2459
+ })
2444
2460
  doc('logicalexpression', <<'EOT'
2445
2461
  A logical expression is a combination of operands and mathematical operations.
2446
2462
  The final result of a logical expression is always true or false. Logical
@@ -2460,7 +2476,7 @@ concept of operator precedence or right-left associativity. This may change in
2460
2476
  the future.
2461
2477
 
2462
2478
  An operand can also be just a number. 0 evaluates to false, all other numbers
2463
- to true.
2479
+ to true. The logical expression can also be the special constants ''''@all'''' or ''''@none''''. The first always evaluates to true, the latter to false.
2464
2480
  EOT
2465
2481
  )
2466
2482
  also(%w( functions ))
@@ -2809,10 +2825,12 @@ EOT
2809
2825
  arg(0, 'operand', <<'EOT'
2810
2826
  An operand can consist of a date, a text string, a [[functions|function]], a
2811
2827
  property attribute or a numerical value. It can also be the name of a declared
2812
- flag. Use the ''''scenario_id.attribute'''' notation to use an attribute of the
2813
- currently evaluated property. The scenario ID always has to be specified, also
2814
- for non-scenario specific attributes. This is necessary to distinguish them
2815
- from flags.
2828
+ flag. Use the ''''scenario_id.attribute'''' notation to use an attribute of
2829
+ the currently evaluated property. The scenario ID always has to be specified,
2830
+ also for non-scenario specific attributes. This is necessary to distinguish
2831
+ them from flags. See [[columnid]] for a list of available attributes. The use
2832
+ of list attributes is not recommended. User defined attributes are available
2833
+ as well.
2816
2834
 
2817
2835
  An operand can be a negated operand by prefixing a ~ charater or it can be
2818
2836
  another logical expression enclosed in braces.
@@ -3188,7 +3206,7 @@ EOT
3188
3206
 
3189
3207
  def rule_projectHeader
3190
3208
  pattern(%w( _project !optionalID $STRING !optionalVersion !interval ), lambda {
3191
- @project = Project.new(@val[1], @val[2], @val[3], @messageHandler)
3209
+ @project = Project.new(@val[1], @val[2], @val[3])
3192
3210
  @project['start'] = @val[4].start
3193
3211
  @project['end'] = @val[4].end
3194
3212
  @projectId = @val[1]
@@ -3302,8 +3320,8 @@ EOT
3302
3320
  example('Caption', '2')
3303
3321
 
3304
3322
  pattern(%w( !balance ), lambda {
3305
- @project['costAccount'] = @val[0][0]
3306
- @project['revenueAccount'] = @val[0][1]
3323
+ @project['costaccount'] = @val[0][0]
3324
+ @project['revenueaccount'] = @val[0][1]
3307
3325
  })
3308
3326
 
3309
3327
  pattern(%w( _flags !declareFlagList ), lambda {
@@ -3390,11 +3408,8 @@ EOT
3390
3408
  pattern(%w( !task ))
3391
3409
  pattern(%w( !timeSheet ))
3392
3410
  pattern(%w( _vacation !vacationName !intervals ), lambda {
3393
- begin
3394
- @val[2].each do |interval|
3395
- @project['leaves'] << Leave.new(:holiday, interval)
3396
- end
3397
- rescue AttributeOverwrite
3411
+ @val[2].each do |interval|
3412
+ @project['leaves'] << Leave.new(:holiday, interval)
3398
3413
  end
3399
3414
  })
3400
3415
  doc('vacation', <<'EOT'
@@ -3494,9 +3509,18 @@ EOT
3494
3509
  pattern(%w( !resourceReport ))
3495
3510
  pattern(%w( !taskReport ))
3496
3511
  pattern(%w( !textReport ))
3512
+ pattern(%w( !traceReport ))
3497
3513
  end
3498
3514
 
3499
3515
  def rule_reportableAttributes
3516
+ singlePattern('_activetasks')
3517
+ descr(<<'EOT'
3518
+ The number of sub-tasks (including the current task) that are active in the
3519
+ reported time period. Active means that they are ongoing at the current time
3520
+ or [[now]] date.
3521
+ EOT
3522
+ )
3523
+
3500
3524
  singlePattern('_annualleave')
3501
3525
  descr(<<'EOT'
3502
3526
  The number of annual leave units within the reported time period. The unit
@@ -3552,6 +3576,14 @@ height. This does not work well with rich text columns in some browsers. Some
3552
3576
  show a scrollbar for the compressed table cells, others don't. It is
3553
3577
  recommended, that you don't use rich text columns in conjuction with the chart
3554
3578
  column.
3579
+ EOT
3580
+ )
3581
+
3582
+ singlePattern('_closedtasks')
3583
+ descr(<<'EOT'
3584
+ The number of sub-tasks (including the current task) that have been closed
3585
+ during the reported time period. Closed means that they have and end date
3586
+ before the current time or [[now]] date.
3555
3587
  EOT
3556
3588
  )
3557
3589
 
@@ -3594,7 +3626,7 @@ EOT
3594
3626
  descr(<<'EOT'
3595
3627
  The resources that have this resource assigned as manager.
3596
3628
 
3597
- The list can be customized by the [listitem.column listitem] attribute.
3629
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3598
3630
  EOT
3599
3631
  )
3600
3632
 
@@ -3636,7 +3668,7 @@ symbols are used for <nowiki><dep></nowiki>.
3636
3668
  * '''<nowiki>]->]</nowiki>''': End-to-End dependency
3637
3669
  * '''<nowiki>[->]</nowiki>''': Start-to-End dependency
3638
3670
 
3639
- The list can be customized by the [listitem.column listitem] attribute.
3671
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3640
3672
  The dependency symbol can be generated via the ''''dependency'''' attribute
3641
3673
  inthe query, the target date via the ''''date'''' attribute.
3642
3674
  EOT
@@ -3706,7 +3738,7 @@ A list of milestones that are a prerequiste for the current task. For
3706
3738
  container tasks it will also include the inputs of the child tasks. Inputs may
3707
3739
  not have any predecessors.
3708
3740
 
3709
- The list can be customized by the [listitem.column listitem] attribute.
3741
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3710
3742
  EOT
3711
3743
  )
3712
3744
 
@@ -3742,7 +3774,7 @@ EOT
3742
3774
  descr(<<'EOT'
3743
3775
  A list of managers that the resource reports to.
3744
3776
 
3745
- The list can be customized by the [listitem.column listitem] attribute.
3777
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3746
3778
  EOT
3747
3779
  )
3748
3780
 
@@ -3770,6 +3802,14 @@ EOT
3770
3802
  singlePattern('_note')
3771
3803
  descr('The note attached to a task')
3772
3804
 
3805
+ singlePattern('_opentasks')
3806
+ descr(<<'EOT'
3807
+ The number of sub-tasks (including the current task) that have not yet been
3808
+ closed during the reported time period. Closed means that they have and end
3809
+ date before the current time or [[now]] date.
3810
+ EOT
3811
+ )
3812
+
3773
3813
  singlePattern('_pathcriticalness')
3774
3814
  descr('The criticalness of the task with respect to all the paths that ' +
3775
3815
  'it is a part of.')
@@ -3785,7 +3825,7 @@ are used
3785
3825
  * '''<nowiki>]->]</nowiki>''': End-to-End dependency
3786
3826
  * '''<nowiki>[->]</nowiki>''': Start-to-End dependency
3787
3827
 
3788
- The list can be customized by the [listitem.column listitem] attribute.
3828
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3789
3829
  The dependency symbol can be generated via the ''''dependency'''' attribute
3790
3830
  inthe query, the target date via the ''''date'''' attribute.
3791
3831
  EOT
@@ -3804,7 +3844,7 @@ EOT
3804
3844
  descr(<<'EOT'
3805
3845
  All resources that have this resource assigned as a direct or indirect manager.
3806
3846
 
3807
- The list can be customized by the [listitem.column listitem] attribute.
3847
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3808
3848
  EOT
3809
3849
  )
3810
3850
 
@@ -3812,7 +3852,7 @@ EOT
3812
3852
  descr(<<'EOT'
3813
3853
  A list of resources that are assigned to the task in the report time frame.
3814
3854
 
3815
- The list can be customized by the [listitem.column listitem] attribute.
3855
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3816
3856
  EOT
3817
3857
  )
3818
3858
 
@@ -3820,7 +3860,7 @@ EOT
3820
3860
  descr(<<'EOT'
3821
3861
  The responsible people for this task.
3822
3862
 
3823
- The list can be customized by the [listitem.column listitem] attribute.
3863
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3824
3864
  EOT
3825
3865
  )
3826
3866
 
@@ -3867,7 +3907,7 @@ A list of milestones that depend on the current task. For container tasks it
3867
3907
  will also include the targets of the child tasks. Targets may not have any
3868
3908
  follower tasks.
3869
3909
 
3870
- The list can be customized by the [listitem.column listitem] attribute.
3910
+ The list can be customized by the [[listitem.column|listitem]] attribute.
3871
3911
  EOT
3872
3912
  )
3873
3913
 
@@ -3903,7 +3943,7 @@ EOT
3903
3943
  "#{@val[1].fullId} is not a container account",
3904
3944
  @sourceFileInfo[1])
3905
3945
  end
3906
- @property.set('accountRoot', @val[1])
3946
+ @property.set('accountroot', @val[1])
3907
3947
  })
3908
3948
  doc('accountroot', <<'EOT'
3909
3949
  Only accounts below the specified root-level accounts are exported. The exported
@@ -3915,8 +3955,8 @@ EOT
3915
3955
  example('AccountReport')
3916
3956
 
3917
3957
  pattern(%w( !balance ), lambda {
3918
- @property.set('costAccount', @val[0][0])
3919
- @property.set('revenueAccount', @val[0][1])
3958
+ @property.set('costaccount', @val[0][0])
3959
+ @property.set('revenueaccount', @val[0][1])
3920
3960
  })
3921
3961
 
3922
3962
  pattern(%w( _caption $STRING ), lambda {
@@ -4006,6 +4046,24 @@ EOT
4006
4046
  pattern(%w( !hideaccount ))
4007
4047
  pattern(%w( !hideresource ))
4008
4048
  pattern(%w( !hidetask ))
4049
+
4050
+ pattern(%w( _height $INTEGER ), lambda {
4051
+ if @val[1] < 200
4052
+ error('min_report_height',
4053
+ "The report must have a minimum height of 200 pixels.")
4054
+ end
4055
+ @property.set('height', @val[1])
4056
+ })
4057
+ doc('height', <<'EOT'
4058
+ Set the height of the report in pixels. This attribute is only used for
4059
+ reports that cannot determine the height based on the content. Such report can
4060
+ be freely resized to fit in. The vast majority of reports can determine their
4061
+ height based on the provided content. These reports will simply ignore this
4062
+ setting.
4063
+ EOT
4064
+ )
4065
+ also('width')
4066
+
4009
4067
  pattern(%w( !journalReportAttributes ))
4010
4068
  pattern(%w( _journalmode !journalReportMode ), lambda {
4011
4069
  @property.set('journalMode', @val[1])
@@ -4110,7 +4168,7 @@ EOT
4110
4168
  "#{@val[1].fullId} is not a group resource",
4111
4169
  @sourceFileInfo[1])
4112
4170
  end
4113
- @property.set('resourceRoot', @val[1])
4171
+ @property.set('resourceroot', @val[1])
4114
4172
  })
4115
4173
  doc('resourceroot', <<'EOT'
4116
4174
  Only resources below the specified root-level resources are exported. The
@@ -4127,7 +4185,7 @@ EOT
4127
4185
  "#{@val[1].fullId} is not a container task",
4128
4186
  @sourceFileInfo[1])
4129
4187
  end
4130
- @property.set('taskRoot', @val[1])
4188
+ @property.set('taskroot', @val[1])
4131
4189
  })
4132
4190
  doc('taskroot', <<'EOT'
4133
4191
  Only tasks below the specified root-level tasks are exported. The exported
@@ -4154,6 +4212,23 @@ EOT
4154
4212
  )
4155
4213
 
4156
4214
  pattern(%w( !reportTitle ))
4215
+
4216
+ pattern(%w( _width $INTEGER ), lambda {
4217
+ if @val[1] < 400
4218
+ error('min_report_width',
4219
+ "The report must have a minimum width of 400 pixels.")
4220
+ end
4221
+ @property.set('width', @val[1])
4222
+ })
4223
+ doc('width', <<'EOT'
4224
+ Set the width of the report in pixels. This attribute is only used for
4225
+ reports that cannot determine the width based on the content. Such report can
4226
+ be freely resized to fit in. The vast majority of reports can determine their
4227
+ width based on the provided content. These reports will simply ignore this
4228
+ setting.
4229
+ EOT
4230
+ )
4231
+ also('height')
4157
4232
  end
4158
4233
 
4159
4234
  def rule_reportEnd
@@ -4418,8 +4493,9 @@ sorting, the parent resources will always be included to form the tree.
4418
4493
  Tree sorting is the default. You need to change it if you do not want certain
4419
4494
  parent resources to be included in the report.
4420
4495
 
4421
- The tasks that the resources are allocated to can be included as well. Use the
4422
- [[hidetask]] attribute for this.
4496
+ By default, all the tasks that the resources are allocated to are hidden, but
4497
+ they can be listed as well. Use the [[hidetask]] attribute to select which
4498
+ tasks should be included.
4423
4499
  EOT
4424
4500
  )
4425
4501
  end
@@ -4428,7 +4504,7 @@ EOT
4428
4504
  pattern(%w( _resourcereport !optionalID !reportName ), lambda {
4429
4505
  newReport(@val[1], @val[2], :resourcereport, @sourceFileInfo[0])
4430
4506
 
4431
- if @property.modified?('columns')
4507
+ unless @property.modified?('columns')
4432
4508
  # Set the default columns for this report.
4433
4509
  %w( no name ).each do |col|
4434
4510
  @property.get('columns') <<
@@ -4603,12 +4679,12 @@ EOT
4603
4679
  )
4604
4680
 
4605
4681
  pattern(%w( _vacation !vacationName !intervals ), lambda {
4606
- begin
4607
- @val[2].each do |interval|
4682
+ @val[2].each do |interval|
4683
+ begin
4608
4684
  # We map the old 'vacation' attribute to public holidays.
4609
- @property['leaves', @scenarioIdx] << Leave.new(:holiday, interval)
4685
+ @property['leaves', @scenarioIdx] += [ Leave.new(:holiday, interval) ]
4686
+ rescue AttributeOverwrite
4610
4687
  end
4611
- rescue AttributeOverwrite
4612
4688
  end
4613
4689
  })
4614
4690
  doc('vacation.resource', <<'EOT'
@@ -4943,12 +5019,12 @@ EOT
4943
5019
  )
4944
5020
 
4945
5021
  pattern(%w( _vacation !vacationName !intervalsOptional ), lambda {
4946
- begin
4947
- @val[2].each do |interval|
5022
+ @val[2].each do |interval|
5023
+ begin
4948
5024
  # We map the old 'vacation' attribute to public holidays.
4949
- @property['leaves', @scenarioIdx] << Leave.new(:holiday, interval)
5025
+ @property['leaves', @scenarioIdx] += [ Leave.new(:holiday, interval) ]
5026
+ rescue AttributeOverwrite
4950
5027
  end
4951
- rescue AttributeOverwrite
4952
5028
  end
4953
5029
  })
4954
5030
  doc('vacation.shift', <<'EOT'
@@ -5719,8 +5795,9 @@ will always be included to form the tree. Tree sorting is the default. You
5719
5795
  need to change it if you do not want certain parent tasks to be included in
5720
5796
  the report.
5721
5797
 
5722
- The resources that are allocated to each task can be listed as well. Use the
5723
- [[hideresource]] attribute for this.
5798
+ By default, all the resources that are allocated to each task are hidden, but
5799
+ they can be listed as well. Use the [[hideresource]] attribute to select which
5800
+ resources should be included.
5724
5801
  EOT
5725
5802
  )
5726
5803
  example('HtmlTaskReport')
@@ -6632,6 +6709,107 @@ EOT
6632
6709
  )
6633
6710
  end
6634
6711
 
6712
+ def rule_traceReport
6713
+ pattern(%w( !traceReportHeader !reportBody ), lambda {
6714
+ @property = @property.parent
6715
+ })
6716
+ doc('tracereport', <<'EOT'
6717
+ The trace report works noticeably different than all other TaskJuggler
6718
+ reports. It uses a CSV file to track the values of the selected attributes.
6719
+ Each time ''''tj3'''' is run with the ''''--add-trace'''' option, a new set of
6720
+ values is appended to the CSV file. The first column of the CSV file holds the
6721
+ date when the snapshot was taken. This is either the current date or the
6722
+ ''''now'''' date if provided. There is no need to specify CSV as output format
6723
+ for the report. You can either use these tracked values directly by specifying other report formats or by importing the CSV file into another program.
6724
+
6725
+ The first column always contains the current date when that
6726
+ table row was added. All subsequent columns can be defined by the user with
6727
+ the [[columns]] attribute. This column set is then repeated for all properties
6728
+ that are not hidden by [[hideaccount]], [[hideresource]] and [[hidetask]]. By
6729
+ default, all properties are excluded. You must provide at least one of the
6730
+ ''''hide...'''' attributes to select the properties you want to have included
6731
+ in the report. Please be aware that total number of columns is the product of
6732
+ attributes defined with [[columns]] times the number of included properties.
6733
+ Select you values carefully or you will end up with very large reports.
6734
+
6735
+ The column headers can be customized by using the [[title.column|title]]
6736
+ attribute. When you include multiple properties, these headers are not unique
6737
+ unless you include mini-queries to modify them based on the property they
6738
+ colum is represeting. You can use the queries
6739
+ ''''<nowiki><-id-></nowiki>'''', ''''<nowiki><-name-></nowiki>'''',
6740
+ ''''<nowiki><-scenario-></nowiki>'''' and
6741
+ ''''<nowiki><-attribute-></nowiki>''''. ''''<nowiki><-id-></nowiki>'''' is
6742
+ replaced with the ID of the property, ''''<nowiki><-name-></nowiki>'''' with
6743
+ the name and so on.
6744
+
6745
+ You can change the set of tracked values over time. Old values will be
6746
+ preserved and the corresponding columns will be the last ones in the CSV file.
6747
+
6748
+ When other formats are requested, the CSV file is read in and a report that
6749
+ shows the tracked values over time will be generated. The CSV file may contain
6750
+ all kinds of values that are being tracked. Report formats that don't support
6751
+ a mix of different values will just show the values of the second column.
6752
+
6753
+ The HTML version generates SVG graphs that are embedded in the HTML page.
6754
+ These graphs are only visble if the web browser supports HTML5. This is true
6755
+ for the latest generation of browsers, but older browsers may not support this
6756
+ format.
6757
+ EOT
6758
+ )
6759
+ example('TraceReport')
6760
+ end
6761
+
6762
+ def rule_traceReportHeader
6763
+ pattern(%w( _tracereport !optionalID !reportName ), lambda {
6764
+ newReport(@val[1], @val[2], :tracereport, @sourceFileInfo[0])
6765
+
6766
+ # The top-level always inherits the global timeFormat setting. This is
6767
+ # not desireable in this case, so we ignore this.
6768
+ if (@property.level == 0 && !@property.provided('timeFormat')) ||
6769
+ (@property.level > 0 && !@property.modified?('timeFormat'))
6770
+ # CSV readers such of Libre-/OpenOffice can't deal with time zones. We
6771
+ # probably also don't need seconds.
6772
+ @property.set('timeFormat', '%Y-%m-%d-%H:%M')
6773
+ end
6774
+ unless @property.modified?('columns')
6775
+ # Set the default columns for this report.
6776
+ %w( end ).each do |col|
6777
+ @property.get('columns') <<
6778
+ TableColumnDefinition.new(col, columnTitle(col))
6779
+ end
6780
+ end
6781
+ # Hide all accounts.
6782
+ unless @property.modified?('hideAccount')
6783
+ @property.set('hideAccount',
6784
+ LogicalExpression.new(LogicalOperation.new(1)))
6785
+ end
6786
+ unless @property.modified?('sortAccounts')
6787
+ @property.set('sortAccounts',
6788
+ [ [ 'tree', true, -1 ],
6789
+ [ 'seqno', true, -1 ] ])
6790
+ end
6791
+ # Show all tasks, sorted by tree, start-up, seqno-up.
6792
+ unless @property.modified?('hideTask')
6793
+ @property.set('hideTask',
6794
+ LogicalExpression.new(LogicalOperation.new(0)))
6795
+ end
6796
+ unless @property.modified?('sortTasks')
6797
+ @property.set('sortTasks',
6798
+ [ [ 'tree', true, -1 ],
6799
+ [ 'start', true, 0 ],
6800
+ [ 'seqno', true, -1 ] ])
6801
+ end
6802
+ # Show no resources, but set sorting to id-up.
6803
+ unless @property.modified?('hideResource')
6804
+ @property.set('hideResource',
6805
+ LogicalExpression.new(LogicalOperation.new(1)))
6806
+ end
6807
+ unless @property.modified?('sortResources')
6808
+ @property.set('sortResources', [ [ 'id', true, -1 ] ])
6809
+ end
6810
+ })
6811
+ end
6812
+
6635
6813
  def rule_tsNewTaskHeader
6636
6814
  pattern(%w( _newtask !taskIdUnverifd $STRING ), lambda {
6637
6815
  @timeSheetRecord = TimeSheetRecord.new(@timeSheet, @val[1])
@@ -6670,9 +6848,12 @@ EOT
6670
6848
  repeatable
6671
6849
 
6672
6850
  pattern(%w( !hideresource ))
6851
+ pattern(%w( !hidetask ))
6673
6852
  pattern(%w( !reportEnd ))
6674
6853
  pattern(%w( !reportPeriod ))
6675
6854
  pattern(%w( !reportStart ))
6855
+ pattern(%w( !sortResources ))
6856
+ pattern(%w( !sortTasks ))
6676
6857
  end
6677
6858
 
6678
6859
  def rule_tsReportBody
@@ -7053,7 +7234,6 @@ EOT
7053
7234
  unless (wh = @property['workinghours', @scenarioIdx])
7054
7235
  # The property does not have it's own WorkingHours yet.
7055
7236
  wh = WorkingHours.new(@project['workinghours'])
7056
- @property['workinghours', @scenarioIdx] = wh
7057
7237
  end
7058
7238
  end
7059
7239
  wh.timezone = @project['timezone']
@@ -7062,6 +7242,16 @@ EOT
7062
7242
  rescue
7063
7243
  error('bad_workinghours', $!.message)
7064
7244
  end
7245
+
7246
+ if @property
7247
+ # Make sure we actually assign something so the attribute is marked as
7248
+ # set by the user.
7249
+ begin
7250
+ @property['workinghours', @scenarioIdx] = wh
7251
+ rescue AttributeOverwrite
7252
+ # Working hours can be set multiple times.
7253
+ end
7254
+ end
7065
7255
  })
7066
7256
  end
7067
7257