taskjuggler 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -31,13 +31,10 @@ class TaskJuggler
31
31
 
32
32
  include TjpSyntaxRules
33
33
 
34
- # Create the parser object. _messageHandler_ is a TjMessageHandler that is
35
- # used for error reporting.
36
- def initialize(messageHandler)
34
+ # Create the parser object.
35
+ def initialize
37
36
  super
38
37
 
39
- @tjMessageHandler = messageHandler
40
-
41
38
  # Define the token types that the ProjectFileScanner may return for
42
39
  # variable elements.
43
40
  @variables = [ :INTEGER, :FLOAT, :DATE, :TIME, :STRING, :LITERAL,
@@ -52,7 +49,7 @@ class TaskJuggler
52
49
  # Call this function with the master file to start processing a TJP file or
53
50
  # a set of TJP files.
54
51
  def open(file, master, fileNameIsBuffer = false)
55
- @scanner = ProjectFileScanner.new(file, @messageHandler)
52
+ @scanner = ProjectFileScanner.new(file)
56
53
  # We need the ProjectFileScanner object for error reporting.
57
54
  if master && !fileNameIsBuffer && file != '.' && file[-4, 4] != '.tjp'
58
55
  error('illegal_extension', "Project file name must end with " +
@@ -216,22 +213,19 @@ class TaskJuggler
216
213
  # variable tokens, a subset can be provided by _tokenSet_.
217
214
  def newRichText(text, sfi, tokenSet = nil)
218
215
  rText = RichText.new(text, RTFHandlers.create(@project, sfi))
219
- unless (rti = rText.generateIntermediateFormat( [ 0, 0, 0], tokenSet))
220
- rText.messageHandler.messages.each do |msg|
221
- # Map the SourceFileInfo of the RichText back to the original
222
- # location in the input file.
223
- sfi = TextParser::SourceFileInfo.new(
224
- sfi.fileName, sfi.lineNo + msg.sourceFileInfo.lineNo - 1, 0)
225
- # Then replay the error message.
226
- @messageHandler.addMessage(msg.type, msg.id, msg.message, sfi,
227
- msg.line)
228
- end
229
- end
230
- rti.sectionNumbers = false
216
+ # The RichText is processed by a separate parser. Messages will not have
217
+ # the proper source file info unless we baseline them with the original
218
+ # source file info.
219
+ mh = MessageHandlerInstance.instance
220
+ mh.baselineSFI = sfi
221
+ rti = rText.generateIntermediateFormat( [ 0, 0, 0 ], tokenSet)
222
+ # Reset the baseline again.
223
+ mh.baselineSFI = nil
224
+ rti.sectionNumbers = false if rti
231
225
  rti
232
226
  end
233
227
 
234
- # This method is a convenience wrapper around Project.new. It checks if
228
+ # This method is a convenience wrapper around Report.new. It checks if
235
229
  # the report name already exists. It also triggers the attribute
236
230
  # inheritance. +name+ is the name of the report, +type+ is the report
237
231
  # type. +sourceFileInfo+ is a SourceFileInfo of the report definition. The
@@ -432,8 +426,12 @@ class TaskJuggler
432
426
  # Determine the title of the column with the ID _colId_. The title may be
433
427
  # from the static set or be from a user defined attribute.
434
428
  def columnTitle(colId)
435
- TableReport.defaultColumnTitle(colId) ||
436
- @project.attributeName(colId)
429
+ if @property.typeSpec == :tracereport
430
+ "<-id->:<-scenario->.#{colId}"
431
+ else
432
+ TableReport.defaultColumnTitle(colId) ||
433
+ @project.attributeName(colId)
434
+ end
437
435
  end
438
436
 
439
437
 
@@ -485,7 +483,11 @@ class TaskJuggler
485
483
  end
486
484
  # The << operator does not set the 'provided' flag. Just do a self
487
485
  # assignment to trigget the flag to get set.
488
- @property[attrId, @scenarioIdx] = @property[attrId, @scenarioIdx]
486
+ begin
487
+ @property[attrId, @scenarioIdx] = @property[attrId, @scenarioIdx]
488
+ rescue AttributeOverwrite
489
+ # Overwrites are ok here.
490
+ end
489
491
  end
490
492
 
491
493
  end
@@ -19,7 +19,7 @@ class TaskJuggler
19
19
  # of the TJP syntax.
20
20
  class ProjectFileScanner < TextParser::Scanner
21
21
 
22
- def initialize(masterFile, messageHandler)
22
+ def initialize(masterFile)
23
23
  tokenPatterns = [
24
24
  # Any white spaces
25
25
  [ nil, /\s+/, :tjp, method('newPos') ],
@@ -150,7 +150,7 @@ class TaskJuggler
150
150
  [ :LITERAL, /./ ]
151
151
  ]
152
152
 
153
- super(masterFile, messageHandler, Log, tokenPatterns, :tjp)
153
+ super(masterFile, Log, tokenPatterns, :tjp)
154
154
  end
155
155
 
156
156
  private
@@ -11,6 +11,8 @@
11
11
  # published by the Free Software Foundation.
12
12
  #
13
13
 
14
+ require 'taskjuggler/MessageHandler'
15
+
14
16
  class TaskJuggler
15
17
 
16
18
  # This class is the base object for all Project properties. A Project property
@@ -27,6 +29,8 @@ class TaskJuggler
27
29
  # attribute like an URL that contains more details about the task.
28
30
  class PropertyTreeNode
29
31
 
32
+ include MessageHandler
33
+
30
34
  attr_reader :propertySet, :id, :subId, :parent, :project, :sequenceNo,
31
35
  :children, :adoptees
32
36
  attr_accessor :name, :sourceFileInfo
@@ -363,11 +367,18 @@ class TaskJuggler
363
367
  end
364
368
 
365
369
  # Return a list with all parent nodes of this node.
366
- def ancestors
370
+ def ancestors(includeStepParents = false)
367
371
  nodes = []
368
- n = self
369
- while n.parent
370
- nodes << (n = n.parent)
372
+ if includeStepParents
373
+ parents.each do |parent|
374
+ nodes << parent
375
+ nodes += parent.ancestors(true)
376
+ end
377
+ else
378
+ n = self
379
+ while n.parent
380
+ nodes << (n = n.parent)
381
+ end
371
382
  end
372
383
  nodes
373
384
  end
@@ -554,16 +565,14 @@ class TaskJuggler
554
565
  def query_alert(query)
555
566
  journal = @project['journal']
556
567
  query.sortable = query.numerical = alert =
557
- journal.alertLevel(query.end, self, query.hideJournalEntry)
568
+ journal.alertLevel(query.end, self, query)
558
569
  alertLevel = @project['alertLevels'][alert]
559
570
  query.string = alertLevel.name
560
571
  rText = "<fcol:#{alertLevel.color}><nowiki>#{alertLevel.name}" +
561
572
  "</nowiki></fcol>"
562
- unless (rti = RichText.new(rText, RTFHandlers.create(@project),
563
- @project.messageHandler).
564
- generateIntermediateFormat)
565
- @project.messageHandler.warning('ptn_journal',
566
- "Syntax error in journal message")
573
+ unless (rti = RichText.new(rText, RTFHandlers.create(@project)).
574
+ generateIntermediateFormat)
575
+ warning('ptn_journal', "Syntax error in journal message")
567
576
  return nil
568
577
  end
569
578
  rti.blockMode = false
@@ -572,15 +581,13 @@ class TaskJuggler
572
581
 
573
582
  def query_alertmessages(query)
574
583
  journalMessages(@project['journal'].alertEntries(query.end, self, 1,
575
- query.start,
576
- query.hideJournalEntry),
584
+ query.start, query),
577
585
  query, true)
578
586
  end
579
587
 
580
588
  def query_alertsummaries(query)
581
589
  journalMessages(@project['journal'].alertEntries(query.end, self, 1,
582
- query.start,
583
- query.hideJournalEntry),
590
+ query.start, query),
584
591
  query, false)
