taskjuggler 3.4.0 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (530) hide show
  1. data/CHANGELOG +41 -0
  2. data/data/css/tjreport.css +4 -1
  3. data/data/tjp.vim +22 -11
  4. data/examples/ToDo-List/todolist.tjp +1 -1
  5. data/lib/header.tmpl +1 -1
  6. data/lib/taskjuggler/Account.rb +1 -1
  7. data/lib/taskjuggler/AccountCredit.rb +1 -1
  8. data/lib/taskjuggler/AccountScenario.rb +1 -1
  9. data/lib/taskjuggler/AlertLevelDefinitions.rb +1 -1
  10. data/lib/taskjuggler/AlgorithmDiff.rb +1 -1
  11. data/lib/taskjuggler/Allocation.rb +1 -1
  12. data/lib/taskjuggler/AppConfig.rb +1 -1
  13. data/lib/taskjuggler/AttributeBase.rb +11 -1
  14. data/lib/taskjuggler/AttributeDefinition.rb +1 -1
  15. data/lib/taskjuggler/Attributes.rb +3 -3
  16. data/lib/taskjuggler/BatchProcessor.rb +1 -1
  17. data/lib/taskjuggler/Booking.rb +1 -1
  18. data/lib/taskjuggler/Charge.rb +1 -1
  19. data/lib/taskjuggler/ChargeSet.rb +1 -1
  20. data/lib/taskjuggler/DataCache.rb +1 -1
  21. data/lib/taskjuggler/FileList.rb +1 -1
  22. data/lib/taskjuggler/HTMLDocument.rb +2 -2
  23. data/lib/taskjuggler/HTMLElements.rb +1 -1
  24. data/lib/taskjuggler/ICalendar.rb +2 -2
  25. data/lib/taskjuggler/Interval.rb +1 -1
  26. data/lib/taskjuggler/IntervalList.rb +1 -1
  27. data/lib/taskjuggler/Journal.rb +1 -1
  28. data/lib/taskjuggler/KateSyntax.rb +1 -1
  29. data/lib/taskjuggler/KeywordArray.rb +1 -1
  30. data/lib/taskjuggler/KeywordDocumentation.rb +3 -2
  31. data/lib/taskjuggler/LeaveList.rb +1 -1
  32. data/lib/taskjuggler/Limits.rb +1 -1
  33. data/lib/taskjuggler/Log.rb +1 -1
  34. data/lib/taskjuggler/LogicalExpression.rb +1 -1
  35. data/lib/taskjuggler/LogicalFunction.rb +23 -1
  36. data/lib/taskjuggler/LogicalOperation.rb +5 -2
  37. data/lib/taskjuggler/MessageHandler.rb +9 -3
  38. data/lib/taskjuggler/PTNProxy.rb +1 -1
  39. data/lib/taskjuggler/Painter.rb +1 -1
  40. data/lib/taskjuggler/Project.rb +4 -3
  41. data/lib/taskjuggler/ProjectFileParser.rb +15 -4
  42. data/lib/taskjuggler/ProjectFileScanner.rb +1 -1
  43. data/lib/taskjuggler/PropertyList.rb +2 -2
  44. data/lib/taskjuggler/PropertySet.rb +2 -2
  45. data/lib/taskjuggler/PropertyTreeNode.rb +44 -16
  46. data/lib/taskjuggler/Query.rb +23 -10
  47. data/lib/taskjuggler/RealFormat.rb +1 -1
  48. data/lib/taskjuggler/Resource.rb +1 -1
  49. data/lib/taskjuggler/ResourceScenario.rb +6 -1
  50. data/lib/taskjuggler/RichText.rb +1 -1
  51. data/lib/taskjuggler/RichText/Document.rb +1 -1
  52. data/lib/taskjuggler/RichText/Element.rb +1 -1
  53. data/lib/taskjuggler/RichText/FunctionExample.rb +3 -3
  54. data/lib/taskjuggler/RichText/FunctionHandler.rb +1 -1
  55. data/lib/taskjuggler/RichText/Parser.rb +1 -1
  56. data/lib/taskjuggler/RichText/RTFHandlers.rb +1 -1
  57. data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
  58. data/lib/taskjuggler/RichText/RTFQuery.rb +4 -3
  59. data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
  60. data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -1
  61. data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
  62. data/lib/taskjuggler/RichText/Scanner.rb +2 -1
  63. data/lib/taskjuggler/RichText/Snip.rb +1 -1
  64. data/lib/taskjuggler/RichText/SyntaxRules.rb +1 -1
  65. data/lib/taskjuggler/RichText/TOCEntry.rb +1 -1
  66. data/lib/taskjuggler/RichText/TableOfContents.rb +1 -1
  67. data/lib/taskjuggler/RuntimeConfig.rb +1 -1
  68. data/lib/taskjuggler/Scenario.rb +1 -1
  69. data/lib/taskjuggler/ScenarioData.rb +1 -1
  70. data/lib/taskjuggler/Scoreboard.rb +10 -6
  71. data/lib/taskjuggler/SheetHandlerBase.rb +1 -1
  72. data/lib/taskjuggler/SheetReceiver.rb +1 -1
  73. data/lib/taskjuggler/SheetSender.rb +1 -1
  74. data/lib/taskjuggler/Shift.rb +1 -1
  75. data/lib/taskjuggler/ShiftAssignments.rb +1 -1
  76. data/lib/taskjuggler/ShiftScenario.rb +1 -1
  77. data/lib/taskjuggler/SimpleQueryExpander.rb +1 -1
  78. data/lib/taskjuggler/StatusSheetReceiver.rb +1 -1
  79. data/lib/taskjuggler/StatusSheetSender.rb +1 -1
  80. data/lib/taskjuggler/StdIoWrapper.rb +1 -1
  81. data/lib/taskjuggler/SyntaxReference.rb +15 -1
  82. data/lib/taskjuggler/TableColumnDefinition.rb +1 -1
  83. data/lib/taskjuggler/TableColumnSorter.rb +1 -1
  84. data/lib/taskjuggler/Task.rb +1 -1
  85. data/lib/taskjuggler/TaskDependency.rb +1 -1
  86. data/lib/taskjuggler/TaskJuggler.rb +7 -4
  87. data/lib/taskjuggler/TaskScenario.rb +95 -72
  88. data/lib/taskjuggler/TernarySearchTree.rb +1 -1
  89. data/lib/taskjuggler/TextFormatter.rb +1 -1
  90. data/lib/taskjuggler/TextParser.rb +1 -1
  91. data/lib/taskjuggler/TextParser/MacroTable.rb +1 -1
  92. data/lib/taskjuggler/TextParser/Pattern.rb +1 -1
  93. data/lib/taskjuggler/TextParser/Rule.rb +6 -1
  94. data/lib/taskjuggler/TextParser/Scanner.rb +1 -1
  95. data/lib/taskjuggler/TextParser/SourceFileInfo.rb +1 -1
  96. data/lib/taskjuggler/TextParser/StackElement.rb +1 -1
  97. data/lib/taskjuggler/TextParser/State.rb +1 -1
  98. data/lib/taskjuggler/TextParser/TokenDoc.rb +1 -1
  99. data/lib/taskjuggler/TimeSheetReceiver.rb +1 -1
  100. data/lib/taskjuggler/TimeSheetSender.rb +1 -1
  101. data/lib/taskjuggler/TimeSheetSummary.rb +1 -1
  102. data/lib/taskjuggler/TimeSheets.rb +1 -1
  103. data/lib/taskjuggler/Tj3AppBase.rb +3 -2
  104. data/lib/taskjuggler/Tj3Config.rb +3 -3
  105. data/lib/taskjuggler/Tj3SheetAppBase.rb +1 -1
  106. data/lib/taskjuggler/TjException.rb +1 -1
  107. data/lib/taskjuggler/TjTime.rb +17 -12
  108. data/lib/taskjuggler/TjpExample.rb +1 -1
  109. data/lib/taskjuggler/TjpSyntaxRules.rb +378 -303
  110. data/lib/taskjuggler/URLParameter.rb +1 -1
  111. data/lib/taskjuggler/UTF8String.rb +1 -1
  112. data/lib/taskjuggler/UserManual.rb +3 -3
  113. data/lib/taskjuggler/VimSyntax.rb +1 -1
  114. data/lib/taskjuggler/WorkingHours.rb +1 -1
  115. data/lib/taskjuggler/XMLDocument.rb +1 -1
  116. data/lib/taskjuggler/XMLElement.rb +1 -1
  117. data/lib/taskjuggler/apps/Tj3.rb +20 -6
  118. data/lib/taskjuggler/apps/Tj3Client.rb +1 -1
  119. data/lib/taskjuggler/apps/Tj3Daemon.rb +1 -1
  120. data/lib/taskjuggler/apps/Tj3Man.rb +2 -2
  121. data/lib/taskjuggler/apps/Tj3SsReceiver.rb +1 -1
  122. data/lib/taskjuggler/apps/Tj3SsSender.rb +1 -1
  123. data/lib/taskjuggler/apps/Tj3TsReceiver.rb +1 -1
  124. data/lib/taskjuggler/apps/Tj3TsSender.rb +1 -1
  125. data/lib/taskjuggler/apps/Tj3TsSummary.rb +1 -1
  126. data/lib/taskjuggler/apps/Tj3WebD.rb +2 -2
  127. data/lib/taskjuggler/daemon/Daemon.rb +1 -1
  128. data/lib/taskjuggler/daemon/DaemonConnector.rb +1 -1
  129. data/lib/taskjuggler/daemon/ProcessIntercom.rb +1 -1
  130. data/lib/taskjuggler/daemon/ProjectBroker.rb +1 -1
  131. data/lib/taskjuggler/daemon/ProjectServer.rb +1 -1
  132. data/lib/taskjuggler/daemon/ReportServer.rb +1 -1
  133. data/lib/taskjuggler/daemon/ReportServlet.rb +1 -1
  134. data/lib/taskjuggler/daemon/WebServer.rb +1 -1
  135. data/lib/taskjuggler/daemon/WelcomePage.rb +1 -1
  136. data/lib/taskjuggler/deep_copy.rb +1 -1
  137. data/lib/taskjuggler/reports/AccountListRE.rb +1 -1
  138. data/lib/taskjuggler/reports/CSVFile.rb +1 -1
  139. data/lib/taskjuggler/reports/ChartPlotter.rb +1 -1
  140. data/lib/taskjuggler/reports/CollisionDetector.rb +1 -1
  141. data/lib/taskjuggler/reports/ColumnTable.rb +1 -1
  142. data/lib/taskjuggler/reports/ExportRE.rb +1 -1
  143. data/lib/taskjuggler/reports/GanttChart.rb +1 -1
  144. data/lib/taskjuggler/reports/GanttContainer.rb +1 -1
  145. data/lib/taskjuggler/reports/GanttHeader.rb +1 -1
  146. data/lib/taskjuggler/reports/GanttHeaderScaleItem.rb +1 -1
  147. data/lib/taskjuggler/reports/GanttLine.rb +1 -1
  148. data/lib/taskjuggler/reports/GanttLoadStack.rb +1 -1
  149. data/lib/taskjuggler/reports/GanttMilestone.rb +1 -1
  150. data/lib/taskjuggler/reports/GanttRouter.rb +1 -1
  151. data/lib/taskjuggler/reports/GanttTaskBar.rb +1 -1
  152. data/lib/taskjuggler/reports/HTMLGraphics.rb +1 -1
  153. data/lib/taskjuggler/reports/ICalReport.rb +1 -1
  154. data/lib/taskjuggler/reports/MspXmlRE.rb +1 -1
  155. data/lib/taskjuggler/reports/Navigator.rb +1 -1
  156. data/lib/taskjuggler/reports/NikuReport.rb +1 -1
  157. data/lib/taskjuggler/reports/Report.rb +31 -19
  158. data/lib/taskjuggler/reports/ReportBase.rb +1 -1
  159. data/lib/taskjuggler/reports/ReportContext.rb +1 -1
  160. data/lib/taskjuggler/reports/ReportTable.rb +1 -1
  161. data/lib/taskjuggler/reports/ReportTableCell.rb +1 -1
  162. data/lib/taskjuggler/reports/ReportTableColumn.rb +1 -1
  163. data/lib/taskjuggler/reports/ReportTableLegend.rb +1 -1
  164. data/lib/taskjuggler/reports/ReportTableLine.rb +1 -1
  165. data/lib/taskjuggler/reports/ResourceListRE.rb +1 -1
  166. data/lib/taskjuggler/reports/StatusSheetReport.rb +1 -1
  167. data/lib/taskjuggler/reports/TableReport.rb +4 -5
  168. data/lib/taskjuggler/reports/TableReportColumn.rb +1 -1
  169. data/lib/taskjuggler/reports/TagFile.rb +1 -1
  170. data/lib/taskjuggler/reports/TaskListRE.rb +1 -1
  171. data/lib/taskjuggler/reports/TextReport.rb +1 -1
  172. data/lib/taskjuggler/reports/TimeSheetReport.rb +1 -1
  173. data/lib/taskjuggler/reports/TjpExportRE.rb +9 -2
  174. data/lib/taskjuggler/reports/TraceReport.rb +1 -1
  175. data/lib/tj3.rb +1 -1
  176. data/lib/tj3client.rb +1 -1
  177. data/lib/tj3d.rb +1 -1
  178. data/lib/tj3man.rb +1 -1
  179. data/lib/tj3ss_receiver.rb +1 -1
  180. data/lib/tj3ss_sender.rb +1 -1
  181. data/lib/tj3ts_receiver.rb +1 -1
  182. data/lib/tj3ts_sender.rb +1 -1
  183. data/lib/tj3ts_summary.rb +1 -1
  184. data/lib/tj3webd.rb +1 -1
  185. data/manual/How_To_Contribute +5 -6
  186. data/manual/Installation +3 -3
  187. data/manual/Rich_Text_Attributes +8 -3
  188. data/manual/html/Day_To_Day_Juggling.html +3 -3
  189. data/manual/html/Getting_Started.html +3 -3
  190. data/manual/html/How_To_Contribute.html +6 -7
  191. data/manual/html/Installation.html +6 -6
  192. data/manual/html/Intro.html +3 -3
  193. data/manual/html/Reporting_Bugs.html +3 -3
  194. data/manual/html/Rich_Text_Attributes.html +5 -4
  195. data/manual/html/Software.html +3 -3
  196. data/manual/html/TaskJuggler_2x_Migration.html +3 -3
  197. data/manual/html/TaskJuggler_Internals.html +3 -3
  198. data/manual/html/The_TaskJuggler_Syntax.html +3 -3
  199. data/manual/html/Tutorial.html +3 -3
  200. data/manual/html/account.html +3 -3
  201. data/manual/html/account.task.html +3 -3
  202. data/manual/html/accountprefix.html +3 -3
  203. data/manual/html/accountreport.html +5 -5
  204. data/manual/html/accountroot.html +3 -3
  205. data/manual/html/active.html +3 -3
  206. data/manual/html/adopt.task.html +3 -3
  207. data/manual/html/aggregate.html +3 -3
  208. data/manual/html/alert.html +3 -3
  209. data/manual/html/alertlevels.html +3 -3
  210. data/manual/html/allocate.html +3 -3
  211. data/manual/html/alphabet.html +11 -4
  212. data/manual/html/alternative.html +3 -3
  213. data/manual/html/author.html +3 -3
  214. data/manual/html/auxdir.html +7 -9
  215. data/manual/html/auxdir.report.html +69 -0
  216. data/manual/html/balance.html +5 -5
  217. data/manual/html/booking.resource.html +3 -3
  218. data/manual/html/booking.task.html +3 -3
  219. data/manual/html/caption.html +3 -3
  220. data/manual/html/cellcolor.column.html +4 -4
  221. data/manual/html/celltext.column.html +3 -3
  222. data/manual/html/center.html +3 -3
  223. data/manual/html/charge.html +3 -3
  224. data/manual/html/chargeset.html +3 -3
  225. data/manual/html/columnid.html +10 -6
  226. data/manual/html/columns.html +3 -3
  227. data/manual/html/complete.html +3 -3
  228. data/manual/html/copyright.html +3 -3
  229. data/manual/html/credits.html +3 -3
  230. data/manual/html/css/tjreport.css +4 -1
  231. data/manual/html/currency.html +3 -3
  232. data/manual/html/currencyformat.html +3 -3
  233. data/manual/html/dailymax.html +3 -3
  234. data/manual/html/dailymin.html +3 -3
  235. data/manual/html/dailyworkinghours.html +3 -3
  236. data/manual/html/date.extend.html +3 -3
  237. data/manual/html/date.html +4 -3
  238. data/manual/html/definitions.html +3 -3
  239. data/manual/html/depends.html +3 -3
  240. data/manual/html/details.html +3 -3
  241. data/manual/html/disabled.html +3 -3
  242. data/manual/html/duration.html +3 -3
  243. data/manual/html/efficiency.html +3 -3
  244. data/manual/html/effort.html +3 -3
  245. data/manual/html/email.html +3 -3
  246. data/manual/html/enabled.html +3 -3
  247. data/manual/html/end.column.html +3 -3
  248. data/manual/html/end.html +3 -3
  249. data/manual/html/end.limit.html +3 -3
  250. data/manual/html/end.report.html +3 -3
  251. data/manual/html/end.timesheet.html +3 -3
  252. data/manual/html/endcredit.html +3 -3
  253. data/manual/html/epilog.html +3 -3
  254. data/manual/html/export.html +3 -3
  255. data/manual/html/extend.html +58 -13
  256. data/manual/html/fail.html +4 -4
  257. data/manual/html/fdl.html +3 -3
  258. data/manual/html/flags.account.html +3 -3
  259. data/manual/html/flags.html +3 -3
  260. data/manual/html/flags.journalentry.html +3 -3
  261. data/manual/html/flags.report.html +3 -3
  262. data/manual/html/flags.resource.html +3 -3
  263. data/manual/html/flags.statussheet.html +3 -3
  264. data/manual/html/flags.task.html +3 -3
  265. data/manual/html/flags.timesheet.html +3 -3
  266. data/manual/html/fontcolor.column.html +4 -4
  267. data/manual/html/footer.html +3 -3
  268. data/manual/html/formats.export.html +3 -3
  269. data/manual/html/formats.html +3 -3
  270. data/manual/html/functions.html +4 -4
  271. data/manual/html/gapduration.html +3 -3
  272. data/manual/html/gaplength.html +3 -3
  273. data/manual/html/halign.center.html +3 -3
  274. data/manual/html/halign.column.html +4 -4
  275. data/manual/html/halign.left.html +3 -3
  276. data/manual/html/halign.right.html +3 -3
  277. data/manual/html/hasalert.html +3 -3
  278. data/manual/html/header.html +3 -3
  279. data/manual/html/headline.html +3 -3
  280. data/manual/html/height.html +3 -3
  281. data/manual/html/hideaccount.html +5 -4
  282. data/manual/html/hidejournalentry.html +3 -3
  283. data/manual/html/hidereport.html +4 -4
  284. data/manual/html/hideresource.html +5 -4
  285. data/manual/html/hidetask.html +5 -4
  286. data/manual/html/icalreport.html +3 -3
  287. data/manual/html/include.macro.html +3 -3
  288. data/manual/html/include.project.html +3 -3
  289. data/manual/html/include.properties.html +3 -3
  290. data/manual/html/index.html +2 -2
  291. data/manual/html/inherit.extend.html +4 -4
  292. data/manual/html/interval1.html +3 -3
  293. data/manual/html/interval2.html +3 -3
  294. data/manual/html/interval3.html +3 -3
  295. data/manual/html/interval4.html +3 -3
  296. data/manual/html/isactive.html +3 -3
  297. data/manual/html/ischildof.html +3 -3
  298. data/manual/html/isdependencyof.html +3 -3
  299. data/manual/html/isdutyof.html +3 -3
  300. data/manual/html/isfeatureof.html +3 -3
  301. data/manual/html/isleaf.html +3 -3
  302. data/manual/html/ismilestone.html +3 -3
  303. data/manual/html/isongoing.html +3 -3
  304. data/manual/html/isresource.html +3 -3
  305. data/manual/html/isresponsibilityof.html +3 -3
  306. data/manual/html/istask.html +5 -5
  307. data/manual/html/isvalid.html +66 -0
  308. data/manual/html/journalattributes.html +5 -5
  309. data/manual/html/journalentry.html +3 -3
  310. data/manual/html/journalmode.html +3 -3
  311. data/manual/html/leaveallowance.html +3 -3
  312. data/manual/html/leaves.html +3 -3
  313. data/manual/html/left.html +3 -3
  314. data/manual/html/length.html +5 -5
  315. data/manual/html/limits.allocate.html +3 -3
  316. data/manual/html/limits.html +3 -3
  317. data/manual/html/limits.resource.html +3 -3
  318. data/manual/html/limits.task.html +3 -3
  319. data/manual/html/listitem.column.html +3 -3
  320. data/manual/html/listtype.column.html +3 -3
  321. data/manual/html/loadunit.html +3 -3
  322. data/manual/html/logicalexpression.html +14 -4
  323. data/manual/html/logicalflagexpression.html +3 -3
  324. data/manual/html/macro.html +3 -3
  325. data/manual/html/managers.html +3 -3
  326. data/manual/html/mandatory.html +3 -3
  327. data/manual/html/maxend.html +3 -3
  328. data/manual/html/maximum.html +3 -3
  329. data/manual/html/maxstart.html +3 -3
  330. data/manual/html/milestone.html +3 -3
  331. data/manual/html/minend.html +3 -3
  332. data/manual/html/minimum.html +3 -3
  333. data/manual/html/minstart.html +3 -3
  334. data/manual/html/monthlymax.html +3 -3
  335. data/manual/html/monthlymin.html +3 -3
  336. data/manual/html/navbar.html +10 -2
  337. data/manual/html/navigator.html +3 -3
  338. data/manual/html/newtask.html +4 -4
  339. data/manual/html/nikureport.html +3 -3
  340. data/manual/html/note.task.html +3 -3
  341. data/manual/html/now.html +5 -5
  342. data/manual/html/number.extend.html +77 -0
  343. data/manual/html/numberformat.html +5 -5
  344. data/manual/html/onend.html +3 -3
  345. data/manual/html/onstart.html +3 -3
  346. data/manual/html/opennodes.html +5 -5
  347. data/manual/html/outputdir.html +67 -0
  348. data/manual/html/overtime.booking.html +5 -5
  349. data/manual/html/period.column.html +3 -3
  350. data/manual/html/period.limit.html +3 -3
  351. data/manual/html/period.report.html +3 -3
  352. data/manual/html/period.task.html +3 -3
  353. data/manual/html/persistent.html +3 -3
  354. data/manual/html/precedes.html +3 -3
  355. data/manual/html/priority.html +3 -3
  356. data/manual/html/priority.timesheet.html +3 -3
  357. data/manual/html/project.html +4 -4
  358. data/manual/html/projectid.html +3 -3
  359. data/manual/html/projectid.task.html +3 -3
  360. data/manual/html/projectids.html +3 -3
  361. data/manual/html/projection.html +3 -3
  362. data/manual/html/prolog.html +3 -3
  363. data/manual/html/properties.html +10 -4
  364. data/manual/html/purge.html +3 -3
  365. data/manual/html/rate.html +3 -3
  366. data/manual/html/rate.resource.html +3 -3
  367. data/manual/html/rawhtmlhead.html +3 -3
  368. data/manual/html/reference.extend.html +3 -3
  369. data/manual/html/remaining.html +3 -3
  370. data/manual/html/replace.html +3 -3
  371. data/manual/html/reportprefix.html +3 -3
  372. data/manual/html/resource.html +3 -3
  373. data/manual/html/resourceattributes.html +3 -3
  374. data/manual/html/resourceprefix.html +3 -3
  375. data/manual/html/resourcereport.html +5 -5
  376. data/manual/html/resourceroot.html +3 -3
  377. data/manual/html/resources.limit.html +3 -3
  378. data/manual/html/responsible.html +3 -3
  379. data/manual/html/richtext.extend.html +3 -3
  380. data/manual/html/right.html +3 -3
  381. data/manual/html/rollupaccount.html +4 -4
  382. data/manual/html/rollupresource.html +4 -4
  383. data/manual/html/rolluptask.html +4 -4
  384. data/manual/html/scale.column.html +3 -3
  385. data/manual/html/scenario.html +3 -3
  386. data/manual/html/scenario.ical.html +3 -3
  387. data/manual/html/scenarios.export.html +3 -3
  388. data/manual/html/scenarios.html +3 -3
  389. data/manual/html/scenariospecific.extend.html +4 -4
  390. data/manual/html/scheduled.html +3 -3
  391. data/manual/html/scheduling.html +3 -3
  392. data/manual/html/select.html +3 -3
  393. data/manual/html/selfcontained.html +3 -3
  394. data/manual/html/shift.allocate.html +3 -3
  395. data/manual/html/shift.html +4 -4
  396. data/manual/html/shift.resource.html +3 -3
  397. data/manual/html/shift.task.html +3 -3
  398. data/manual/html/shift.timesheet.html +3 -3
  399. data/manual/html/shifts.allocate.html +3 -3
  400. data/manual/html/shifts.resource.html +3 -3
  401. data/manual/html/shifts.task.html +3 -3
  402. data/manual/html/shorttimeformat.html +3 -3
  403. data/manual/html/sloppy.booking.html +3 -3
  404. data/manual/html/sloppy.projection.html +3 -3
  405. data/manual/html/sortaccounts.html +3 -3
  406. data/manual/html/sortjournalentries.html +3 -3
  407. data/manual/html/sortresources.html +3 -3
  408. data/manual/html/sorttasks.html +3 -3
  409. data/manual/html/start.column.html +3 -3
  410. data/manual/html/start.html +3 -3
  411. data/manual/html/start.limit.html +3 -3
  412. data/manual/html/start.report.html +3 -3
  413. data/manual/html/startcredit.html +3 -3
  414. data/manual/html/status.statussheet.html +3 -3
  415. data/manual/html/status.timesheet.html +3 -3
  416. data/manual/html/statussheet.html +3 -3
  417. data/manual/html/statussheetreport.html +3 -3
  418. data/manual/html/strict.projection.html +3 -3
  419. data/manual/html/summary.html +3 -3
  420. data/manual/html/supplement.html +3 -3
  421. data/manual/html/supplement.resource.html +3 -3
  422. data/manual/html/supplement.task.html +3 -3
  423. data/manual/html/tagfile.html +3 -3
  424. data/manual/html/task.html +3 -3
  425. data/manual/html/task.statussheet.html +3 -3
  426. data/manual/html/task.timesheet.html +3 -3
  427. data/manual/html/taskattributes.html +3 -3
  428. data/manual/html/taskprefix.html +3 -3
  429. data/manual/html/taskreport.html +5 -5
  430. data/manual/html/taskroot.export.html +3 -3
  431. data/manual/html/taskroot.html +3 -3
  432. data/manual/html/text.extend.html +3 -3
  433. data/manual/html/textreport.html +5 -5
  434. data/manual/html/timeformat.html +3 -3
  435. data/manual/html/timeformat1.html +3 -3
  436. data/manual/html/timeformat2.html +3 -3
  437. data/manual/html/timeoff.nikureport.html +3 -3
  438. data/manual/html/timesheet.html +3 -3
  439. data/manual/html/timesheetreport.html +3 -3
  440. data/manual/html/timezone.export.html +3 -3
  441. data/manual/html/timezone.html +3 -3
  442. data/manual/html/timezone.report.html +3 -3
  443. data/manual/html/timezone.shift.html +3 -3
  444. data/manual/html/timingresolution.html +3 -3
  445. data/manual/html/title.column.html +3 -3
  446. data/manual/html/title.html +3 -3
  447. data/manual/html/toc.html +276 -248
  448. data/manual/html/tooltip.column.html +4 -4
  449. data/manual/html/tracereport.html +5 -5
  450. data/manual/html/trackingscenario.html +3 -3
  451. data/manual/html/treelevel.html +3 -3
  452. data/manual/html/vacation.html +3 -3
  453. data/manual/html/vacation.resource.html +3 -3
  454. data/manual/html/vacation.shift.html +3 -3
  455. data/manual/html/warn.html +4 -4
  456. data/manual/html/weeklymax.html +3 -3
  457. data/manual/html/weeklymin.html +3 -3
  458. data/manual/html/weekstartsmonday.html +3 -3
  459. data/manual/html/weekstartssunday.html +3 -3
  460. data/manual/html/width.column.html +4 -4
  461. data/manual/html/width.html +3 -3
  462. data/manual/html/work.html +3 -3
  463. data/manual/html/workinghours.project.html +3 -3
  464. data/manual/html/workinghours.resource.html +3 -3
  465. data/manual/html/workinghours.shift.html +3 -3
  466. data/manual/html/yearlyworkingdays.html +3 -3
  467. data/spec/Color_spec.rb +2 -2
  468. data/spec/ICalendar_spec.rb +1 -1
  469. data/spec/IntervalList_spec.rb +1 -1
  470. data/spec/ProjectBroker_spec.rb +1 -1
  471. data/spec/StatusSheets_spec.rb +1 -1
  472. data/spec/TableColumnSorter_spec.rb +2 -2
  473. data/spec/TernarySearchTree_spec.rb +1 -1
  474. data/spec/TimeSheets_spec.rb +1 -1
  475. data/spec/Tj3Daemon_spec.rb +1 -1
  476. data/spec/Tj3_spec.rb +1 -1
  477. data/spec/TraceReport_spec.rb +2 -2
  478. data/spec/support/DaemonControl.rb +1 -1
  479. data/spec/support/spec_helper.rb +1 -1
  480. data/tasks/gem.rake +7 -1
  481. data/tasks/rdoc.rake +5 -1
  482. data/test/MessageChecker.rb +1 -1
  483. data/test/ReferenceGenerator.rb +1 -1
  484. data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +14 -14
  485. data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +1 -1
  486. data/test/TestSuite/Export-Reports/refs/CustomAttributes.tjp +62 -10
  487. data/test/TestSuite/Export-Reports/refs/Shift.tjp +1 -1
  488. data/test/TestSuite/Scheduler/Correct/DateAndDep.tjp +25 -0
  489. data/test/TestSuite/Scheduler/Correct/hammock.tjp +27 -0
  490. data/test/TestSuite/Scheduler/Errors/container_milestone.tjp +13 -0
  491. data/test/TestSuite/Scheduler/Errors/{weak_end_dep.tjp → impossible_end_dep.tjp} +2 -2
  492. data/test/TestSuite/Scheduler/Errors/{weak_start_dep.tjp → impossible_start_dep.tjp} +2 -2
  493. data/test/TestSuite/Scheduler/Errors/sched_runaway.tjp +20 -0
  494. data/test/TestSuite/Scheduler/Errors/{task_pred_before_gl.tjp → task_pred_before_1.tjp} +1 -1
  495. data/test/TestSuite/Scheduler/Errors/{task_pred_before_gd.tjp → task_pred_before_2.tjp} +1 -1
  496. data/test/TestSuite/Scheduler/Errors/{task_succ_after_gl.tjp → task_succ_after_1.tjp} +1 -1
  497. data/test/TestSuite/Scheduler/Errors/{task_succ_after_gd.tjp → task_succ_after_2.tjp} +1 -1
  498. data/test/TestSuite/Syntax/Correct/CustomAttributes.tjp +53 -9
  499. data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +11 -0
  500. data/test/TjpGen.rb +1 -1
  501. data/test/all.rb +1 -1
  502. data/test/test_AlgorithmDiff.rb +1 -1
  503. data/test/test_BatchProcessor.rb +1 -1
  504. data/test/test_CSV-Reports.rb +1 -1
  505. data/test/test_CSVFile.rb +1 -1
  506. data/test/test_CollisionDetector.rb +1 -1
  507. data/test/test_Export-Reports.rb +1 -1
  508. data/test/test_Journal.rb +1 -1
  509. data/test/test_Limits.rb +1 -1
  510. data/test/test_LogicalExpression.rb +1 -1
  511. data/test/test_MacroTable.rb +1 -1
  512. data/test/test_Project.rb +1 -1
  513. data/test/test_ProjectFileScanner.rb +1 -1
  514. data/test/test_PropertySet.rb +1 -1
  515. data/test/test_Query.rb +1 -1
  516. data/test/test_RealFormat.rb +1 -1
  517. data/test/test_ReportGenerator.rb +1 -1
  518. data/test/test_RichText.rb +1 -1
  519. data/test/test_Scheduler.rb +1 -1
  520. data/test/test_ShiftAssignments.rb +1 -1
  521. data/test/test_SimpleQueryExpander.rb +1 -1
  522. data/test/test_Syntax.rb +1 -1
  523. data/test/test_TextFormatter.rb +1 -1
  524. data/test/test_TjTime.rb +1 -1
  525. data/test/test_TjpExample.rb +1 -1
  526. data/test/test_URLParameter.rb +1 -1
  527. data/test/test_UTF8String.rb +1 -1
  528. data/test/test_WorkingHours.rb +1 -1
  529. data/test/test_deep_copy.rb +1 -1
  530. metadata +26 -14
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = Rule.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -53,6 +53,11 @@ class TaskJuggler::TextParser
53
53
  @patterns << pattern
54
54
  end
55
55
 
56
+ def include?(token)
57
+ @patterns.each { |p| return true if p[0][1] == token }
58
+ false
59
+ end
60
+
56
61
  # Mark the rule as an optional element of the syntax.
57
62
  def setOptional
58
63
  @optional = true
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = Scanner.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = SourceFileInfo.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = StackElement.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = State.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TokenDoc.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TimeSheetReceiver.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TimeSheetSender.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TimeSheetSummary.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TimeSheets.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = Tj3AppBase.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -11,7 +11,6 @@
11
11
  # published by the Free Software Foundation.
12
12
  #
13
13
 
14
- require 'rubygems'
15
14
  require 'optparse'
16
15
  require 'term/ansicolor'
17
16
  require 'taskjuggler/Tj3Config'
@@ -163,6 +162,8 @@ EOT
163
162
  "#{'*' * 79}\nYou have triggered a bug in " +
164
163
  "#{AppConfig.softwareName} version #{AppConfig.version}!\n" +
165
164
  "Please see the user manual on how to get this bug fixed!\n" +
165
+ "http://www.taskjuggler.org/tj3/manual/Reporting_Bugs.html#" +
166
+ "Reporting_Bugs_and_Feature_Requests\n" +
166
167
  "#{'*' * 79}\n")