585
592
  end
586
593
 
@@ -600,8 +607,8 @@ class TaskJuggler
600
607
 
601
608
  def query_alerttrend(query)
602
609
  journal = @project['journal']
603
- startAlert = journal.alertLevel(query.start, self, query.hideJournalEntry)
604
- endAlert = journal.alertLevel(query.end, self, query.hideJournalEntry)
610
+ startAlert = journal.alertLevel(query.start, self, query)
611
+ endAlert = journal.alertLevel(query.end, self, query)
605
612
  if startAlert < endAlert
606
613
  query.sortable = 0
607
614
  query.string = 'Up'
@@ -653,19 +660,6 @@ class TaskJuggler
653
660
  @data[scenarioIdx].send(func, *args, &block)
654
661
  end
655
662
 
656
- def error(id, text)
657
- @project.messageHandler.error(id, text, @sourceFileInfo, nil, self, nil)
658
- end
659
-
660
- def warning(id, text)
661
- @project.messageHandler.warning(id, text, @sourceFileInfo, nil, self, nil)
662
- end
663
-
664
- def info(id, text)
665
- @project.messageHandler.info(id, text, @sourceFileInfo, nil, self, nil)
666
- end
667
-
668
-
669
663
  private
670
664
 
671
665
  # Create a blog-style list of all alert messages that match the Query.
@@ -693,11 +687,9 @@ class TaskJuggler
693
687
  end
694
688
  # Now convert the RichText markup String into RichTextIntermediate
695
689
  # format.
696
- unless (rti = RichText.new(rText, RTFHandlers.create(@project),
697
- @project.messageHandler).
698
- generateIntermediateFormat)
699
- @project.messageHandler.warning('ptn_journal',
700
- "Syntax error in journal message")
690
+ unless (rti = RichText.new(rText, RTFHandlers.create(@project)).
691
+ generateIntermediateFormat)
692
+ warning('ptn_journal', "Syntax error in journal message")
701
693
  return nil
702
694
  end
703
695
  # No section numbers, please!
@@ -325,15 +325,19 @@ class TaskJuggler
325
325
  # should not exceed. nil means no limit. Never use quarters since it's
326
326
  # pretty uncommon to use.
327
327
  max = [ 60, 48, nil, 8, 24, 0, nil ]
328
+ stdFormat = RealFormat.new([ '-', '', '', '.',
329
+ @numberFormat.fractionDigits ])
328
330
 
329
331
  i = 0
332
+ fSep = @numberFormat.fractionSeparator
330
333
  factors.each do |factor|
331
334
  scaledValue = value * factor
332
335
  str = @numberFormat.format(scaledValue)
333
- delta[i] = ((scaledValue - str.to_f).abs * 1000).to_i
336
+ stdStr = stdFormat.format(scaledValue)
337
+ delta[i] = (scaledValue - stdStr.to_f).abs
334
338
  # We ignore results that are 0 or exceed the maximum. To ensure that
335
339
  # we have at least one result the unscaled value is always taken.
336
- if (factor != 1.0 && /^[0.]*$/ =~ str) ||
340
+ if (factor != 1.0 && /^[0.]*$/ =~ stdStr) ||
337
341
  (max[i] && scaledValue > max[i])
338
342
  options << nil
339
343
  else
@@ -346,13 +350,12 @@ class TaskJuggler
346
350
  # the default if all values have the same length.
347
351
  shortest = 2
348
352
  delta.length.times do |j|
349
- shortest = j if options[j] && options[j][0, 2] != '0.' &&
350
- delta[j] <= delta[shortest]
353
+ shortest = j if options[j] && delta[j] < delta[shortest]
351
354
  end
352
355
 
353
356
  # Find the shortest option.
354
357
  6.times do |j|
355
- shortest = j if options[j] && options[j][0, 2] != '0.' &&
358
+ shortest = j if options[j] && options[j][0, 2] != '0' + fSep &&
356
359
  options[j].length < options[shortest].length
357
360
  end
358
361
 
@@ -27,6 +27,9 @@ class TaskJuggler
27
27
  # fractionDigits: Number of fractional digits to show. (Fixnum)
28
28
  class RealFormat
29
29
 
30
+ attr_reader :signPrefix, :signSuffix, :thousandsSeparator,
31
+ :fractionSeparator, :fractionDigits
32
+
30
33
  # Create a new RealFormat object and define the formating rules.
31
34
  def initialize(args)