167
168
  end
168
169
  end
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = Tj3Config.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -14,11 +14,11 @@
14
14
  require 'taskjuggler/UTF8String'
15
15
  require 'taskjuggler/AppConfig'
16
16
 
17
- AppConfig.version = '3.4.0'
17
+ AppConfig.version = '3.5.0'
18
18
  AppConfig.packageName = 'taskjuggler'
19
19
  AppConfig.softwareName = 'TaskJuggler'
20
20
  AppConfig.packageInfo = 'A Project Management Software'
21
- AppConfig.copyright = [ (2006..2012).to_a ]
21
+ AppConfig.copyright = [ (2006..2013).to_a ]
22
22
  AppConfig.authors = [ 'Chris Schlaeger <chris@linux.com>' ]
23
23
  AppConfig.contact = 'http://www.taskjuggler.org'
24
24
  AppConfig.license = <<'EOT'
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = Tj3SheetAppBase.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TjException.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TjTime.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -21,7 +21,7 @@ class TaskJuggler
21
21
  # time zones.
22
22
  class TjTime
23
23
 
24
- attr_reader :time, :timeZone
24
+ attr_reader :time
25
25
 
26
26
  # The number of days per month. Leap years are taken care of separately.
27
27
  MON_MAX = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
@@ -40,17 +40,13 @@ class TaskJuggler
40
40
  # is a Time object it's assumed to be in local time. If it's a string, it
41
41
  # is parsed as a date. Or else it is interpreted as seconds after Epoch.
42
42
  def initialize(t = nil)
43
- @timeZone = @@tz
44
-
45
43
  case t
46
44
  when nil
47
45
  @time = Time.now
48
46
  when Time
49
47
  @time = t
50
- @timeZone = nil
51
48
  when TjTime
52
49
  @time = t.time
53
- @timeZone = nil
54
50
  when String
55
51
  parse(t)
56
52
  when Array
@@ -367,16 +363,18 @@ class TaskJuggler
367
363
 
368
364
  # This function is just a wrapper around Time.strftime(). In case @time is
369
365
  # nil, it returns 'unkown'.
370
- def to_s(format = nil)
366
+ def to_s(format = nil, tz = nil)
371
367
  return 'unknown' if @time.nil?
368
+
369
+ t = tz == 'UTC' ? gmtime : localtime
372
370
  if format.nil?
373
371
  fmt = '%Y-%m-%d-%H:%M' + (@time.sec == 0 ? '' : ':%S') + '-%z'
374
372
  else
375
373
  # Handle TJ specific extensions to the strftime format.
376
- fmt = format.sub(/%Q/, "#{((localtime.mon - 1) / 3) + 1}")
374
+ fmt = format.sub(/%Q/, "#{((t.mon - 1) / 3) + 1}")
377
375
  end
378
376
  # Always report values in local timezone
379
- localtime.strftime(fmt)
377
+ t.strftime(fmt)
380
378
  end
381
379
 
382
380
  # Return the seconds since Epoch.
@@ -515,7 +513,6 @@ class TaskJuggler
515
513
  "(0 - 59) but is #{tzMinute}"
516
514
  end
517
515
  @time += sign * (tzHour * 3600 + tzMinute * 60)
518
- @timeZone = 'UTC'
519
516
  else
520
517
  @time = Time.mktime(year, month, day, hour, minute, second)
521
518
  end
@@ -550,9 +547,17 @@ class TaskJuggler
550
547
  end
551
548
  end
552
549
 
553
- def localtime
554
- return @time if @timeZone == @@tz
550
+ def gmtime
551
+ if @time.utc?
552
+ # @time is already in the right zone (UTC)
553
+ @time
554
+ else
555
+ # To convert a Time object from local time to UTC.
556
+ @time.dup.gmtime
557
+ end
558
+ end
555
559
 
560
+ def localtime
556
561
  if @time.utc?
557
562
  if @@tz == 'UTC'
558
563
  # @time is already in the right zone (UTC)
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TjpExample.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = TjpSyntaxRules.rb -- The TaskJuggler III Project Management Software
5
5
  #
6
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7
7
  # by Chris Schlaeger <chris@linux.com>
8
8
  #
9
9
  # This program is free software; you can redistribute it and/or modify
@@ -130,24 +130,24 @@ EOT
130
130
 
131
131
  def rule_accountReportHeader
132
132
  pattern(%w( _accountreport !optionalID !reportName ), lambda {
133
- newReport(@val[1], @val[2], :accountreport, @sourceFileInfo[0])
134
-
135
- unless @property.modified?('columns')
136
- # Set the default columns for this report.
137
- %w( bsi name monthly ).each do |col|
138
- @property.get('columns') <<
139
- TableColumnDefinition.new(col, columnTitle(col))
133
+ newReport(@val[1], @val[2], :accountreport, @sourceFileInfo[0]) do
134
+ unless @property.modified?('columns')
135
+ # Set the default columns for this report.
136
+ %w( bsi name monthly ).each do |col|
137
+ @property.get('columns') <<
138
+ TableColumnDefinition.new(col, columnTitle(col))
139
+ end
140
+ end
141
+ # Show all accounts, sorted by tree, seqno-up.
142
+ unless @property.modified?('hideAccount')
143
+ @property.set('hideAccount',
144
+ LogicalExpression.new(LogicalOperation.new(0)))
145
+ end
146
+ unless @property.modified?('sortAccounts')
147
+ @property.set('sortAccounts',
148
+ [ [ 'tree', true, -1 ],
149
+ [ 'seqno', true, -1 ] ])
140
150
  end
141
- end
142
- # Show all accounts, sorted by tree, seqno-up.
143
- unless @property.modified?('hideAccount')
144
- @property.set('hideAccount',
145
- LogicalExpression.new(LogicalOperation.new(0)))
146
- end
147
- unless @property.modified?('sortAccounts')
148
- @property.set('sortAccounts',
149
- [ [ 'tree', true, -1 ],
150
- [ 'seqno', true, -1 ] ])
151
151
  end
152
152
  })
153
153
  end
@@ -164,11 +164,7 @@ EOT
164
164
  example('AccountReport')
165
165
 
166
166
  pattern(%w( _credits !accountCredits ), lambda {
167
- begin
168
- @property['credits', @scenarioIdx] += @val[1]
169
- rescue AttributeOverwrite
170
- # Adding multiple credits for an account is a pretty common idiom.
171
- end
167
+ @property['credits', @scenarioIdx] += @val[1]
172
168
  })
173
169
  doc('credits', <<'EOT'
174
170
  Book the specified amounts to the account at the specified date. The
@@ -232,13 +228,7 @@ EOT
232
228
  def rule_allocate
233
229
  pattern(%w( _allocate !allocations ), lambda {
234
230
  checkContainer('allocate')
235
- # Don't use << operator here so the 'provided' flag gets set properly.
236
- begin
237
- @property['allocate', @scenarioIdx] =
238
- @property['allocate', @scenarioIdx] + @val[1]
239
- rescue AttributeOverwrite
240
- # Adding multiple allocates for a task is a pretty common idiom.
241
- end
231
+ @property['allocate', @scenarioIdx] += @val[1]
242
232
  })
243
233
  doc('allocate', <<'EOT'
244
234
  Specify which resources should be allocated to the task. The
@@ -745,9 +735,9 @@ EOT
745
735
  })
746
736
  doc('cellcolor.column', <<'EOT'
747
737
  Specifies an alternative background color for the cells of this column. The
748
- logical expression specifies for which cells the color should be used. If
749
- multiple cellcolor patterns are provided for a column, the first
750
- matching one is used for each cell.
738
+ [[logicalexpression|logical expression]] specifies for which cells the color
739
+ should be used. If multiple cellcolor patterns are provided for a column, the
740
+ first matching one is used for each cell.
751
741
  EOT
752
742
  )
753
743
 
@@ -769,9 +759,9 @@ EOT
769
759
  })
770
760
  doc('fontcolor.column', <<'EOT'
771
761
  Specifies an alternative font color for the cells of this column. The
772
- logical expression specifies for which cells the color should be used. If
773
- multiple fontcolor patterns are provided for a column, the first
774
- matching one is used for each cell.
762
+ [[logicalexpression|logical expression]] specifies for which cells the color
763
+ should be used. If multiple fontcolor patterns are provided for a column, the
764
+ first matching one is used for each cell.
775
765
  EOT
776
766
  )
777
767
 
@@ -780,10 +770,10 @@ EOT
780
770
  CellSettingPattern.new(@val[2], @val[1]))
781
771
  })
782
772
  doc('halign.column', <<'EOT'
783
- Specifies the horizontal alignment of the cell content. The logical expression
784
- specifies for which cells the alignment setting should be used. If multiple
785
- halign patterns are provided for a column, the first matching one is used for
786
- each cell.
773
+ Specifies the horizontal alignment of the cell content. The
774
+ [[logicalexpression|logical expression]] specifies for which cells the alignment
775
+ setting should be used. If multiple halign patterns are provided for a column,
776
+ the first matching one is used for each cell.
787
777
  EOT
788
778
  )
789
779
 