32
35
  iVars = %w( @signPrefix @signSuffix @thousandsSeparator
@@ -85,11 +85,9 @@ class TaskJuggler
85
85
 
86
86
  # Now convert the RichText markup String into RichTextIntermediate
87
87
  # format.
88
- unless (rti = RichText.new(rText, RTFHandlers.create(@project),
89
- @project.messageHandler).
90
- generateIntermediateFormat)
91
- @project.messageHandler.warning(
92
- 'res_dashboard', 'Syntax error in dashboard text')
88
+ unless (rti = RichText.new(rText, RTFHandlers.create(@project)).
89
+ generateIntermediateFormat)
90
+ warning('res_dashboard', 'Syntax error in dashboard text')
93
91
  return nil
94
92
  end
95
93
  # No section numbers, please!
@@ -136,11 +136,18 @@ class TaskJuggler
136
136
  resource.finishScheduling(@scenarioIdx)
137
137
  end
138
138
 
139
- if (parent = @property.parent)
140
- # Add the assigned task to the parent duties list.
139
+ # Add the parent tasks of each task to the duties list.
140
+ @duties.each do |task|
141
+ task.ancestors(true).each do |pTask|
142
+ @duties << pTask unless @duties.include?(pTask)
143
+ end
144
+ end
145
+
146
+ # Add the assigned task to the parent(s) resource duties list.
147
+ @property.parents.each do |pResource|
141
148
  @duties.each do |task|
142
- unless parent['duties', @scenarioIdx].include?(task)
143
- parent['duties', @scenarioIdx] << task
149
+ unless pResource['duties', @scenarioIdx].include?(task)
150
+ pResource['duties', @scenarioIdx] << task
144
151
  end
145
152
  end
146
153
  end
@@ -434,8 +441,11 @@ class TaskJuggler
434
441
 
435
442
 
436
443
  # Returns the work of the resource (and its children) weighted by their
437
- # efficiency.
444
+ # efficiency. If _task_ is provided, only the work for this task and all
445
+ # its sub tasks are being counted.
438
446
  def getEffectiveWork(startIdx, endIdx, task = nil)
447
+ # Make sure we have the real Task and not a proxy.
448
+ task = task.ptn if task
439
449
  # There can't be any effective work if the start is after the end or the
440
450
  # todo list doesn't contain the specified task.
441
451
  return 0.0 if startIdx >= endIdx || (task && !@duties.include?(task))
@@ -632,7 +642,8 @@ class TaskJuggler
632
642
  end
633
643
 
634
644
  # Count the booked slots between the start and end index. If _task_ is not
635
- # nil count only those slots that are assigned to this particular task.
645
+ # nil count only those slots that are assigned to this particular task or
646
+ # any of its sub tasks.
636
647
  def getAllocatedSlots(startIdx, endIdx, task)
637
648
  # If there is no scoreboard, we don't have any allocations.
638
649
  return 0 unless @scoreboard
@@ -641,8 +652,9 @@ class TaskJuggler
641
652
  return 0 if startIdx >= endIdx
642
653
 
643
654
  bookedSlots = 0
655
+ taskList = task ? task.all : []
644
656
  @scoreboard.each(startIdx, endIdx) do |slot|
645
- if (task.nil? && slot.is_a?(Task)) || (task && slot == task)
657
+ if slot.is_a?(Task) && (task.nil? || taskList.include?(slot))
646
658
  bookedSlots += 1
647
659
  end
648
660
  end
@@ -72,7 +72,7 @@ class TaskJuggler
72
72
  #
73
73
  class RichText
74
74
 
75
- attr_reader :inputText, :messageHandler
75
+ attr_reader :inputText
76
76
 
77
77
  # The Parser uses complex to setup data structures that are identical for
78
78
  # all RichText instances. So, we'll share them across the instances.
@@ -83,11 +83,10 @@ class TaskJuggler
83
83
  # case an error occurs, an exception of type TjException will be raised.
84
84
  # _functionHandlers_ is a Hash that maps RichTextFunctionHandler objects
85
85
  # by their function name.
86
- def initialize(text, functionHandlers = [], messageHandler = nil)
86
+ def initialize(text, functionHandlers = [])
87
87
  # Keep a copy of the original text.
88
88
  @inputText = text
89
89
  @functionHandlers = functionHandlers
90
- @messageHandler = messageHandler || MessageHandler.new
91
90
  end
92
91
 
93
92
  # Convert the @inputText into an abstract syntax tree that can then be
@@ -103,11 +102,10 @@ class TaskJuggler
103
102
  # We'll setup the RichTextParser once and share it across all instances.
104
103
  if @@parser
105
104
  # We already have a RichTextParser that we can reuse.
106
- @@parser.reuse(@messageHandler, rti, sectionCounter, tokenSet)
105
+ @@parser.reuse(rti, sectionCounter, tokenSet)
107
106
  else
108
107
  # There is no RichTextParser yet, create one.
109
- @@parser = RichTextParser.new(@messageHandler, rti, sectionCounter,
110
- tokenSet)
108
+ @@parser = RichTextParser.new(rti, sectionCounter, tokenSet)
111
109
  end
112
110
 
113
111
  @@parser.open(@inputText)
@@ -23,7 +23,7 @@ class TaskJuggler
23
23
  class RichTextFunctionExample < RichTextFunctionHandler
24
24
 
25
25
  def initialize
26
- super(nil, 'example')
26
+ super('example')
27
27
  @blockFunction = true
28
28
  end
29
29
 
@@ -11,6 +11,8 @@
11
11
  # published by the Free Software Foundation.
12
12
  #
13
13
 
14
+ require 'taskjuggler/MessageHandler'
15
+
14
16
  class TaskJuggler
15
17
 
16
18
  # This class is the abstract base class for all RichText function handlers.
@@ -24,19 +26,16 @@ class TaskJuggler
24
26
  # second is the argument Array.
25
27
  class RichTextFunctionHandler
26
28
 
29
+ include MessageHandler
30
+
27
31
  attr_reader :function, :blockFunction
28
32
 
29
- def initialize(messageHandler, function, sourceFileInfo = nil)
30
- @messageHandler = messageHandler
33
+ def initialize(function, sourceFileInfo = nil)
31
34
  @function = function
32
35
  @blockFunction = false
33
36
  @sourceFileInfo = sourceFileInfo
34
37
  end
35
38
 
36
- def error(id, text)
37
- @messageHandler.error(id, text, @sourceFileInfo) if @messageHandler
38
- end
39
-
40
39
  end
41
40
 
42
41
  end
@@ -29,9 +29,8 @@ class TaskJuggler
29
29
 
30
30
  # Create the parser and initialize the rule set. _rt_ is the RichText object
31
31
  # the resulting tree of RichTextElement objects should belong to.
32
- def initialize(messageHandler, rti, sectionCounter = [ 0, 0, 0, 0 ],
33
- tokenSet = nil)
34
- super(messageHandler)
32
+ def initialize(rti, sectionCounter = [ 0, 0, 0, 0 ], tokenSet = nil)
33
+ super()
35
34
  @richTextI = rti
36
35
  # These are the tokens that can be returned by the RichTextScanner.
37
36
  @variables = [ :LINEBREAK, :SPACE, :WORD,
@@ -56,12 +55,11 @@ class TaskJuggler
56
55
  @numberListCounter = [ 0, 0, 0, 0 ]
57
56
  end
58
57
 
59
- def reuse(messageHandler, rti, sectionCounter = [ 0, 0, 0, 0],
58
+ def reuse(rti, sectionCounter = [ 0, 0, 0, 0],
60
59
  tokenSet = nil)
61
60
  @blockedVariables = {}
62
61
  @stack = nil
63
62
  @richTextI = rti
64
- @messageHandler = messageHandler
65
63
  @sectionCounter = sectionCounter
66
64
  limitTokenSet(tokenSet)
67
65
  end
@@ -70,7 +68,7 @@ class TaskJuggler
70
68
  def open(text)
71
69
  # Make sure that the last line is properly terminated with a newline.
72
70
  # Multiple newlines at the end are simply ignored.
73
- @scanner = RichTextScanner.new(text + "\n\n", @messageHandler, Log)
71
+ @scanner = RichTextScanner.new(text + "\n\n", Log)
74
72
  @scanner.open(true)
75
73
  end
76
74