@@ -876,9 +866,10 @@ EOT
876
866
  doc('tooltip.column', <<'EOT'
877
867
  Specifies an alternative content for the tooltip. This will replace the
878
868
  original content of the tooltip that would be available for columns with text
879
- that does not fit the column with. The logical expression specifies for which
880
- cells the text should be used. If multiple tooltip patterns are provided for a
881
- column, the first matching one is taken for each cell.
869
+ that does not fit the column with. The [[logicalexpression|logical expression]]
870
+ specifies for which cells the text should be used. If multiple tooltip
871
+ patterns are provided for a column, the first matching one is taken for each
872
+ cell.
882
873
  EOT
883
874
  )
884
875
  arg(2, 'text', <<'EOT'
@@ -891,11 +882,12 @@ EOT
891
882
  @column.width = @val[1]
892
883
  })
893
884
  doc('width.column', <<'EOT'
894
- Specifies the width of the column in screen pixels. If the content of the
895
- column does not fit into this width, it will be cut off. In some cases a
885
+ Specifies the maximum width of the column in screen pixels. If the content of
886
+ the column does not fit into this width, it will be cut off. In some cases a
896
887
  scrollbar is added or a tooltip window with the complete content is shown when
897
888
  the mouse is moved over the column. The latter is only supported in
898
- interactive output formats.
889
+ interactive output formats. The resulting column width may be smaller if the
890
+ column has a fixed width (e. g. the chart column).
899
891
  EOT
900
892
  )
901
893
  end
@@ -954,6 +946,9 @@ This is result in a date 2 weeks earlier than the current (or specified) date.
954
946
  See [[duration]] for a complete list of supported time intervals. Don't forget
955
947
  to put at least one space character after the date to prevent TaskJuggler from
956
948
  interpreting the interval as an hour.
949
+
950
+ Date attributes may be invalid in some cases. This needs special care in
951
+ [[logicalexpression|logical expressions]].
957
952
  EOT
958
953
  )
959
954
  end
@@ -1209,31 +1204,33 @@ EOT
1209
1204
 
1210
1205
  def rule_exportHeader
1211
1206
  pattern(%w( _export !optionalID $STRING ), lambda {
1212
- newReport(@val[1], @val[2], :export, @sourceFileInfo[0])
1213
- unless @property.modified?('formats')
1214
- @property.set('formats', [ :tjp ])
1215
- end
1207
+ newReport(@val[1], @val[2], :export, @sourceFileInfo[0]) do
1208
+ unless @property.modified?('formats')
1209
+ @property.set('formats', [ :tjp ])
1210
+ end
1216
1211
 
1217
- # By default, we export all scenarios.
1218
- unless @property.modified?('scenarios')
1219
- scenarios = Array.new(@project.scenarios.items) { |i| i }
1220
- scenarios.delete_if { |sc| !@project.scenario(sc).get('active') }
1221
- @property.set('scenarios', scenarios)
1222
- end
1223
- # Show all tasks, sorted by seqno-up.
1224
- unless @property.modified?('hideTask')
1225
- @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
1226
- end
1227
- unless @property.modified?('sortTasks')
1228
- @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
1229
- end
1230
- # Show all resources, sorted by seqno-up.
1231
- unless @property.modified?('hideResource')
1232
- @property.set('hideResource',
1233
- LogicalExpression.new(LogicalOperation.new(0)))
1234
- end
1235
- unless @property.modified?('sortResources')
1236
- @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
1212
+ # By default, we export all scenarios.
1213
+ unless @property.modified?('scenarios')
1214
+ scenarios = Array.new(@project.scenarios.items) { |i| i }
1215
+ scenarios.delete_if { |sc| !@project.scenario(sc).get('active') }
1216
+ @property.set('scenarios', scenarios)
1217
+ end
1218
+ # Show all tasks, sorted by seqno-up.
1219
+ unless @property.modified?('hideTask')
1220
+ @property.set('hideTask',
1221
+ LogicalExpression.new(LogicalOperation.new(0)))
1222
+ end
1223
+ unless @property.modified?('sortTasks')
1224
+ @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
1225
+ end
1226
+ # Show all resources, sorted by seqno-up.
1227
+ unless @property.modified?('hideResource')
1228
+ @property.set('hideResource',
1229
+ LogicalExpression.new(LogicalOperation.new(0)))
1230
+ end
1231
+ unless @property.modified?('sortResources')
1232
+ @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
1233
+ end
1237
1234
  end
1238
1235
  })
1239
1236
  arg(2, 'file name', <<'EOT'
@@ -1263,6 +1260,28 @@ EOT
1263
1260
  })
1264
1261
  doc('date.extend', <<'EOT'
1265
1262
  Extend the property with a new attribute of type date.
1263
+ EOT
1264
+ )
1265
+ arg(2, 'name', 'The name of the new attribute. It is used as header ' +
1266
+ 'in report columns and the like.')
1267
+
1268
+ pattern(%w( _number !extendId $STRING !extendOptionsBody ), lambda {
1269
+ # Extend the propertySet definition and parser rules
1270
+ if extendPropertySetDefinition(FloatAttribute, nil)
1271
+ @ruleToExtendWithScenario.addPattern(TextParser::Pattern.new(
1272
+ [ '_' + @val[1], '!number' ], lambda {
1273
+ @property[@val[0], @scenarioIdx] = @val[1]
1274
+ }))
1275
+ else
1276
+ @ruleToExtend.addPattern(TextParser::Pattern.new(
1277
+ [ '_' + @val[1], '!number' ], lambda {
1278
+ @property.set(@val[0], @val[1])
1279
+ }))
1280
+ end
1281
+ })
1282
+ doc('number.extend', <<'EOT'
1283
+ Extend the property with a new attribute of type number. Possible values for
1284
+ this attribute could be integer or floating point numbers.
1266
1285
  EOT
1267
1286
  )
1268
1287
  arg(2, 'name', 'The name of the new attribute. It is used as header ' +
@@ -1405,10 +1424,10 @@ EOT
1405
1424
  end
1406
1425
  })
1407
1426
  doc('fail', <<'EOT'
1408
- The fail attribute adds a logical expression to the property. The condition
1409
- described by the logical expression is checked after the scheduling and an
1410
- error is raised if the condition evaluates to true. This attribute is
1411
- primarily intended for testing purposes.
1427
+ The fail attribute adds a [[logicalexpression|logical expression]] to the
1428
+ property. The condition described by the logical expression is checked after
1429
+ the scheduling and an error is raised if the condition evaluates to true. This
1430
+ attribute is primarily intended for testing purposes.
1412
1431
  EOT
1413
1432
  )
1414
1433
  end
@@ -1522,11 +1541,7 @@ EOT
1522
1541
  @val[1].each do |flag|
1523
1542
  next if @property['flags', @scenarioIdx].include?(flag)
1524
1543
 
1525
- # We allow multiple instances of flag definitions.
1526
- begin
1527
- @property['flags', @scenarioIdx] += [ flag ]
1528
- rescue AttributeOverwrite
1529
- end
1544
+ @property['flags', @scenarioIdx] += [ flag ]
1530
1545
  end
1531
1546
  })
1532
1547
  end
@@ -1684,6 +1699,10 @@ EOT
1684
1699
  pattern(['_istask', '_(', '_)' ])
1685
1700
  doc('istask', 'The result is true if the property is a task.')
1686
1701
 
1702
+ pattern(%w( _isvalid _( $ID _) ))
1703
+ doc('isvalid', 'Returns false if argument is not an assigned or ' +
1704
+ 'properly computed value.')
1705
+
1687
1706
  pattern(%w( _treelevel _( _) ))
1688
1707
  doc('treelevel', <<'EOT'
1689
1708
  Returns the nesting level of a property in the property tree.
@@ -1729,8 +1748,9 @@ EOT
1729
1748
  @property.set('hideAccount', @val[1])
1730
1749
  })
1731
1750
  doc('hideaccount', <<'EOT'
1732
- Do not include accounts that match the specified logical expression. If the
1733
- report is sorted in ''''tree'''' mode (default) then enclosing accounts are
1751
+ Do not include accounts that match the specified [[logicalexpression|logical
1752
+ expression]]. If the report is sorted in ''''tree'''' mode (default) then
1753
+ enclosing accounts are
1734
1754
  listed even if the expression matches the account.
1735
1755
  EOT
1736
1756
  )
@@ -1752,9 +1772,9 @@ EOT
1752
1772
  @property.set('hideResource', @val[1])
1753
1773
  })
1754
1774
  doc('hideresource', <<'EOT'
1755
- Do not include resources that match the specified logical expression. If the
1756
- report is sorted in ''''tree'''' mode (default) then enclosing resources are
1757
- listed even if the expression matches the resource.
1775
+ Do not include resources that match the specified [[logicalexpression|logical
1776
+ expression]]. If the report is sorted in ''''tree'''' mode (default) then
1777
+ enclosing resources are listed even if the expression matches the resource.
1758
1778
  EOT
1759
1779
  )
1760
1780
  also(%w( sortresources ))
@@ -1765,9 +1785,9 @@ EOT
1765
1785
  @property.set('hideTask', @val[1])
1766
1786
  })
1767
1787
  doc('hidetask', <<'EOT'
1768
- Do not include tasks that match the specified logical expression. If the
1769
- report is sorted in ''''tree'''' mode (default) then enclosing tasks are
1770
- listed even if the expression matches the task.
1788
+ Do not include tasks that match the specified [[logicalexpression|logical
1789
+ expression]]. If the report is sorted in ''''tree'''' mode (default) then
1790
+ enclosing tasks are listed even if the expression matches the task.
1771
1791
  EOT
1772
1792
  )
1773
1793
  also(%w( sorttasks ))
@@ -1820,23 +1840,24 @@ EOT
1820
1840
 
1821
1841
  def rule_iCalReportHeader
1822
1842
  pattern(%w( _icalreport !optionalID $STRING ), lambda {
1823
- newReport(@val[1], @val[2], :iCal, @sourceFileInfo[0])
1824
- @property.set('formats', [ :iCal ])
1825
-
1826
- # By default, we export only the first scenario.
1827
- unless @project.scenario(0).get('active')
1828
- @property.set('scenarios', [ 0 ])
1829
- end
1830
- # Show all tasks, sorted by seqno-up.
1831
- @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
1832
- @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
1833
- # Show all resources, sorted by seqno-up.
1834
- @property.set('hideResource',
1835
- LogicalExpression.new(LogicalOperation.new(0)))
1836
- @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
1837
- # Show all journal entries.
1838
- @property.set('hideJournalEntry',
1839
- LogicalExpression.new(LogicalOperation.new(0)))
1843
+ newReport(@val[1], @val[2], :iCal, @sourceFileInfo[0]) do
1844
+ @property.set('formats', [ :iCal ])
1845
+
1846
+ # By default, we export only the first scenario.
1847
+ unless @project.scenario(0).get('active')
1848
+ @property.set('scenarios', [ 0 ])
1849
+ end
1850
+ # Show all tasks, sorted by seqno-up.
1851
+ @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
1852
+ @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
1853
+ # Show all resources, sorted by seqno-up.
1854
+ @property.set('hideResource',
1855
+ LogicalExpression.new(LogicalOperation.new(0)))
1856
+ @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
1857
+ # Show all journal entries.
1858
+ @property.set('hideJournalEntry',
1859
+ LogicalExpression.new(LogicalOperation.new(0)))
1860
+ end
1840
1861
  })
1841
1862
  arg(1, 'file name', <<'EOT'
1842
1863
  The name of the report file to generate without an extension. Use . to use
@@ -2609,17 +2630,27 @@ in the report.
2609
2630
  Operands can be previously declared flags, built-in [[functions]], property
2610
2631
  attributes (specified as scenario.attribute) or another logical expression.
2611
2632
  When you combine logical operations to a more complex expression, the
2612
- operators are evaluated from left to right. '''a | b & c''' is identical to
2613
- '''(a | b) & c'''. It's highly recommended that you always use brackets to
2633
+ operators are evaluated from left to right. ''''a | b & c'''' is identical to
2634
+ ''''(a | b) & c''''. It's highly recommended that you always use brackets to
2614
2635
  control the evaluation sequence. Currently, TaskJuggler does not support the
2615
2636
  concept of operator precedence or right-left associativity. This may change in
2616
2637
  the future.
2617
2638
 
2618
2639
  An operand can also be just a number. 0 evaluates to false, all other numbers
2619
- to true. The logical expression can also be the special constants ''''@all'''' or ''''@none''''. The first always evaluates to true, the latter to false.
2640
+ to true. The logical expression can also be the special constants ''''@all''''
2641
+ or ''''@none''''. The first always evaluates to true, the latter to false.
2642
+
2643
+ Date attributes needs special attention. Attributes like [[maxend]] can
2644
+ be undefined. To use such an attribute in a comparison, you need to test for
2645
+ the validity first. E. g. to compare the end date of the ''''plan''''
2646
+ scenario with the ''''maxend'''' value use ''''isvalid(plan.maxend) &
2647
+ (plan.end > plan.maxend)''''. The ''''&'''' and ''''|'''' operators are lazy.
2648
+ If the result is already known after evaluation the first operand, the second
2649
+ operand will not be evaluated any more.
2620
2650
  EOT
2621
2651
  )
2622
2652
  also(%w( functions ))
2653
+ example('LogicalExpression', '1')
2623
2654
  end
2624
2655
 
2625
2656
  def rule_macro
@@ -2751,7 +2782,7 @@ EOT
2751
2782
  })
2752
2783
  doc('hidereport', <<'EOT'
2753
2784
  This attribute can be used to exclude the reports that match the specified
2754
- expression from the navigation bar.
2785
+ [[logicalexpression|logical expression]] from the navigation bar.
2755
2786
  EOT
2756
2787
  )
2757
2788
  end
@@ -2810,8 +2841,9 @@ EOF
2810
2841
 
2811
2842
  def rule_nikuReportHeader
2812
2843
  pattern(%w( _nikureport !optionalID $STRING ), lambda {
2813
- newReport(@val[1], @val[2], :niku, @sourceFileInfo[0])
2814
- @property.set('numberFormat', RealFormat.new(['-', '', '', '.', 2]))
2844
+ newReport(@val[1], @val[2], :niku, @sourceFileInfo[0]) do
2845
+ @property.set('numberFormat', RealFormat.new(['-', '', '', '.', 2]))
2846
+ end
2815
2847
  })
2816
2848
  arg(1, 'file name', <<'EOT'
2817
2849
  The name of the time sheet report file to generate. It must end with a .tji
@@ -3229,6 +3261,24 @@ EOT
3229
3261
  @project['numberFormat'] = @val[0]
3230
3262
  })
3231
3263
 
3264
+ pattern(%w( _outputdir $STRING ), lambda {
3265
+ # Directory name must be terminated by a slash.
3266
+ if @val[1].empty?
3267
+ error('outdir_empty', 'Output directory may not be empty.')
3268
+ end
3269
+ if !File.directory?(@val[1])
3270
+ error('outdir_missing',
3271
+ "Output directory '#{@val[1]}' does not exist or is not " +
3272
+ "a directory!")
3273
+ end
3274
+ @project.outputDir = @val[1] + (@val[1][-1] == ?/ ? '' : '/')
3275
+ })
3276
+ doc('outputdir',
3277
+ 'Specifies the directory into which the reports should be generated. ' +
3278
+ 'This will not affect reports whos name start with a slash. This ' +
3279
+ 'setting can be overwritten by the command line option.')
3280
+ arg(1, 'directory', 'Path to an existing directory')
3281
+
3232
3282
  pattern(%w( !scenario ))
3233
3283
  pattern(%w( _shorttimeformat $STRING ), lambda {
3234
3284
  @project['shortTimeFormat'] = @val[1]
@@ -3465,6 +3515,24 @@ EOT
3465
3515
 
3466
3516
  pattern(%w( !account ))
3467
3517
 
3518
+ pattern(%w( _auxdir $STRING ), lambda {
3519
+ auxdir = @val[1]
3520
+ # Ensure that the directory always ends with a '/'.
3521
+ auxdir += '/' unless auxdir[-1] == ?/
3522
+ @project['auxdir'] = auxdir
3523
+ })
3524
+ level(:beta)
3525
+ doc('auxdir', <<'EOT'
3526
+ Specifies an alternative directory for the auxiliary report files such as CSS,
3527
+ JavaScript and icon files. This setting will affect all subsequent report
3528
+ definitions unless it gets overridden. If this attribute is not set, the
3529
+ directory and its contents will be generated automatically. If this attribute
3530
+ is provided, the user has to ensure that the directory exists and is filled
3531
+ with the proper data. The specified path can be absolute or relative to the
3532
+ generated report file.
3533
+ EOT
3534
+ )
3535
+
3468
3536
  pattern(%w( _copyright $STRING ), lambda {
3469
3537
  @project['copyright'] = @val[1]
3470
3538
  })
@@ -3730,7 +3798,11 @@ EOT
3730
3798
  )
3731
3799
 
3732
3800
  singlePattern('_balance')
3733
- descr('The account balance at the beginning of the reported period.')
3801
+ descr(<<'EOT'
3802
+ The account balance at the beginning of the reported period. This is the
3803
+ balance before any transactions of the reported period have been credited.
3804
+ EOT
3805
+ )
3734
3806
 
3735
3807
  singlePattern('_bsi')
3736
3808
  descr('The hierarchical or work breakdown structure index (i. e. 1.2.3)')
@@ -4093,6 +4165,12 @@ will also include the targets of the child tasks. Targets may not have any
4093
4165
  follower tasks.
4094
4166
 
4095
4167
  The list can be customized by the [[listitem.column|listitem]] attribute.
4168
+ EOT
4169
+ )
4170
+
4171
+ singlePattern('_turnover')
4172
+ descr(<<'EOT'
4173
+ The financial turnover of an account during the reporting interval.
4096
4174
  EOT
4097
4175
  )
4098
4176
 
@@ -4146,12 +4224,12 @@ EOT
4146
4224
  @property.set('auxdir', auxdir)
4147
4225
  })
4148
4226
  level(:beta)
4149
- doc('auxdir', <<'EOT'
4227
+ doc('auxdir.report', <<'EOT'
4150
4228
  Specifies an alternative directory for the auxiliary report files such as CSS,
4151
- JavaScript and icon files. If this attribute is not set, the directoy will be
4152
- generated automatically. If an alternative is provided, the user has to ensure
4229
+ JavaScript and icon files. If this attribute is not set, the directory will be
4230
+ generated automatically. If this attribute is provided, the user has to ensure
4153
4231
  that the directory exists and is filled with the proper data. The specified
4154
- path and be absolute or relative to the generated report file.
4232
+ path can be absolute or relative to the generated report file.
4155
4233
  EOT
4156
4234
  )
4157
4235
 
@@ -4706,34 +4784,34 @@ EOT
4706
4784
 
4707
4785
  def rule_resourceReportHeader
4708
4786
  pattern(%w( _resourcereport !optionalID !reportName ), lambda {
4709
- newReport(@val[1], @val[2], :resourcereport, @sourceFileInfo[0])
4710
-
4711
- unless @property.modified?('columns')
4712
- # Set the default columns for this report.
4713
- %w( no name ).each do |col|
4714
- @property.get('columns') <<
4715
- TableColumnDefinition.new(col, columnTitle(col))
4787
+ newReport(@val[1], @val[2], :resourcereport, @sourceFileInfo[0]) do
4788
+ unless @property.modified?('columns')
4789
+ # Set the default columns for this report.
4790
+ %w( no name ).each do |col|
4791
+ @property.get('columns') <<
4792
+ TableColumnDefinition.new(col, columnTitle(col))
4793
+ end
4794
+ end
4795
+ # Show all resources, sorted by tree and id-up.
4796
+ unless @property.modified?('hideResource')
4797
+ @property.set('hideResource',
4798
+ LogicalExpression.new(LogicalOperation.new(0)))
4799
+ end
4800
+ unless @property.modified?('sortResources')
4801
+ @property.set('sortResources', [ [ 'tree', true, -1 ],
4802
+ [ 'id', true, -1 ] ])
4803
+ end
4804
+ # Hide all resources, but set sorting to tree, start-up, seqno-up.
4805
+ unless @property.modified?('hideTask')
4806
+ @property.set('hideTask',
4807
+ LogicalExpression.new(LogicalOperation.new(1)))
4808
+ end
4809
+ unless @property.modified?('sortTasks')
4810
+ @property.set('sortTasks',
4811
+ [ [ 'tree', true, -1 ],
4812
+ [ 'start', true, 0 ],
4813
+ [ 'seqno', true, -1 ] ])
4716
4814
  end
4717
- end
4718
- # Show all resources, sorted by tree and id-up.
4719
- unless @property.modified?('hideResource')
4720
- @property.set('hideResource',
4721
- LogicalExpression.new(LogicalOperation.new(0)))
4722
- end
4723
- unless @property.modified?('sortResources')
4724
- @property.set('sortResources', [ [ 'tree', true, -1 ],
4725
- [ 'id', true, -1 ] ])
4726
- end
4727
- # Hide all resources, but set sorting to tree, start-up, seqno-up.
4728
- unless @property.modified?('hideTask')
4729
- @property.set('hideTask',
4730
- LogicalExpression.new(LogicalOperation.new(1)))
4731
- end
4732
- unless @property.modified?('sortTasks')
4733
- @property.set('sortTasks',
4734
- [ [ 'tree', true, -1 ],
4735
- [ 'start', true, 0 ],
4736
- [ 'seqno', true, -1 ] ])
4737
4815
  end
4738
4816
  })
4739
4817
  end
@@ -4801,10 +4879,7 @@ EOT
4801
4879
  pattern(%w( !leaveAllowances ))
4802
4880
 
4803
4881
  pattern(%w( !leaves ), lambda {
4804
- begin
4805
- @property['leaves', @scenarioIdx] += @val[0]
4806
- rescue AttributeOverwrite
4807
- end
4882
+ @property['leaves', @scenarioIdx] += @val[0]
4808
4883
  })
4809
4884
 
4810
4885
  pattern(%w( !limits ), lambda {
@@ -4884,11 +4959,8 @@ EOT
4884
4959
 
4885
4960
  pattern(%w( _vacation !vacationName !intervals ), lambda {
4886
4961
  @val[2].each do |interval|
4887
- begin
4888
- # We map the old 'vacation' attribute to public holidays.
4889
- @property['leaves', @scenarioIdx] += [ Leave.new(:holiday, interval) ]
4890
- rescue AttributeOverwrite
4891
- end
4962
+ # We map the old 'vacation' attribute to public holidays.
4963
+ @property['leaves', @scenarioIdx] += [ Leave.new(:holiday, interval) ]
4892
4964
  end
4893
4965
  })
4894
4966
  doc('vacation.resource', <<'EOT'
@@ -4922,8 +4994,8 @@ EOT
4922
4994
  @property.set('rollupAccount', @val[1])
4923
4995
  })
4924
4996
  doc('rollupaccount', <<'EOT'
4925
- Do not show sub-accounts of accounts that match the specified logical
4926
- expression.
4997
+ Do not show sub-accounts of accounts that match the specified
4998
+ [[logicalexpression|logical expression]].
4927
4999
  EOT
4928
5000
  )
4929
5001
  end
@@ -4933,8 +5005,8 @@ EOT
4933
5005
  @property.set('rollupResource', @val[1])
4934
5006
  })
4935
5007
  doc('rollupresource', <<'EOT'
4936
- Do not show sub-resources of resources that match the specified logical
4937
- expression.
5008
+ Do not show sub-resources of resources that match the specified
5009
+ [[logicalexpression|logical expression]].
4938
5010
  EOT
4939
5011
  )
4940
5012
  example('RollupResource')
@@ -4945,7 +5017,8 @@ EOT
4945
5017
  @property.set('rollupTask', @val[1])
4946
5018
  })
4947
5019
  doc('rolluptask', <<'EOT'
4948
- Do not show sub-tasks of tasks that match the specified logical expression.
5020
+ Do not show sub-tasks of tasks that match the specified
5021
+ [[logicalexpression|logical expression]].
4949
5022
  EOT
4950
5023
  )
4951
5024
  end
@@ -5053,6 +5126,10 @@ EOT
5053
5126
  end
5054
5127
  @property = Scenario.new(@project, @val[1], @val[2], @property)
5055
5128
  @property.inheritAttributes
5129
+
5130
+ if @project.scenarios.length > 1
5131
+ MessageHandlerInstance.instance.hideScenario = false
5132
+ end
5056
5133
  })
5057
5134
  arg(1, 'id', 'The ID of the scenario')
5058
5135
  arg(2, 'name', 'The name of the scenario')
@@ -5103,8 +5180,9 @@ EOT
5103
5180
  })
5104
5181
  doc('shift', <<'EOT'
5105
5182
  A shift combines several workhours related settings in a reusable entity.
5106
- Besides the weekly working hours it can also hold information such as
5107
- leaves and a time zone.
5183
+ Besides the weekly working hours it can also hold information such as leaves
5184
+ and a time zone. It lets you create a work time calendar that can be used to
5185
+ limit the working time for resources or tasks.
5108
5186
 
5109
5187
  Shifts have a global name space. All IDs must be unique within the shifts of
5110
5188
  the project.
@@ -5182,10 +5260,7 @@ EOT
5182
5260
 
5183
5261
  def rule_shiftScenarioAttributes
5184
5262
  pattern(%w( !leaves ), lambda {
5185
- begin
5186
- @property['leaves', @scenarioIdx] += @val[0]
5187
- rescue AttributeOverwrite
5188
- end
5263
+ @property['leaves', @scenarioIdx] += @val[0]
5189
5264
  })
5190
5265
 
5191
5266
  pattern(%w( _replace ), lambda {
@@ -5224,11 +5299,8 @@ EOT
5224
5299
 
5225
5300
  pattern(%w( _vacation !vacationName !intervalsOptional ), lambda {
5226
5301
  @val[2].each do |interval|
5227
- begin
5228
- # We map the old 'vacation' attribute to public holidays.
5229
- @property['leaves', @scenarioIdx] += [ Leave.new(:holiday, interval) ]
5230
- rescue AttributeOverwrite
5231
- end
5302
+ # We map the old 'vacation' attribute to public holidays.
5303
+ @property['leaves', @scenarioIdx] += [ Leave.new(:holiday, interval) ]
5232
5304
  end
5233
5305
  })
5234
5306
  doc('vacation.shift', <<'EOT'
@@ -5377,22 +5449,23 @@ EOT
5377
5449
  end
5378
5450
  def rule_ssReportHeader
5379
5451
  pattern(%w( _statussheetreport !optionalID $STRING ), lambda {
5380
- newReport(@val[1], @val[2], :statusSheet, @sourceFileInfo[0])
5381
- @property.set('formats', [ :tjp ])
5452
+ newReport(@val[1], @val[2], :statusSheet, @sourceFileInfo[0]) do
5453
+ @property.set('formats', [ :tjp ])
5382
5454
 
5383
- unless (@project['trackingScenarioIdx'])
5384
- error('ss_no_tracking_scenario',
5385
- 'You must have a tracking scenario defined to use status sheets.')
5386
- end
5387
- # Show all tasks, sorted by id-up.
5388
- @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
5389
- @property.set('sortTasks', [ [ 'id', true, -1 ] ])
5390
- # Show all resources, sorted by seqno-up.
5391
- @property.set('hideResource',
5392
- LogicalExpression.new(LogicalOperation.new(0)))
5393
- @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
5394
- @property.set('loadUnit', :hours)
5395
- @property.set('definitions', [])
5455
+ unless (@project['trackingScenarioIdx'])
5456
+ error('ss_no_tracking_scenario',
5457
+ 'You must have a tracking scenario defined to use status sheets.')
5458
+ end
5459
+ # Show all tasks, sorted by id-up.
5460
+ @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
5461
+ @property.set('sortTasks', [ [ 'id', true, -1 ] ])
5462
+ # Show all resources, sorted by seqno-up.
5463
+ @property.set('hideResource',
5464
+ LogicalExpression.new(LogicalOperation.new(0)))
5465
+ @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
5466
+ @property.set('loadUnit', :hours)
5467
+ @property.set('definitions', [])
5468
+ end
5396
5469
  })
5397
5470
  arg(2, 'file name', <<'EOT'
5398
5471
  The name of the status sheet report file to generate. It must end with a .tji
@@ -5681,16 +5754,17 @@ EOT
5681
5754
 
5682
5755
  def rule_tagfileHeader
5683
5756
  pattern(%w( _tagfile !optionalID $STRING ), lambda {
5684
- newReport(@val[1], @val[2], :tagfile, @sourceFileInfo[0])
5685
- @property.set('formats', [ :ctags ])
5757
+ newReport(@val[1], @val[2], :tagfile, @sourceFileInfo[0]) do
5758
+ @property.set('formats', [ :ctags ])
5686
5759
 
5687
- # Include all tasks.
5688
- @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
5689
- @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
5690
- # Include all resources.
5691
- @property.set('hideResource',
5692
- LogicalExpression.new(LogicalOperation.new(0)))
5693
- @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
5760
+ # Include all tasks.
5761
+ @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
5762
+ @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
5763
+ # Include all resources.
5764
+ @property.set('hideResource',
5765
+ LogicalExpression.new(LogicalOperation.new(0)))
5766
+ @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
5767
+ end
5694
5768
  })
5695
5769
  arg(2, 'file name', <<'EOT'
5696
5770
  The name of the tagfile to generate. Use ''''tags'''' if you want vim and
@@ -6017,33 +6091,33 @@ EOT
6017
6091
 
6018
6092
  def rule_taskReportHeader
6019
6093
  pattern(%w( _taskreport !optionalID !reportName ), lambda {
6020
- newReport(@val[1], @val[2], :taskreport, @sourceFileInfo[0])
6021
-
6022
- unless @property.modified?('columns')
6023
- # Set the default columns for this report.
6024
- %w( bsi name start end effort chart ).each do |col|
6025
- @property.get('columns') <<
6026
- TableColumnDefinition.new(col, columnTitle(col))
6094
+ newReport(@val[1], @val[2], :taskreport, @sourceFileInfo[0]) do
6095
+ unless @property.modified?('columns')
6096
+ # Set the default columns for this report.
6097
+ %w( bsi name start end effort chart ).each do |col|
6098
+ @property.get('columns') <<
6099
+ TableColumnDefinition.new(col, columnTitle(col))
6100
+ end
6101
+ end
6102
+ # Show all tasks, sorted by tree, start-up, seqno-up.
6103
+ unless @property.modified?('hideTask')
6104
+ @property.set('hideTask',
6105
+ LogicalExpression.new(LogicalOperation.new(0)))
6106
+ end
6107
+ unless @property.modified?('sortTasks')
6108
+ @property.set('sortTasks',
6109
+ [ [ 'tree', true, -1 ],
6110
+ [ 'start', true, 0 ],
6111
+ [ 'seqno', true, -1 ] ])
6112
+ end
6113
+ # Show no resources, but set sorting to id-up.
6114
+ unless @property.modified?('hideResource')
6115
+ @property.set('hideResource',
6116
+ LogicalExpression.new(LogicalOperation.new(1)))
6117
+ end
6118
+ unless @property.modified?('sortResources')
6119
+ @property.set('sortResources', [ [ 'id', true, -1 ] ])
6027
6120
  end
6028
- end
6029
- # Show all tasks, sorted by tree, start-up, seqno-up.
6030
- unless @property.modified?('hideTask')
6031
- @property.set('hideTask',
6032
- LogicalExpression.new(LogicalOperation.new(0)))
6033
- end
6034
- unless @property.modified?('sortTasks')
6035
- @property.set('sortTasks',
6036
- [ [ 'tree', true, -1 ],
6037
- [ 'start', true, 0 ],
6038
- [ 'seqno', true, -1 ] ])
6039
- end
6040
- # Show no resources, but set sorting to id-up.
6041
- unless @property.modified?('hideResource')
6042
- @property.set('hideResource',
6043
- LogicalExpression.new(LogicalOperation.new(1)))
6044
- end
6045
- unless @property.modified?('sortResources')
6046
- @property.set('sortResources', [ [ 'id', true, -1 ] ])
6047
6121
  end
6048
6122
  })
6049
6123
  end
@@ -6114,12 +6188,8 @@ EOT
6114
6188
  mode = :perDiem
6115
6189
  amount = @val[1] / 7.0
6116
6190
  end
6117
- # Multiple 'charge' attributes are allowed.
6118
- begin
6119
- @property['charge', @scenarioIdx] +=
6120
- [ Charge.new(amount, mode, @property, @scenarioIdx) ]
6121
- rescue AttributeOverwrite
6122
- end
6191
+ @property['charge', @scenarioIdx] +=
6192
+ [ Charge.new(amount, mode, @property, @scenarioIdx) ]
6123
6193
  })
6124
6194
  doc('charge', <<'EOT'
6125
6195
  Specify a one-time or per-period charge to a certain account. The charge can
@@ -6156,9 +6226,8 @@ EOT
6156
6226
 
6157
6227
  pattern(%w( _depends !taskDepList ), lambda {
6158
6228
  checkContainer('depends')
6229
+ @property['depends', @scenarioIdx] += @val[1]
6159
6230
  begin
6160
- @property['depends', @scenarioIdx] =
6161
- @property['depends', @scenarioIdx] + @val[1]
6162
6231
  @property['forward', @scenarioIdx] = true
6163
6232
  rescue AttributeOverwrite
6164
6233
  end
@@ -6263,9 +6332,9 @@ EOT
6263
6332
  setDurationAttribute('length', @val[1])
6264
6333
  })
6265
6334
  doc('length', <<'EOT'
6266
- Specifies the global working time to be used for this task. The value is
6267
- specified in working time, not calendar time. 7d means 7 working days, or 7
6268
- times 8 hours (assuming default settings), not one week.
6335
+ Specifies the duration of this task as working time, not calendar time. 7d
6336
+ means 7 working days, or 7 times 8 hours (assuming default settings), not one
6337
+ week.
6269
6338
 
6270
6339
  A task with a length specification may have resource allocations. Resources
6271
6340
  are allocated when they are available. There is no guarantee that the task
@@ -6274,12 +6343,14 @@ on the duration of the task. A time slot where none of the specified resources
6274
6343
  is available is still considered working time, if there is no global vacation
6275
6344
  and global working hours are defined accordingly.
6276
6345
 
6277
- For the length calculation, only the global working hours and the global
6278
- leaves matter. If a resource has additinal working hours defined, it's
6279
- quite possible that a task with a length of 5d will have an allocated effort
6280
- larger than 40 hours. Resource working hours only have an impact on whether an
6281
- allocation is made or not for a particular time slot. They don't effect the
6282
- resulting duration of the task.
6346
+ For the length calculation, the global working hours and the global leaves
6347
+ matter unless the task has [[shifts.task|shifts]] assigned. In the latter case
6348
+ the working hours and leaves of the shift apply for the specified period to
6349
+ determine if a slot is working time or not. If a resource has additinal
6350
+ working hours defined, it's quite possible that a task with a length of 5d
6351
+ will have an allocated effort larger than 40 hours. Resource working hours
6352
+ only have an impact on whether an allocation is made or not for a particular
6353
+ time slot. They don't effect the resulting duration of the task.
6283
6354
 
6284
6355
  Tasks may not have subtasks if this attribute is used. Setting this attribute
6285
6356
  will reset the [[duration]], [[effort]] and [[milestone]] attributes.
@@ -6368,8 +6439,8 @@ EOT
6368
6439
 
6369
6440
  pattern(%w( _precedes !taskPredList ), lambda {
6370
6441
  checkContainer('precedes')
6371
- begin
6372
6442
  @property['precedes', @scenarioIdx] += @val[1]
6443
+ begin
6373
6444
  @property['forward', @scenarioIdx] = false
6374
6445
  rescue AttributeOverwrite
6375
6446
  end
@@ -6814,10 +6885,13 @@ EOT
6814
6885
  @timeSheetRecord = nil
6815
6886
  })
6816
6887
  doc('newtask', <<'EOT'
6817
- The keyword can be used add a new task to the project. If the task ID requires
6818
- further parent task that don't exist yet, these tasks will be created as well.
6819
- If the task exists already, an error is generated. The new task can be used
6820
- immediately to report progress and status against it.
6888
+ The keyword can be used to request a new task to the project. If the task ID
6889
+ requires further parent task that don't exist yet, these tasks will be
6890
+ requested as well. If the task exists already, an error will be generated. The
6891
+ newly requested task can be used immediately to report progress and status
6892
+ against it. These tasks will not automatically be added to the project plan.
6893
+ The project manager has to manually create them after reviewing the request
6894
+ during the time sheet reviews.
6821
6895
  EOT
6822
6896
  )
6823
6897
  example('TimeSheet1', '3')
@@ -6979,51 +7053,51 @@ EOT
6979
7053
 
6980
7054
  def rule_traceReportHeader
6981
7055
  pattern(%w( _tracereport !optionalID !reportName ), lambda {
6982
- newReport(@val[1], @val[2], :tracereport, @sourceFileInfo[0])
6983
-
6984
- # The top-level always inherits the global timeFormat setting. This is
6985
- # not desireable in this case, so we ignore this.
6986
- if (@property.level == 0 && !@property.provided('timeFormat')) ||
6987
- (@property.level > 0 && !@property.modified?('timeFormat'))
6988
- # CSV readers such of Libre-/OpenOffice can't deal with time zones. We
6989
- # probably also don't need seconds.
6990
- @property.set('timeFormat', '%Y-%m-%d-%H:%M')
6991
- end
6992
- unless @property.modified?('columns')
6993
- # Set the default columns for this report.
6994
- %w( end ).each do |col|
6995
- @property.get('columns') <<
6996
- TableColumnDefinition.new(col, columnTitle(col))
7056
+ newReport(@val[1], @val[2], :tracereport, @sourceFileInfo[0]) do
7057
+ # The top-level always inherits the global timeFormat setting. This is
7058
+ # not desireable in this case, so we ignore this.
7059
+ if (@property.level == 0 && !@property.provided('timeFormat')) ||
7060
+ (@property.level > 0 && !@property.modified?('timeFormat'))
7061
+ # CSV readers such of Libre-/OpenOffice can't deal with time zones. We
7062
+ # probably also don't need seconds.
7063
+ @property.set('timeFormat', '%Y-%m-%d-%H:%M')
7064
+ end
7065
+ unless @property.modified?('columns')
7066
+ # Set the default columns for this report.
7067
+ %w( end ).each do |col|
7068
+ @property.get('columns') <<
7069
+ TableColumnDefinition.new(col, columnTitle(col))
7070
+ end
7071
+ end
7072
+ # Hide all accounts.
7073
+ unless @property.modified?('hideAccount')
7074
+ @property.set('hideAccount',
7075
+ LogicalExpression.new(LogicalOperation.new(1)))
7076
+ end
7077
+ unless @property.modified?('sortAccounts')
7078
+ @property.set('sortAccounts',
7079
+ [ [ 'tree', true, -1 ],
7080
+ [ 'seqno', true, -1 ] ])
7081
+ end
7082
+ # Show all tasks, sorted by tree, start-up, seqno-up.
7083
+ unless @property.modified?('hideTask')
7084
+ @property.set('hideTask',
7085
+ LogicalExpression.new(LogicalOperation.new(0)))
7086
+ end
7087
+ unless @property.modified?('sortTasks')
7088
+ @property.set('sortTasks',
7089
+ [ [ 'tree', true, -1 ],
7090
+ [ 'start', true, 0 ],
7091
+ [ 'seqno', true, -1 ] ])
7092
+ end
7093
+ # Show no resources, but set sorting to id-up.
7094
+ unless @property.modified?('hideResource')
7095
+ @property.set('hideResource',
7096
+ LogicalExpression.new(LogicalOperation.new(1)))
7097
+ end
7098
+ unless @property.modified?('sortResources')
7099
+ @property.set('sortResources', [ [ 'id', true, -1 ] ])
6997
7100
  end
6998
- end
6999
- # Hide all accounts.
7000
- unless @property.modified?('hideAccount')
7001
- @property.set('hideAccount',
7002
- LogicalExpression.new(LogicalOperation.new(1)))
7003
- end
7004
- unless @property.modified?('sortAccounts')
7005
- @property.set('sortAccounts',
7006
- [ [ 'tree', true, -1 ],
7007
- [ 'seqno', true, -1 ] ])
7008
- end
7009
- # Show all tasks, sorted by tree, start-up, seqno-up.
7010
- unless @property.modified?('hideTask')
7011
- @property.set('hideTask',
7012
- LogicalExpression.new(LogicalOperation.new(0)))
7013
- end
7014
- unless @property.modified?('sortTasks')
7015
- @property.set('sortTasks',
7016
- [ [ 'tree', true, -1 ],
7017
- [ 'start', true, 0 ],
7018
- [ 'seqno', true, -1 ] ])
7019
- end
7020
- # Show no resources, but set sorting to id-up.
7021
- unless @property.modified?('hideResource')
7022
- @property.set('hideResource',
7023
- LogicalExpression.new(LogicalOperation.new(1)))
7024
- end
7025
- unless @property.modified?('sortResources')
7026
- @property.set('sortResources', [ [ 'id', true, -1 ] ])
7027
7101
  end
7028
7102
  })
7029
7103
  end
@@ -7038,23 +7112,24 @@ EOT
7038
7112
  end
7039
7113
  def rule_tsReportHeader
7040
7114
  pattern(%w( _timesheetreport !optionalID $STRING ), lambda {
7041
- newReport(@val[1], @val[2], :timeSheet, @sourceFileInfo[0])
7042
- @property.set('formats', [ :tjp ])
7115
+ newReport(@val[1], @val[2], :timeSheet, @sourceFileInfo[0]) do
7116
+ @property.set('formats', [ :tjp ])
7043
7117
 
7044
- unless (scenarioIdx = @project['trackingScenarioIdx'])
7045
- error('ts_no_tracking_scenario',
7046
- 'You must have a tracking scenario defined to use time sheets.')
7047
- end
7048
- @property.set('scenarios', [ scenarioIdx ])
7049
- # Show all tasks, sorted by seqno-up.
7050
- @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
7051
- @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
7052
- # Show all resources, sorted by seqno-up.
7053
- @property.set('hideResource',
7054
- LogicalExpression.new(LogicalOperation.new(0)))
7055
- @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
7056
- @property.set('loadUnit', :hours)
7057
- @property.set('definitions', [])
7118
+ unless (scenarioIdx = @project['trackingScenarioIdx'])
7119
+ error('ts_no_tracking_scenario',
7120
+ 'You must have a tracking scenario defined to use time sheets.')
7121
+ end
7122
+ @property.set('scenarios', [ scenarioIdx ])
7123
+ # Show all tasks, sorted by seqno-up.
7124
+ @property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
7125
+ @property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
7126
+ # Show all resources, sorted by seqno-up.
7127
+ @property.set('hideResource',
7128
+ LogicalExpression.new(LogicalOperation.new(0)))
7129
+ @property.set('sortResources', [ [ 'seqno', true, -1 ] ])
7130
+ @property.set('loadUnit', :hours)
7131
+ @property.set('definitions', [])
7132
+ end
7058
7133
  })
7059
7134
  arg(2, 'file name', <<'EOT'
7060
7135
  The name of the time sheet report file to generate. It must end with a .tji
@@ -7354,10 +7429,10 @@ EOT
7354
7429
  end
7355
7430
  })
7356
7431
  doc('warn', <<'EOT'
7357
- The warn attribute adds a logical expression to the property. The condition
7358
- described by the logical expression is checked after the scheduling and an
7359
- warning is generated if the condition evaluates to true. This attribute is
7360
- primarily intended for testing purposes.
7432
+ The warn attribute adds a [[logicalexpression|logical expression]] to the
7433
+ property. The condition described by the logical expression is checked after
7434
+ the scheduling and an warning is generated if the condition evaluates to true.
7435
+ This attribute is primarily intended for testing purposes.
7361
7436
  EOT
7362
7437
  )
7363
7438
  end