taskjuggler 0.0.6 → 0.0.7

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 (545) hide show
  1. data/CHANGELOG +160 -0
  2. data/benchmarks/UTF-8-Strings.rb +58 -0
  3. data/data/css/tjreport.css +7 -2
  4. data/doc/AppConfig.html +10 -4
  5. data/doc/Arguments.html +10 -4
  6. data/doc/CHANGELOG.html +171 -5
  7. data/doc/COPYING.html +10 -4
  8. data/doc/Object.html +11 -107
  9. data/doc/README.html +10 -4
  10. data/doc/RuntimeConfig.html +10 -4
  11. data/doc/String.html +16 -11
  12. data/doc/StringIO.html +10 -4
  13. data/doc/TaskJuggler.html +506 -435
  14. data/doc/TaskJuggler/Account.html +10 -4
  15. data/doc/TaskJuggler/AccountAttribute.html +10 -4
  16. data/doc/TaskJuggler/AccountScenario.html +10 -4
  17. data/doc/TaskJuggler/Allocation.html +69 -60
  18. data/doc/TaskJuggler/AllocationAttribute.html +10 -4
  19. data/doc/TaskJuggler/AttributeBase.html +10 -4
  20. data/doc/TaskJuggler/AttributeDefinition.html +10 -4
  21. data/doc/TaskJuggler/BatchProcessor.html +202 -192
  22. data/doc/TaskJuggler/Booking.html +10 -4
  23. data/doc/TaskJuggler/BookingListAttribute.html +10 -4
  24. data/doc/TaskJuggler/BooleanAttribute.html +10 -4
  25. data/doc/TaskJuggler/CSVFile.html +10 -4
  26. data/doc/TaskJuggler/CellSettingPattern.html +10 -4
  27. data/doc/TaskJuggler/CellSettingPatternList.html +10 -4
  28. data/doc/TaskJuggler/Charge.html +10 -4
  29. data/doc/TaskJuggler/ChargeListAttribute.html +10 -4
  30. data/doc/TaskJuggler/ChargeSet.html +10 -4
  31. data/doc/TaskJuggler/ChargeSetListAttribute.html +10 -4
  32. data/doc/TaskJuggler/ColumnListAttribute.html +10 -4
  33. data/doc/TaskJuggler/ColumnTable.html +10 -4
  34. data/doc/TaskJuggler/Daemon.html +71 -52
  35. data/doc/TaskJuggler/DateAttribute.html +10 -4
  36. data/doc/TaskJuggler/DefinitionListAttribute.html +10 -4
  37. data/doc/TaskJuggler/DependencyListAttribute.html +10 -4
  38. data/doc/TaskJuggler/DurationAttribute.html +10 -4
  39. data/doc/TaskJuggler/{MacroParser.html → FileList.html} +58 -173
  40. data/doc/TaskJuggler/{RichTextException.html → FileRecord.html} +59 -80
  41. data/doc/TaskJuggler/FixnumAttribute.html +10 -4
  42. data/doc/TaskJuggler/FlagListAttribute.html +10 -4
  43. data/doc/TaskJuggler/FloatAttribute.html +10 -4
  44. data/doc/TaskJuggler/FormatListAttribute.html +10 -4
  45. data/doc/TaskJuggler/GanttChart.html +10 -4
  46. data/doc/TaskJuggler/GanttContainer.html +14 -8
  47. data/doc/TaskJuggler/GanttHeader.html +10 -4
  48. data/doc/TaskJuggler/GanttHeaderScaleItem.html +10 -4
  49. data/doc/TaskJuggler/GanttLine.html +29 -24
  50. data/doc/TaskJuggler/GanttLoadStack.html +10 -4
  51. data/doc/TaskJuggler/GanttMilestone.html +10 -4
  52. data/doc/TaskJuggler/GanttRouter.html +10 -4
  53. data/doc/TaskJuggler/GanttTaskBar.html +20 -10
  54. data/doc/TaskJuggler/HTMLDocument.html +10 -4
  55. data/doc/TaskJuggler/HTMLGraphics.html +10 -4
  56. data/doc/TaskJuggler/Interval.html +10 -4
  57. data/doc/TaskJuggler/IntervalListAttribute.html +10 -4
  58. data/doc/TaskJuggler/JobInfo.html +10 -4
  59. data/doc/TaskJuggler/Journal.html +227 -160
  60. data/doc/TaskJuggler/JournalEntry.html +10 -4
  61. data/doc/TaskJuggler/JournalEntryList.html +158 -72
  62. data/doc/TaskJuggler/KeywordArray.html +21 -9
  63. data/doc/TaskJuggler/KeywordDocumentation.html +612 -475
  64. data/doc/TaskJuggler/Limits.html +13 -8
  65. data/doc/TaskJuggler/Limits/Limit.html +10 -4
  66. data/doc/TaskJuggler/LimitsAttribute.html +10 -4
  67. data/doc/TaskJuggler/ListAttributeBase.html +10 -4
  68. data/doc/TaskJuggler/Log.html +10 -4
  69. data/doc/TaskJuggler/LogFile.html +10 -4
  70. data/doc/TaskJuggler/LogicalAttribute.html +10 -4
  71. data/doc/TaskJuggler/LogicalExpression.html +11 -5
  72. data/doc/TaskJuggler/LogicalExpressionAttribute.html +10 -4
  73. data/doc/TaskJuggler/LogicalFlag.html +10 -4
  74. data/doc/TaskJuggler/LogicalFunction.html +132 -124
  75. data/doc/TaskJuggler/LogicalOperation.html +10 -4
  76. data/doc/TaskJuggler/Macro.html +16 -10
  77. data/doc/TaskJuggler/MacroTable.html +44 -38
  78. data/doc/TaskJuggler/ManagerResponsibilities.html +10 -4
  79. data/doc/TaskJuggler/ManagerStatusRecord.html +10 -4
  80. data/doc/TaskJuggler/Message.html +92 -68
  81. data/doc/TaskJuggler/MessageHandler.html +349 -28
  82. data/doc/TaskJuggler/Navigator.html +10 -4
  83. data/doc/TaskJuggler/NavigatorElement.html +10 -4
  84. data/doc/TaskJuggler/NikuProject.html +10 -4
  85. data/doc/TaskJuggler/NikuReport.html +10 -4
  86. data/doc/TaskJuggler/NikuResource.html +10 -4
  87. data/doc/TaskJuggler/NodeListAttribute.html +10 -4
  88. data/doc/TaskJuggler/OnShiftCache.html +10 -4
  89. data/doc/TaskJuggler/ProcessIntercom.html +118 -111
  90. data/doc/TaskJuggler/ProcessIntercomIface.html +75 -22
  91. data/doc/TaskJuggler/Project.html +886 -913
  92. data/doc/TaskJuggler/ProjectBroker.html +442 -331
  93. data/doc/TaskJuggler/ProjectBrokerIface.html +95 -38
  94. data/doc/TaskJuggler/ProjectFileParser.html +320 -317
  95. data/doc/TaskJuggler/ProjectFileScanner.html +336 -339
  96. data/doc/TaskJuggler/ProjectRecord.html +119 -56
  97. data/doc/TaskJuggler/ProjectServer.html +282 -237
  98. data/doc/TaskJuggler/ProjectServerIface.html +45 -39
  99. data/doc/TaskJuggler/PropertyAttribute.html +10 -4
  100. data/doc/TaskJuggler/PropertyList.html +177 -173
  101. data/doc/TaskJuggler/PropertySet.html +11 -5
  102. data/doc/TaskJuggler/PropertyTreeNode.html +194 -191
  103. data/doc/TaskJuggler/Query.html +280 -256
  104. data/doc/TaskJuggler/RTFHandlers.html +10 -4
  105. data/doc/TaskJuggler/RTFNavigator.html +33 -26
  106. data/doc/TaskJuggler/RTFQuery.html +135 -169
  107. data/doc/TaskJuggler/RTFReport.html +63 -56
  108. data/doc/TaskJuggler/RTFReportLink.html +58 -47
  109. data/doc/TaskJuggler/RTFWithQuerySupport.html +666 -0
  110. data/doc/TaskJuggler/RealFormat.html +10 -4
  111. data/doc/TaskJuggler/RealFormatAttribute.html +10 -4
  112. data/doc/TaskJuggler/ReferenceAttribute.html +10 -4
  113. data/doc/TaskJuggler/Report.html +333 -290
  114. data/doc/TaskJuggler/ReportBase.html +182 -174
  115. data/doc/TaskJuggler/ReportContext.html +10 -4
  116. data/doc/TaskJuggler/ReportServer.html +144 -126
  117. data/doc/TaskJuggler/ReportServerIface.html +50 -44
  118. data/doc/TaskJuggler/ReportServerRecord.html +38 -32
  119. data/doc/TaskJuggler/ReportServlet.html +144 -137
  120. data/doc/TaskJuggler/ReportTable.html +10 -4
  121. data/doc/TaskJuggler/ReportTableCell.html +169 -164
  122. data/doc/TaskJuggler/ReportTableColumn.html +10 -4
  123. data/doc/TaskJuggler/ReportTableLegend.html +10 -4
  124. data/doc/TaskJuggler/ReportTableLine.html +10 -4
  125. data/doc/TaskJuggler/Resource.html +121 -115
  126. data/doc/TaskJuggler/ResourceListAttribute.html +10 -4
  127. data/doc/TaskJuggler/ResourceListRE.html +10 -4
  128. data/doc/TaskJuggler/ResourceScenario.html +13 -7
  129. data/doc/TaskJuggler/RichText.html +61 -37
  130. data/doc/TaskJuggler/RichTextAttribute.html +10 -4
  131. data/doc/TaskJuggler/RichTextDocument.html +91 -81
  132. data/doc/TaskJuggler/RichTextElement.html +378 -317
  133. data/doc/TaskJuggler/RichTextFunctionExample.html +10 -4
  134. data/doc/TaskJuggler/RichTextFunctionHandler.html +16 -11
  135. data/doc/TaskJuggler/RichTextImage.html +10 -4
  136. data/doc/TaskJuggler/RichTextIntermediate.html +138 -70
  137. data/doc/TaskJuggler/RichTextParser.html +48 -40
  138. data/doc/TaskJuggler/RichTextScanner.html +328 -906
  139. data/doc/TaskJuggler/RichTextSnip.html +59 -57
  140. data/doc/TaskJuggler/RichTextSyntaxRules.html +458 -369
  141. data/doc/TaskJuggler/Scenario.html +10 -4
  142. data/doc/TaskJuggler/ScenarioData.html +33 -30
  143. data/doc/TaskJuggler/ScenarioListAttribute.html +10 -4
  144. data/doc/TaskJuggler/Scoreboard.html +10 -4
  145. data/doc/TaskJuggler/SheetHandlerBase.html +315 -191
  146. data/doc/TaskJuggler/SheetReceiver.html +334 -313
  147. data/doc/TaskJuggler/SheetSender.html +10 -4
  148. data/doc/TaskJuggler/Shift.html +10 -4
  149. data/doc/TaskJuggler/ShiftAssignment.html +10 -4
  150. data/doc/TaskJuggler/ShiftAssignments.html +10 -4
  151. data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +10 -4
  152. data/doc/TaskJuggler/ShiftScenario.html +10 -4
  153. data/doc/TaskJuggler/SimpleQueryExpander.html +697 -0
  154. data/doc/TaskJuggler/SortListAttribute.html +10 -4
  155. data/doc/TaskJuggler/SourceFileInfo.html +10 -4
  156. data/doc/TaskJuggler/StatusSheetReceiver.html +10 -4
  157. data/doc/TaskJuggler/StatusSheetReport.html +10 -4
  158. data/doc/TaskJuggler/StatusSheetSender.html +10 -4
  159. data/doc/TaskJuggler/StringAttribute.html +10 -4
  160. data/doc/TaskJuggler/SymbolAttribute.html +10 -4
  161. data/doc/TaskJuggler/SyntaxReference.html +260 -230
  162. data/doc/TaskJuggler/TOCEntry.html +99 -42
  163. data/doc/TaskJuggler/TSResourceRecord.html +10 -4
  164. data/doc/TaskJuggler/TSTaskRecord.html +10 -4
  165. data/doc/TaskJuggler/TableColumnDefinition.html +10 -4
  166. data/doc/TaskJuggler/TableOfContents.html +54 -12
  167. data/doc/TaskJuggler/TableReport.html +877 -872
  168. data/doc/TaskJuggler/Task.html +117 -68
  169. data/doc/TaskJuggler/TaskDependency.html +10 -4
  170. data/doc/TaskJuggler/TaskListAttribute.html +10 -4
  171. data/doc/TaskJuggler/TaskListRE.html +10 -4
  172. data/doc/TaskJuggler/TaskScenario.html +1681 -1563
  173. data/doc/TaskJuggler/TextFormatter.html +10 -4
  174. data/doc/TaskJuggler/TextParser.html +567 -534
  175. data/doc/TaskJuggler/TextParser/Pattern.html +128 -118
  176. data/doc/TaskJuggler/TextParser/Rule.html +26 -15
  177. data/doc/TaskJuggler/TextParser/StackElement.html +10 -4
  178. data/doc/TaskJuggler/TextParser/TextParserResultArray.html +22 -16
  179. data/doc/TaskJuggler/TextParser/TokenDoc.html +10 -4
  180. data/doc/TaskJuggler/TextReport.html +15 -6
  181. data/doc/TaskJuggler/TextScanner.html +319 -287
  182. data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +16 -10
  183. data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +23 -17
  184. data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +17 -11
  185. data/doc/TaskJuggler/TextScanner/StreamHandle.html +102 -96
  186. data/doc/TaskJuggler/TimeSheet.html +138 -175
  187. data/doc/TaskJuggler/TimeSheetReceiver.html +10 -4
  188. data/doc/TaskJuggler/TimeSheetRecord.html +65 -58
  189. data/doc/TaskJuggler/TimeSheetReport.html +47 -42
  190. data/doc/TaskJuggler/TimeSheetSender.html +10 -4
  191. data/doc/TaskJuggler/TimeSheetSummary.html +91 -83
  192. data/doc/TaskJuggler/TimeSheets.html +22 -16
  193. data/doc/TaskJuggler/Tj3AppBase.html +10 -4
  194. data/doc/TaskJuggler/Tj3Client.html +399 -365
  195. data/doc/TaskJuggler/Tj3Daemon.html +107 -94
  196. data/doc/TaskJuggler/Tj3SheetAppBase.html +10 -4
  197. data/doc/TaskJuggler/Tj3SsReceiver.html +10 -4
  198. data/doc/TaskJuggler/Tj3SsSender.html +10 -4
  199. data/doc/TaskJuggler/Tj3TsReceiver.html +10 -4
  200. data/doc/TaskJuggler/Tj3TsSender.html +10 -4
  201. data/doc/TaskJuggler/Tj3TsSummary.html +10 -4
  202. data/doc/TaskJuggler/TjException.html +10 -4
  203. data/doc/TaskJuggler/TjTime.html +145 -140
  204. data/doc/TaskJuggler/TjpExample.html +10 -4
  205. data/doc/TaskJuggler/TjpExportRE.html +122 -118
  206. data/doc/TaskJuggler/TjpSyntaxRules.html +4065 -4052
  207. data/doc/TaskJuggler/URLParameter.html +10 -4
  208. data/doc/TaskJuggler/UserManual.html +162 -155
  209. data/doc/TaskJuggler/VimSyntax.html +1028 -0
  210. data/doc/TaskJuggler/WebServer.html +45 -27
  211. data/doc/TaskJuggler/WorkingHours.html +10 -4
  212. data/doc/TaskJuggler/WorkingHoursAttribute.html +10 -4
  213. data/doc/TaskJuggler/XMLBlob.html +10 -4
  214. data/doc/TaskJuggler/XMLComment.html +10 -4
  215. data/doc/TaskJuggler/XMLDocument.html +10 -4
  216. data/doc/TaskJuggler/XMLElement.html +10 -4
  217. data/doc/TaskJuggler/XMLNamedText.html +10 -4
  218. data/doc/TaskJuggler/XMLText.html +10 -4
  219. data/doc/index.html +735 -677
  220. data/doc/lib/AccountScenario_rb.html +1 -1
  221. data/doc/lib/Account_rb.html +1 -1
  222. data/doc/lib/Allocation_rb.html +1 -1
  223. data/doc/lib/AppConfig_rb.html +1 -1
  224. data/doc/lib/AttributeBase_rb.html +1 -1
  225. data/doc/lib/AttributeDefinition_rb.html +1 -1
  226. data/doc/lib/Attributes_rb.html +1 -1
  227. data/doc/lib/BatchProcessor_rb.html +1 -1
  228. data/doc/lib/Booking_rb.html +1 -1
  229. data/doc/lib/ChargeSet_rb.html +1 -1
  230. data/doc/lib/Charge_rb.html +1 -1
  231. data/doc/lib/{Message_rb.html → FileList_rb.html} +3 -5
  232. data/doc/lib/HTMLDocument_rb.html +1 -1
  233. data/doc/lib/Interval_rb.html +1 -1
  234. data/doc/lib/Journal_rb.html +1 -1
  235. data/doc/lib/KeywordArray_rb.html +1 -1
  236. data/doc/lib/KeywordDocumentation_rb.html +1 -1
  237. data/doc/lib/Limits_rb.html +1 -1
  238. data/doc/lib/LogFile_rb.html +1 -1
  239. data/doc/lib/Log_rb.html +1 -1
  240. data/doc/lib/LogicalExpression_rb.html +1 -1
  241. data/doc/lib/LogicalFunction_rb.html +1 -1
  242. data/doc/lib/LogicalOperation_rb.html +1 -1
  243. data/doc/lib/MacroTable_rb.html +1 -3
  244. data/doc/lib/MessageHandler_rb.html +1 -1
  245. data/doc/lib/ProjectFileParser_rb.html +1 -1
  246. data/doc/lib/ProjectFileScanner_rb.html +1 -1
  247. data/doc/lib/Project_rb.html +4 -2
  248. data/doc/lib/PropertyList_rb.html +1 -1
  249. data/doc/lib/PropertySet_rb.html +1 -1
  250. data/doc/lib/PropertyTreeNode_rb.html +1 -1
  251. data/doc/lib/Query_rb.html +1 -1
  252. data/doc/lib/RTFHandlers_rb.html +1 -1
  253. data/doc/lib/RTFNavigator_rb.html +1 -1
  254. data/doc/lib/RTFQuery_rb.html +2 -2
  255. data/doc/lib/RTFReportLink_rb.html +4 -2
  256. data/doc/lib/RTFReport_rb.html +1 -1
  257. data/doc/lib/{MacroParser_rb.html → RTFWithQuerySupport_rb.html} +4 -6
  258. data/doc/lib/RealFormat_rb.html +1 -1
  259. data/doc/lib/ResourceScenario_rb.html +1 -1
  260. data/doc/lib/Resource_rb.html +1 -1
  261. data/doc/lib/RichTextDocument_rb.html +1 -1
  262. data/doc/lib/RichTextElement_rb.html +1 -1
  263. data/doc/lib/RichTextFunctionExample_rb.html +1 -1
  264. data/doc/lib/RichTextFunctionHandler_rb.html +1 -1
  265. data/doc/lib/RichTextParser_rb.html +1 -1
  266. data/doc/lib/RichTextScanner_rb.html +3 -1
  267. data/doc/lib/RichTextSnip_rb.html +1 -1
  268. data/doc/lib/RichTextSyntaxRules_rb.html +1 -1
  269. data/doc/lib/RichText_rb.html +3 -1
  270. data/doc/lib/RuntimeConfig_rb.html +1 -1
  271. data/doc/lib/ScenarioData_rb.html +2 -2
  272. data/doc/lib/Scenario_rb.html +1 -1
  273. data/doc/lib/Scoreboard_rb.html +1 -1
  274. data/doc/lib/SheetHandlerBase_rb.html +5 -1
  275. data/doc/lib/SheetReceiver_rb.html +3 -1
  276. data/doc/lib/SheetSender_rb.html +1 -1
  277. data/doc/lib/ShiftAssignments_rb.html +1 -1
  278. data/doc/lib/ShiftScenario_rb.html +1 -1
  279. data/doc/lib/Shift_rb.html +1 -1
  280. data/doc/lib/SimpleQueryExpander_rb.html +67 -0
  281. data/doc/lib/SourceFileInfo_rb.html +1 -1
  282. data/doc/lib/StatusSheetReceiver_rb.html +1 -1
  283. data/doc/lib/StatusSheetSender_rb.html +1 -1
  284. data/doc/lib/SyntaxReference_rb.html +1 -1
  285. data/doc/lib/TOCEntry_rb.html +1 -1
  286. data/doc/lib/TableColumnDefinition_rb.html +1 -1
  287. data/doc/lib/TableOfContents_rb.html +1 -1
  288. data/doc/lib/TaskDependency_rb.html +1 -1
  289. data/doc/lib/TaskJuggler_rb.html +1 -1
  290. data/doc/lib/TaskScenario_rb.html +1 -1
  291. data/doc/lib/Task_rb.html +1 -1
  292. data/doc/lib/TextFormatter_rb.html +1 -1
  293. data/doc/lib/TextParser/Pattern_rb.html +1 -1
  294. data/doc/lib/TextParser/Rule_rb.html +1 -1
  295. data/doc/lib/TextParser/StackElement_rb.html +1 -1
  296. data/doc/lib/TextParser/TokenDoc_rb.html +1 -1
  297. data/doc/lib/TextParser_rb.html +3 -1
  298. data/doc/lib/TextScanner_rb.html +1 -3
  299. data/doc/lib/TimeSheetReceiver_rb.html +1 -1
  300. data/doc/lib/TimeSheetSender_rb.html +1 -1
  301. data/doc/lib/TimeSheetSummary_rb.html +1 -1
  302. data/doc/lib/TimeSheets_rb.html +1 -1
  303. data/doc/lib/Tj3AppBase_rb.html +1 -1
  304. data/doc/lib/Tj3Config_rb.html +1 -1
  305. data/doc/lib/Tj3SheetAppBase_rb.html +1 -1
  306. data/doc/lib/TjException_rb.html +1 -1
  307. data/doc/lib/TjTime_rb.html +1 -1
  308. data/doc/lib/TjpExample_rb.html +1 -1
  309. data/doc/lib/TjpSyntaxRules_rb.html +1 -1
  310. data/doc/lib/URLParameter_rb.html +1 -1
  311. data/doc/lib/UTF8String_rb.html +1 -1
  312. data/doc/lib/UserManual_rb.html +1 -1
  313. data/doc/lib/{ruby-signal-bug_rb.html → VimSyntax_rb.html} +17 -4
  314. data/doc/lib/WorkingHours_rb.html +1 -1
  315. data/doc/lib/XMLDocument_rb.html +1 -1
  316. data/doc/lib/XMLElement_rb.html +1 -1
  317. data/doc/lib/daemon/Daemon_rb.html +1 -1
  318. data/doc/lib/daemon/ProcessIntercom_rb.html +1 -1
  319. data/doc/lib/daemon/ProjectBroker_rb.html +1 -1
  320. data/doc/lib/daemon/ProjectServer_rb.html +1 -1
  321. data/doc/lib/daemon/ReportServer_rb.html +1 -3
  322. data/doc/lib/daemon/WebServer_rb.html +1 -1
  323. data/doc/lib/deep_copy_rb.html +1 -1
  324. data/doc/lib/reports/CSVFile_rb.html +1 -1
  325. data/doc/lib/reports/ColumnTable_rb.html +1 -1
  326. data/doc/lib/reports/GanttChart_rb.html +1 -1
  327. data/doc/lib/reports/GanttContainer_rb.html +1 -1
  328. data/doc/lib/reports/GanttHeaderScaleItem_rb.html +1 -1
  329. data/doc/lib/reports/GanttHeader_rb.html +1 -1
  330. data/doc/lib/reports/GanttLine_rb.html +1 -1
  331. data/doc/lib/reports/GanttLoadStack_rb.html +1 -1
  332. data/doc/lib/reports/GanttMilestone_rb.html +1 -1
  333. data/doc/lib/reports/GanttRouter_rb.html +1 -1
  334. data/doc/lib/reports/GanttTaskBar_rb.html +1 -1
  335. data/doc/lib/reports/HTMLGraphics_rb.html +1 -1
  336. data/doc/lib/reports/Navigator_rb.html +1 -1
  337. data/doc/lib/reports/NikuReport_rb.html +1 -1
  338. data/doc/lib/reports/ReportBase_rb.html +1 -1
  339. data/doc/lib/reports/ReportContext_rb.html +1 -1
  340. data/doc/lib/reports/ReportTableCell_rb.html +1 -1
  341. data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
  342. data/doc/lib/reports/ReportTableLegend_rb.html +1 -1
  343. data/doc/lib/reports/ReportTableLine_rb.html +1 -1
  344. data/doc/lib/reports/ReportTable_rb.html +1 -1
  345. data/doc/lib/reports/Report_rb.html +1 -1
  346. data/doc/lib/reports/ResourceListRE_rb.html +1 -1
  347. data/doc/lib/reports/StatusSheetReport_rb.html +1 -1
  348. data/doc/lib/reports/TableReport_rb.html +1 -1
  349. data/doc/lib/reports/TaskListRE_rb.html +1 -1
  350. data/doc/lib/reports/TextReport_rb.html +1 -1
  351. data/doc/lib/reports/TimeSheetReport_rb.html +1 -1
  352. data/doc/lib/reports/TjpExportRE_rb.html +1 -1
  353. data/doc/lib/taskjuggler3_rb.html +1 -1
  354. data/doc/lib/tj3client_rb.html +1 -1
  355. data/doc/lib/tj3d_rb.html +1 -1
  356. data/doc/lib/tj3man_rb.html +1 -1
  357. data/doc/lib/tj3ss_receiver_rb.html +1 -1
  358. data/doc/lib/tj3ss_sender_rb.html +1 -1
  359. data/doc/lib/tj3ts_receiver_rb.html +1 -1
  360. data/doc/lib/tj3ts_sender_rb.html +1 -1
  361. data/doc/lib/tj3ts_summary_rb.html +1 -1
  362. data/lib/Allocation.rb +8 -5
  363. data/lib/BatchProcessor.rb +7 -3
  364. data/lib/FileList.rb +58 -0
  365. data/lib/Journal.rb +73 -33
  366. data/lib/KeywordArray.rb +4 -0
  367. data/lib/KeywordDocumentation.rb +45 -11
  368. data/lib/Limits.rb +0 -1
  369. data/lib/LogicalExpression.rb +1 -1
  370. data/lib/LogicalFunction.rb +14 -12
  371. data/lib/MacroTable.rb +3 -4
  372. data/lib/MessageHandler.rb +136 -7
  373. data/lib/Project.rb +72 -86
  374. data/lib/ProjectFileParser.rb +30 -33
  375. data/lib/ProjectFileScanner.rb +7 -16
  376. data/lib/PropertyList.rb +25 -27
  377. data/lib/PropertySet.rb +1 -1
  378. data/lib/PropertyTreeNode.rb +9 -12
  379. data/lib/Query.rb +5 -4
  380. data/lib/RTFNavigator.rb +2 -1
  381. data/lib/RTFQuery.rb +4 -11
  382. data/lib/RTFReport.rb +2 -1
  383. data/lib/RTFReportLink.rb +10 -4
  384. data/lib/RTFWithQuerySupport.rb +45 -0
  385. data/lib/Resource.rb +20 -20
  386. data/lib/ResourceScenario.rb +3 -3
  387. data/lib/RichText.rb +15 -7
  388. data/lib/RichTextDocument.rb +8 -4
  389. data/lib/RichTextElement.rb +35 -12
  390. data/lib/RichTextFunctionHandler.rb +11 -12
  391. data/lib/RichTextParser.rb +5 -3
  392. data/lib/RichTextScanner.rb +144 -565
  393. data/lib/RichTextSnip.rb +3 -7
  394. data/lib/RichTextSyntaxRules.rb +51 -32
  395. data/lib/ScenarioData.rb +16 -25
  396. data/lib/SheetHandlerBase.rb +59 -2
  397. data/lib/SheetReceiver.rb +36 -18
  398. data/lib/SimpleQueryExpander.rb +58 -0
  399. data/lib/SyntaxReference.rb +9 -5
  400. data/lib/TOCEntry.rb +2 -0
  401. data/lib/TableOfContents.rb +4 -0
  402. data/lib/Task.rb +23 -12
  403. data/lib/TaskJuggler.rb +72 -33
  404. data/lib/TaskScenario.rb +131 -53
  405. data/lib/TextParser.rb +43 -30
  406. data/lib/TextParser/Pattern.rb +17 -13
  407. data/lib/TextParser/Rule.rb +5 -0
  408. data/lib/TextScanner.rb +46 -25
  409. data/lib/TimeSheetSummary.rb +9 -7
  410. data/lib/TimeSheets.rb +14 -23
  411. data/lib/Tj3Config.rb +1 -1
  412. data/lib/TjTime.rb +1 -2
  413. data/lib/TjpSyntaxRules.rb +128 -104
  414. data/lib/UTF8String.rb +0 -1
  415. data/lib/UserManual.rb +5 -4
  416. data/lib/VimSyntax.rb +223 -0
  417. data/lib/daemon/Daemon.rb +9 -0
  418. data/lib/daemon/ProcessIntercom.rb +19 -4
  419. data/lib/daemon/ProjectBroker.rb +149 -68
  420. data/lib/daemon/ProjectServer.rb +119 -79
  421. data/lib/daemon/ReportServer.rb +42 -31
  422. data/lib/daemon/WebServer.rb +21 -2
  423. data/lib/deep_copy.rb +1 -1
  424. data/lib/reports/GanttContainer.rb +2 -2
  425. data/lib/reports/GanttLine.rb +2 -3
  426. data/lib/reports/GanttTaskBar.rb +7 -3
  427. data/lib/reports/Report.rb +62 -57
  428. data/lib/reports/ReportBase.rb +6 -4
  429. data/lib/reports/ReportTableCell.rb +13 -14
  430. data/lib/reports/TableReport.rb +2 -1
  431. data/lib/reports/TextReport.rb +3 -0
  432. data/lib/reports/TimeSheetReport.rb +2 -3
  433. data/lib/reports/TjpExportRE.rb +0 -2
  434. data/lib/tj3client.rb +31 -3
  435. data/lib/tj3d.rb +8 -1
  436. data/manual/Day_To_Day_Juggling +2 -95
  437. data/manual/How_To_Contribute +2 -1
  438. data/manual/Rich_Text_Attributes +37 -3
  439. data/manual/Software +203 -0
  440. data/test/MessageChecker.rb +4 -4
  441. data/test/TestSuite/HTML-Reports/Alerts.html +172 -0
  442. data/test/TestSuite/HTML-Reports/CellText.html +758 -0
  443. data/test/TestSuite/HTML-Reports/ColumnPeriods.html +156 -0
  444. data/test/TestSuite/HTML-Reports/IsOngoing.html +172 -0
  445. data/test/TestSuite/HTML-Reports/LogicalFunctions.html +245 -0
  446. data/test/TestSuite/HTML-Reports/Query.html +31 -0
  447. data/test/TestSuite/HTML-Reports/css/tjmanual.css +14 -0
  448. data/test/TestSuite/HTML-Reports/css/tjreport.css +233 -21
  449. data/test/TestSuite/HTML-Reports/depArrows.html +842 -0
  450. data/test/TestSuite/HTML-Reports/scripts/scripts/wz_tooltip.js +1301 -0
  451. data/test/TestSuite/HTML-Reports/scripts/wz_tooltip.js +20 -20
  452. data/test/TestSuite/ReportGenerator/Correct/Alerts.tjp +48 -0
  453. data/test/TestSuite/ReportGenerator/Correct/Macros.tjp +57 -0
  454. data/test/TestSuite/ReportGenerator/Correct/refs/Alerts-1.csv +386 -0
  455. data/test/TestSuite/ReportGenerator/Correct/refs/Macros-1.csv +6 -0
  456. data/test/TestSuite/ReportGenerator/{Correct → Errors}/css/tjmanual.css +0 -0
  457. data/test/TestSuite/ReportGenerator/{Correct → Errors}/css/tjreport.css +0 -0
  458. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/details.png +0 -0
  459. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-green.png +0 -0
  460. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-red.png +0 -0
  461. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-yellow.png +0 -0
  462. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/resource.png +0 -0
  463. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/resourcegroup.png +0 -0
  464. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/task.png +0 -0
  465. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/taskgroup.png +0 -0
  466. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-down.png +0 -0
  467. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-flat.png +0 -0
  468. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-up.png +0 -0
  469. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.html +26 -0
  470. data/test/TestSuite/ReportGenerator/{Correct → Errors}/scripts/wz_tooltip.js +0 -0
  471. data/test/TestSuite/Scheduler/Correct/Allocate.html +3210 -0
  472. data/test/TestSuite/Scheduler/Correct/Allocate.tjp +19 -0
  473. data/test/TestSuite/Scheduler/Correct/Container.html +22 -22
  474. data/test/TestSuite/Scheduler/Correct/Limits.html +4964 -0
  475. data/test/TestSuite/Scheduler/Correct/Shift.html +1707 -417
  476. data/test/TestSuite/Scheduler/Correct/Shift2.html +9 -9
  477. data/test/TestSuite/Scheduler/Correct/css/tjreport.css +6 -2
  478. data/test/TestSuite/Scheduler/Errors/css/tjmanual.css +66 -0
  479. data/test/TestSuite/Scheduler/Errors/css/tjreport.css +407 -0
  480. data/test/TestSuite/Scheduler/Errors/icons/details.png +0 -0
  481. data/test/TestSuite/Scheduler/Errors/icons/flag-green.png +0 -0
  482. data/test/TestSuite/Scheduler/Errors/icons/flag-red.png +0 -0
  483. data/test/TestSuite/Scheduler/Errors/icons/flag-yellow.png +0 -0
  484. data/test/TestSuite/Scheduler/Errors/icons/resource.png +0 -0
  485. data/test/TestSuite/Scheduler/Errors/icons/resourcegroup.png +0 -0
  486. data/test/TestSuite/Scheduler/Errors/icons/task.png +0 -0
  487. data/test/TestSuite/Scheduler/Errors/icons/taskgroup.png +0 -0
  488. data/test/TestSuite/Scheduler/Errors/icons/trend-down.png +0 -0
  489. data/test/TestSuite/Scheduler/Errors/icons/trend-flat.png +0 -0
  490. data/test/TestSuite/Scheduler/Errors/icons/trend-up.png +0 -0
  491. data/test/TestSuite/Scheduler/Errors/loop_detected_1.tjp +1 -1
  492. data/test/TestSuite/Scheduler/Errors/loop_detected_10.tjp +1 -1
  493. data/test/TestSuite/Scheduler/Errors/loop_detected_11.tjp +1 -1
  494. data/test/TestSuite/Scheduler/Errors/loop_detected_12.tjp +1 -1
  495. data/test/TestSuite/Scheduler/Errors/loop_detected_13.tjp +1 -1
  496. data/test/TestSuite/Scheduler/Errors/loop_detected_14.tjp +1 -1
  497. data/test/TestSuite/Scheduler/Errors/loop_detected_2.tjp +1 -1
  498. data/test/TestSuite/Scheduler/Errors/loop_detected_3.tjp +1 -1
  499. data/test/TestSuite/Scheduler/Errors/loop_detected_4.tjp +1 -1
  500. data/test/TestSuite/Scheduler/Errors/loop_detected_5.tjp +1 -1
  501. data/test/TestSuite/Scheduler/Errors/loop_detected_6.tjp +1 -1
  502. data/test/TestSuite/Scheduler/Errors/loop_detected_7.tjp +1 -1
  503. data/test/TestSuite/Scheduler/Errors/loop_detected_8.tjp +1 -1
  504. data/test/TestSuite/Scheduler/Errors/loop_detected_9.tjp +1 -1
  505. data/test/TestSuite/Scheduler/Errors/scripts/wz_tooltip.js +1301 -0
  506. data/test/TestSuite/Scheduler/Errors/task_pred_before.tjp +11 -0
  507. data/test/TestSuite/Scheduler/Errors/task_pred_before_gd.tjp +11 -0
  508. data/test/TestSuite/Scheduler/Errors/task_pred_before_gl.tjp +11 -0
  509. data/test/TestSuite/Scheduler/Errors/task_succ_after.tjp +12 -0
  510. data/test/TestSuite/Scheduler/Errors/task_succ_after_gd.tjp +12 -0
  511. data/test/TestSuite/Scheduler/Errors/task_succ_after_gl.tjp +12 -0
  512. data/test/TestSuite/StatusSheets/dev2.tji +22 -0
  513. data/test/TestSuite/StatusSheets/resrep.tji +7 -0
  514. data/test/TestSuite/StatusSheets/run +6 -4
  515. data/test/TestSuite/StatusSheets/tj3d.log +312 -0
  516. data/test/TestSuite/Syntax/Correct/Managers.html +263 -0
  517. data/test/TestSuite/Syntax/Correct/tutorial.tjp +1 -2
  518. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
  519. data/test/TestSuite/Syntax/Errors/macro_stack_overflow.tjp +1 -1
  520. data/test/TestSuite/TimeSheets/acceptable_intervals +1 -0
  521. data/test/TestSuite/TimeSheets/resrep.tji +7 -0
  522. data/test/TestSuite/TimeSheets/run +6 -5
  523. data/test/TestSuite/TimeSheets/statussheets.log +1 -0
  524. data/test/TestSuite/TimeSheets/ts.tji +351 -0
  525. data/test/TestSuite/TimeSheets/tsdef.tji +2 -0
  526. data/test/test_PropertySet.rb +2 -2
  527. data/test/test_RichText.rb +178 -387
  528. data/test/test_SimpleQueryExpander.rb +55 -0
  529. data/test/test_deep_copy.rb +2 -2
  530. metadata +854 -834
  531. data/lib/MacroParser.rb +0 -77
  532. data/lib/Message.rb +0 -56
  533. data/lib/ruby-signal-bug.rb +0 -43
  534. data/test/TestSuite/HTML-Reports/TimeSheet.html +0 -79
  535. data/test/TestSuite/HTML-Reports/reference.html +0 -51
  536. data/test/TestSuite/ReportGenerator/Correct/Journal.html +0 -63
  537. data/test/TestSuite/ReportGenerator/Correct/LogicalFunctions2.csv +0 -3
  538. data/test/TestSuite/ReportGenerator/Correct/opennodes.csv +0 -2
  539. data/test/TestSuite/ReportGenerator/Correct/opennodes.tjp +0 -26
  540. data/test/TestSuite/ReportGenerator/Correct/refs/opennodes-1.csv +0 -2
  541. data/test/TestSuite/Scheduler/Correct/Booking2.html +0 -603
  542. data/test/TestSuite/Scheduler/Correct/TimeSheet2.html +0 -108
  543. data/test/TestSuite/StatusSheetTemplates/project.tji +0 -35
  544. data/test/TestSuite/StatusSheetTemplates/project.tjp +0 -56
  545. data/test/TestSuite/Syntax/Correct/ResourcePrefix.html +0 -32
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = SimpleQueryExpander.rb -- The TaskJuggler III Project Management Software
5
+ #
6
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'strscan'
14
+
15
+ class TaskJuggler
16
+
17
+ # The SimpleQueryExpander class is used to replace embedded attribute
18
+ # queries in a string with the value of the attribute. The embedded queries
19
+ # must have the form <-name-> where name is the name of the attribute. The
20
+ # Query class is used to determine the value of the attribute within the
21
+ # context of the query.
22
+ class SimpleQueryExpander
23
+
24
+ # _inputStr_ is the String with the embedded queries. _query_ is the Query
25
+ # with that provides the evaluation context. _messageHandle_ is a
26
+ # MessageHandler that will be used for error reporting. _sourceFileInfo_
27
+ # is a SourceFileInfo reference used for error reporting.
28
+ def initialize(inputStr, query, messageHandler, sourceFileInfo)
29
+ @inputStr = inputStr
30
+ @query = query.dup
31
+ @messageHandler = messageHandler
32
+ @sourceFileInfo = sourceFileInfo
33
+ end
34
+
35
+ def expand
36
+ # Create a copy of the input string since we will modify it.
37
+ str = @inputStr.dup
38
+ # Replace all occurences of <-name->.
39
+ str.gsub!(/<-[a-zA-Z][_a-zA-Z]*->/) do |match|
40
+ len = match.size
41
+ attribute = match[2..-3]
42
+ @query.attributeId = attribute
43
+ @query.process
44
+ if @query.ok
45
+ @query.to_s
46
+ else
47
+ # The query failed. We report an error.
48
+ @messageHandler.error('sqe_expand_failed',
49
+ "Unknown attribute #{attribute}",
50
+ @sourceFileInfo)
51
+ end
52
+ end
53
+ str
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -24,10 +24,14 @@ class TaskJuggler
24
24
  # output as well as HTML files are supported.
25
25
  class SyntaxReference
26
26
 
27
- # The constructor is the most important function of this class. It creates a
28
- # parser object and then traverses all rules and extracts the documented
29
- # patterns. In a second pass the extracted KeywordDocumentation objects are
30
- # then cross referenced to capture their relationships.
27
+ attr_reader :keywords
28
+
29
+ # The constructor is the most important function of this class. It creates
30
+ # a parser object and then traverses all rules and extracts the documented
31
+ # patterns. In a second pass the extracted KeywordDocumentation objects
32
+ # are then cross referenced to capture their relationships. _manual_ is an
33
+ # optional reference to the UserManual object that uses this
34
+ # SyntaxReference.
31
35
  def initialize(manual = nil)
32
36
  @manual = manual
33
37
  @messageHandler = MessageHandler.new(true)
@@ -69,7 +73,7 @@ class TaskJuggler
69
73
  end
70
74
  end
71
75
 
72
- # Return a sorted Array with all keywords.
76
+ # Return a sorted Array with all keywords (as String objects).
73
77
  def all
74
78
  sorted = @keywords.keys.sort
75
79
  # Register the neighbours with each keyword so we can use this info in
@@ -21,6 +21,8 @@ class TaskJuggler
21
21
  # be turned into an HTML tree.
22
22
  class TOCEntry
23
23
 
24
+ attr_reader :number, :title, :tag
25
+
24
26
  # Create a TOCEntry object.
25
27
  # _number_: The section number as String, e. g. '1.2.3' or 'A.3'.
26
28
  # _title_: The section title as String.
@@ -30,6 +30,10 @@ class TaskJuggler
30
30
  @entries << entry
31
31
  end
32
32
 
33
+ def each
34
+ @entries.each { |e| yield e }
35
+ end
36
+
33
37
  # Return HTML elements that represent the content of the TableOfContents
34
38
  # object. The result is a tree of XMLElement objects.
35
39
  def to_html
@@ -32,25 +32,37 @@ class TaskJuggler
32
32
  end
33
33
 
34
34
  def query_journal(query)
35
- journalText(query, true)
35
+ journalText(query, true, false)
36
+ end
37
+
38
+ def query_journal_sub(query)
39
+ journalText(query, true, true)
36
40
  end
37
41
 
38
42
  private
39
43
 
40
44
  # Create a blog-style list of all alert messages that match the Query.
41
- def journalText(query, longVersion)
45
+ def journalText(query, longVersion, recursive)
42
46
  # The components of the message are either UTF-8 text or RichText. For
43
47
  # the RichText components, we use the originally provided markup since
44
48
  # we compose the result as RichText markup first.
45
49
  rText = ''
46
- list = @project['journal'].entriesByTask(self, query.start, query.end)
50
+ if recursive
51
+ list = @project['journal'].entriesByTaskR(self, query.start, query.end)
52
+ else
53
+ list = @project['journal'].entriesByTask(self, query.start, query.end)
54
+ end
47
55
  list.reverse.each do |entry|
48
56
  tsRecord = entry.timeSheetRecord
49
57
 
50
58
  if entry.property.is_a?(Task)
51
59
  levelRecord = @project['alertLevels'][entry.alertLevel]
52
- alertName = "[[File:icons/flag-#{levelRecord[0]}.png|" +
53
- "alt=[#{levelRecord[1]}]|text-bottom]]"
60
+ if query.selfContained
61
+ alertName = "<nowiki>[#{levelRecord[1]}]</nowiki>"
62
+ else
63
+ alertName = "[[File:icons/flag-#{levelRecord[0]}.png|" +
64
+ "alt=[#{levelRecord[1]}]|text-bottom]]"
65
+ end
54
66
  rText += "== #{alertName} <nowiki>#{entry.headline}</nowiki> ==\n" +
55
67
  "''Reported on #{entry.date.to_s(query.timeFormat)}'' "
56
68
  if entry.author
@@ -84,15 +96,14 @@ class TaskJuggler
84
96
 
85
97
  # Now convert the RichText markup String into RichTextIntermediate
86
98
  # format.
87
- begin
88
- rti = RichText.new(rText, RTFHandlers.create(@project)).
89
- generateIntermediateFormat
90
- rescue RichTextException => msg
91
- $stderr.puts "Error while processing Rich Text\n" +
92
- "Line #{msg.lineNo}: #{msg.text}\n" +
93
- "#{msg.line}"
99
+ unless (rti = RichText.new(rText, RTFHandlers.create(@project),
100
+ @project.messageHandler).
101
+ generateIntermediateFormat)
102
+ @project.messageHandler.warning(
103
+ 'task_journal_text', 'Syntax error in journal text')
94
104
  return nil
95
105
  end
106
+
96
107
  # No section numbers, please!
97
108
  rti.sectionNumbers = false
98
109
  # We use a special class to allow CSS formating.
@@ -45,17 +45,29 @@ class TaskJuggler
45
45
  files.each do |file|
46
46
  begin
47
47
  @parser.open(file, master)
48
- rescue TjException
48
+ rescue TjException => msg
49
+ if msg.message && !msg.message.empty?
50
+ @messageHandler.critical('parse', msg.message)
51
+ end
49
52
  Log.exit('parser')
50
53
  return false
51
54
  end
52
55
  if master
53
- @project = @parser.parse('project')
56
+ # The first file is considered the master file.
57
+ if (@project = @parser.parse('project')) == false
58
+ Log.exit('parser')
59
+ return false
60
+ end
54
61
  master = false
55
62
  else
63
+ # All other files.
56
64
  @parser.setGlobalMacros
57
- @parser.parse('properties')
65
+ if @parser.parse('properties') == false
66
+ Log.exit('parser')
67
+ return false
68
+ end
58
69
  end
70
+ @project.inputFiles << file
59
71
  @parser.close
60
72
  end
61
73
 
@@ -70,9 +82,19 @@ class TaskJuggler
70
82
  # Parse a file and add the content to the existing project. _fileName_ is
71
83
  # the name of the file. _rule_ is the TextParser::Rule to start with.
72
84
  def parseFile(fileName, rule)
73
- @parser.open(fileName, false)
85
+ begin
86
+ @parser.open(fileName, false)
87
+ @project.inputFiles << fileName
88
+ rescue TjException => msg
89
+ if msg.message && !msg.message.empty?
90
+ @messageHandler.critical('parse_file', msg.message)
91
+ end
92
+ return nil
93
+ end
94
+
74
95
  @parser.setGlobalMacros
75
- return nil if (res = @parser.parse(rule)).nil?
96
+ return nil if (res = @parser.parse(rule)) == false
97
+
76
98
  @parser.close
77
99
  res
78
100
  end
@@ -83,7 +105,16 @@ class TaskJuggler
83
105
  Log.enter('scheduler', 'Scheduling project ...')
84
106
  #puts @project.to_s
85
107
  @project.warnTsDeltas = @warnTsDeltas
86
- res = @project.schedule
108
+
109
+ begin
110
+ res = @project.schedule
111
+ rescue TjException => msg
112
+ if msg.message && !msg.message.empty?
113
+ @messageHandler.critical('scheduling_error', msg.message)
114
+ end
115
+ return false
116
+ end
117
+
87
118
  Log.exit('scheduler')
88
119
  res
89
120
  end
@@ -95,9 +126,18 @@ class TaskJuggler
95
126
  outputDir += '/' unless outputDir.empty? || outputDir[-1] == '/'
96
127
  @project.outputDir = outputDir
97
128
  Log.enter('reports', 'Generating reports ...')
98
- res = @project.generateReports(@maxCpuCores)
129
+
130
+ begin
131
+ @project.generateReports(@maxCpuCores)
132
+ rescue TjException => msg
133
+ if msg.message && !msg.message.empty?
134
+ @messageHandler.critical('generate_reports', msg.message)
135
+ end
136
+ return false
137
+ end
138
+
99
139
  Log.exit('reports')
100
- res
140
+ true
101
141
  end
102
142
 
103
143
  # Generate the report with the ID _reportId_. If _regExpMode_ is true,
@@ -109,7 +149,10 @@ class TaskJuggler
109
149
  begin
110
150
  Log.enter('generateReport', 'Generating report #{reportId} ...')
111
151
  @project.generateReport(reportId, regExpMode, dynamicAttributes)
112
- rescue TjException
152
+ rescue TjException => msg
153
+ if msg.message && !msg.message.empty?
154
+ @messageHandler.critical('generate_report', msg.message)
155
+ end
113
156
  Log.exit('generateReport')
114
157
  return false
115
158
  end
@@ -117,14 +160,16 @@ class TaskJuggler
117
160
  true
118
161
  end
119
162
 
120
- # Generate the report with the ID _reportId_. If _regExpMode_ is true,
121
- # _reportId_ is interpreted as a Regular Expression and all reports with
122
- # matching IDs are listed.
163
+ # List the details of the report with _reportId_ or if _regExpMode_ the
164
+ # reports that match the regular expression in _reportId_.
123
165
  def listReports(reportId, regExpMode)
124
166
  begin
125
167
  Log.enter('listReports', 'Generating report list for #{reportId} ...')
126
168
  @project.listReports(reportId, regExpMode)
127
- rescue TjException
169
+ rescue TjException => msg
170
+ if msg.message && !msg.message.empty?
171
+ @messageHandler.critical('list_reports', msg.message)
172
+ end
128
173
  Log.exit('listReports')
129
174
  return false
130
175
  end
@@ -149,17 +194,14 @@ class TaskJuggler
149
194
  'scenarioIdx' => @project['trackingScenarioIdx'],
150
195
  'start' => ts.interval.start,
151
196
  'end' => ts.interval.end,
152
- 'timeFormat' => '%Y-%m-%d' }
197
+ 'timeFormat' => '%Y-%m-%d',
198
+ 'selfContained' => true }
153
199
  query = Query.new(queryAttrs)
154
- rti = ts.resource.query_journal(query)
155
- rti.lineWidth = 72
156
- rti.indent = 2
157
- rti.titleIndent = 0
158
- rti.listIndent = 2
159
- rti.parIndent = 2
160
- rti.preIndent = 4
161
- puts rti.to_s
162
- rescue TjException
200
+ puts ts.resource.query_journal(query).richText.inputText
201
+ rescue TjException => msg
202
+ if msg.message && !msg.message.empty?
203
+ @messageHandler.critical('check_time_sheet', msg.message)
204
+ end
163
205
  Log.exit('checkTimeSheet')
164
206
  return false
165
207
  end
@@ -181,17 +223,14 @@ class TaskJuggler
181
223
  'timeFormat' => '%Y-%m-%d',
182
224
  'start' => ss[1],
183
225
  'end' => ss[2],
184
- 'timeFormat' => '%Y-%m-%d' }
226
+ 'timeFormat' => '%Y-%m-%d',
227
+ 'selfContained' => true }
185
228
  query = Query.new(queryAttrs)
186
- rti = ss[0].query_dashboard(query)
187
- rti.lineWidth = 72
188
- rti.indent = 2
189
- rti.titleIndent = 0
190
- rti.listIndent = 2
191
- rti.parIndent = 2
192
- rti.preIndent = 4
193
- puts rti.to_s
194
- rescue TjException
229
+ puts ss[0].query_dashboard(query).richText.inputText
230
+ rescue TjException => msg
231
+ if msg.message && !msg.message.empty?
232
+ @messageHandler.critical('check_status_sheet', msg.message)
233
+ end
195
234
  Log.exit('checkStatusSheet')
196
235
  return false
197
236
  end
@@ -324,7 +324,10 @@ class TaskJuggler
324
324
  # be called to do some more housekeeping. It computes some derived data
325
325
  # based on the just scheduled values.
326
326
  def finishScheduling
327
- calcCompletion
327
+ # The completion degree calculation is done recursively. So we only call
328
+ # it for top-level tasks.
329
+ calcCompletion unless @property.parent
330
+
328
331
  # This list is no longer needed, so let's save some memory. Set it to
329
332
  # nil so we can detect accidental use.
330
333
  @candidates = nil
@@ -434,12 +437,33 @@ class TaskJuggler
434
437
  task = dependency.task
435
438
  limit = task[dependency.onEnd ? 'end' : 'start', @scenarioIdx]
436
439
  next if limit.nil?
437
- if limit > a('start')
440
+ if a('start') < limit
438
441
  error('task_pred_before',
439
442
  "Task #{@property.fullId} must start after " +
440
443
  "#{dependency.onEnd ? 'end' : 'start'} of task " +
441
444
  "#{task.fullId}.")
442
445
  end
446
+ if dependency.gapDuration > 0
447
+ if limit + dependency.gapDuration > a('start')
448
+ error('task_pred_before_gd',
449
+ "Task #{@property.fullId} must start " +
450
+ "#{dependency.gapDuration / (60 * 60 * 24)} days after " +
451
+ "#{dependency.onEnd ? 'end' : 'start'} of task " +
452
+ "#{task.fullId}. TaskJuggler cannot enforce this condition " +
453
+ "because the task is scheduled ALAP (finish-to-start).")
454
+ end
455
+ end
456
+ if dependency.gapLength > 0
457
+ if calcLength(limit, a('start')) < dependency.gapLength
458
+ error('task_pred_before_gl',
459
+ "Task #{@property.fullId} must start " +
460
+ "#{@project.slotsToDays(dependency.gapLength)} " +
461
+ "working days after " +
462
+ "#{dependency.onEnd ? 'end' : 'start'} of task " +
463
+ "#{task.fullId}. TaskJuggler cannot enforce this condition " +
464
+ "because the task is scheduled ALAP (finish-to-start).")
465
+ end
466
+ end
443
467
  end
444
468
 
445
469
  # Check that all following tasks end before this task
@@ -452,6 +476,27 @@ class TaskJuggler
452
476
  "Task #{@property.fullId} must end before " +
453
477
  "#{dependency.onEnd ? 'end' : 'start'} of task #{task.fullId}.")
454
478
  end
479
+ if dependency.gapDuration > 0
480
+ if limit - dependency.gapDuration < a('end')
481
+ error('task_succ_after_gd',
482
+ "Task #{@property.fullId} must end " +
483
+ "#{dependency.gapDuration / (60 * 60 * 24)} days before " +
484
+ "#{dependency.onEnd ? 'end' : 'start'} of task " +
485
+ "#{task.fullId}. TaskJuggler cannot enforce this condition " +
486
+ "because the task is scheduled ASAP (start-to-finish).")
487
+ end
488
+ end
489
+ if dependency.gapLength > 0
490
+ if calcLength(a('end'), limit) < dependency.gapLength
491
+ error('task_succ_after_gl',
492
+ "Task #{@property.fullId} must end " +
493
+ "#{@project.slotsToDays(dependency.gapLength)} " +
494
+ "working days before " +
495
+ "#{dependency.onEnd ? 'end' : 'start'} of task " +
496
+ "#{task.fullId}. TaskJuggler cannot enforce this condition " +
497
+ "because the task is scheduled ASAP (start-to-finish).")
498
+ end
499
+ end
455
500
  end
456
501
 
457
502
  if a('milestone') && a('start') != a('end')
@@ -497,8 +542,9 @@ class TaskJuggler
497
542
  def checkForLoops(path, atEnd, fromOutside)
498
543
  # Check if we have been here before on this path.
499
544
  if path.include?([ @property, atEnd ])
500
- error('loop_detected', "Loop detected at #{atEnd ? 'end' : 'start'} " +
501
- "of task #{@property.fullId}", false)
545
+ warning('loop_detected',
546
+ "Loop detected at #{atEnd ? 'end' : 'start'} " +
547
+ "of task #{@property.fullId}", false)
502
548
  skip = true
503
549
  path.each do |t, e|
504
550
  if t == @property && e == atEnd
@@ -507,7 +553,8 @@ class TaskJuggler
507
553
  end
508
554
  next if skip
509
555
  info("loop_at_#{e ? 'end' : 'start'}",
510
- "Loop ctnd. at #{e ? 'end' : 'start'} of task #{t.fullId}", t)
556
+ "Loop ctnd. at #{e ? 'end' : 'start'} of task #{t.fullId}",
557
+ t.sourceFileInfo)
511
558
  end
512
559
  error('loop_end', "Aborting")
513
560
  end
@@ -1098,12 +1145,8 @@ class TaskJuggler
1098
1145
  end
1099
1146
 
1100
1147
  def query_complete(query)
1101
- if @property.leaf?
1102
- query.sortable = query.numerical = complete = a('complete').to_i
1103
- query.string = "#{complete}%"
1104
- else
1105
- query.string = ''
1106
- end
1148
+ query.sortable = query.numerical = complete = a('complete').to_i
1149
+ query.string = "#{complete}%"
1107
1150
  end
1108
1151
 
1109
1152
  # Compute the cost generated by this Task for a given Account during a given
@@ -1172,10 +1215,10 @@ class TaskJuggler
1172
1215
  str += "* <nowiki>#{task.name}</nowiki> (#{task.fullId}) "
1173
1216
  if onEnd
1174
1217
  taskEnd = task['end', query.scenarioIdx].to_s(query.timeFormat)
1175
- str += "[->] #{taskEnd}"
1218
+ str += "<nowiki>[->]</nowiki> #{taskEnd}"
1176
1219
  else
1177
1220
  taskStart = task['start', query.scenarioIdx].to_s(query.timeFormat)
1178
- str += "[->[ #{taskStart}"
1221
+ str += "<nowiki>[->[</nowiki> #{taskStart}"
1179
1222
  end
1180
1223
  str += "\n"
1181
1224
  end
@@ -1184,16 +1227,19 @@ class TaskJuggler
1184
1227
  str += "* <nowiki>#{task.name}</nowiki> (#{task.fullId}) "
1185
1228
  if onEnd
1186
1229
  taskEnd = task['end', query.scenarioIdx].to_s(query.timeFormat)
1187
- str += "]->] #{taskEnd}"
1230
+ str += "<nowiki>]->]</nowiki> #{taskEnd}"
1188
1231
  else
1189
1232
  taskStart = task['start', query.scenarioIdx].to_s(query.timeFormat)
1190
- str += "]->[ #{taskStart}"
1233
+ str += "<nowiki>]->[</nowiki> #{taskStart}"
1191
1234
  end
1192
1235
  str += "\n"
1193
1236
  end
1194
1237
 
1195
- rText = RichText.new(str)
1196
- query.rti = rText.generateIntermediateFormat
1238
+ rText = RichText.new(str, [], @property.project.messageHandler)
1239
+ unless (query.rti = rText.generateIntermediateFormat)
1240
+ @property.project.messageHandler.warning(
1241
+ 'task_sc_followers', 'Syntax error in followers')
1242
+ end
1197
1243
  end
1198
1244
 
1199
1245
  def query_precursors(query)
@@ -1204,10 +1250,10 @@ class TaskJuggler
1204
1250
  str += "* <nowiki>#{task.name}</nowiki> (#{task.fullId}) "
1205
1251
  if onEnd
1206
1252
  taskEnd = task['end', query.scenarioIdx].to_s(query.timeFormat)
1207
- str += "]->] #{taskEnd}"
1253
+ str += "<nowiki>]->]</nowiki> #{taskEnd}"
1208
1254
  else
1209
1255
  taskStart = task['start', query.scenarioIdx].to_s(query.timeFormat)
1210
- str += "[->[ #{taskStart}"
1256
+ str += "<nowiki>[->[</nowiki> #{taskStart}"
1211
1257
  end
1212
1258
  str += "\n"
1213
1259
  end
@@ -1216,10 +1262,10 @@ class TaskJuggler
1216
1262
  str += "* <nowiki>#{task.name}</nowiki> (#{task.fullId}) "
1217
1263
  if onEnd
1218
1264
  taskEnd = task['end', query.scenarioIdx].to_s(query.timeFormat)
1219
- str += "[->] #{taskEnd}"
1265
+ str += "<nowiki>[->]</nowiki> #{taskEnd}"
1220
1266
  else
1221
1267
  taskStart = task['start', query.scenarioIdx].to_s(query.timeFormat)
1222
- str += "]->[ #{taskStart}"
1268
+ str += "<nowiki>]->[</nowiki> #{taskStart}"
1223
1269
  end
1224
1270
  str += "\n"
1225
1271
  end
@@ -1259,7 +1305,7 @@ class TaskJuggler
1259
1305
 
1260
1306
  def query_targets(query)
1261
1307
  targetList = PropertyList.new(@project.tasks, false)
1262
- targets(targetList)
1308
+ targets(targetList, true)
1263
1309
  targetList.delete(@property)
1264
1310
  targetList.setSorting([['start', true, @scenarioIdx],
1265
1311
  ['seqno', true, -1 ]])
@@ -1569,7 +1615,6 @@ class TaskJuggler
1569
1615
  return unless found
1570
1616
  end
1571
1617
 
1572
- iv = Interval.new(date, date + slotDuration)
1573
1618
  a('allocate').each do |allocation|
1574
1619
  next unless allocation.onShift?(date)
1575
1620
 
@@ -1640,6 +1685,16 @@ class TaskJuggler
1640
1685
  true
1641
1686
  end
1642
1687
 
1688
+ # Calculate the number of general working time slots between the TjTime
1689
+ # objects _d1_ and _d2_.
1690
+ def calcLength(d1, d2)
1691
+ slots = 0
1692
+ while d1 < d2
1693
+ slots += 1 if @project.isWorkingTime(d1)
1694
+ d1 += @project['scheduleGranularity']
1695
+ end
1696
+ slots
1697
+ end
1643
1698
 
1644
1699
  # Register the user provided bookings with the Resource scoreboards. A
1645
1700
  # booking describes the assignment of a Resource to a certain Task for a
@@ -1649,7 +1704,7 @@ class TaskJuggler
1649
1704
  a('booking').each do |booking|
1650
1705
  unless booking.resource.leaf?
1651
1706
  error('booking_resource_not_leaf',
1652
- "Booked resources may not be group resources", true,
1707
+ "Booked resources may not be group resources",
1653
1708
  booking.sourceFileInfo)
1654
1709
  end
1655
1710
  unless a('forward') || scheduled
@@ -1866,51 +1921,59 @@ class TaskJuggler
1866
1921
  # If the user provided a completion degree we are not touching it.
1867
1922
  if @property.provided('complete', @scenarioIdx)
1868
1923
  calcStatus
1869
- return
1924
+ return a('complete')
1870
1925
  end
1871
1926
 
1927
+ # We cannot compute a completion degree without a start or end date.
1872
1928
  if a('start').nil? || a('end').nil?
1873
1929
  @property['complete', @scenarioIdx] = 0.0
1874
1930
  @property['status', @scenarioIdx] = 'unknown'
1875
- return
1931
+ return nil
1876
1932
  end
1877
1933
 
1934
+ completion = 0.0
1878
1935
  if a('milestone')
1879
- @property['complete', @scenarioIdx] =
1936
+ # Milestones are either 0% or 100% complete.
1937
+ @property['complete', @scenarioIdx] = completion =
1880
1938
  @property['end', @scenarioIdx] <= @project['now'] ? 100.0 : 0.0
1881
1939
  @property['status', @scenarioIdx] =
1882
1940
  a('end') <= @project['now'] ? 'done' : 'not reached'
1883
1941
  else
1884
- completion = 0.0
1885
- if a('end') <= @project['now']
1942
+ # The task is in progress. Calculate the current completion
1943
+ # degree.
1944
+ if !property.leaf?
1945
+ # For container task the completion degree is the average of the
1946
+ # sub tasks.
1947
+ completion = 0.0
1948
+ @property.children.each do |child|
1949
+ return nil unless (comp = child.calcCompletion(@scenarioIdx))
1950
+ completion += comp
1951
+ end
1952
+ completion /= @property.children.length
1953
+ elsif a('end') <= @project['now']
1886
1954
  # The task has ended already. It's 100% complete.
1887
1955
  completion = 100.0
1888
1956
  elsif @project['now'] <= a('start')
1889
1957
  # The task has not started yet. Its' 0% complete.
1890
1958
  completion = 0.0
1959
+ elsif a('effort') > 0
1960
+ # Effort based leaf tasks. The completion degree is the percentage
1961
+ # of effort that has been done already.
1962
+ done = getEffectiveWork(@project.dateToIdx(a('start')),
1963
+ @project.dateToIdx(@project['now']))
1964
+ total = @project.convertToDailyLoad(
1965
+ a('effort') * @project['scheduleGranularity'])
1966
+ completion = done / total * 100.0
1891
1967
  else
1892
- # The task is in progress. Calculate the current completion
1893
- # degree.
1894
- if @property.leaf? && a('effort') > 0
1895
- # Effort based leaf tasks. The completion degree is the percantage
1896
- # of effort that has been done already.
1897
- done = getEffectiveWork(@project.dateToIdx(a('start')),
1898
- @project.dateToIdx(@project['now']))
1899
- total = @project.convertToDailyLoad(
1900
- a('effort') * @project['scheduleGranularity'])
1901
- completion = done / total * 100.0
1902
- else
1903
- # Container tasks and length/duration leaf tasks. There is no way
1904
- # we can compute the completion degree of a container task with a
1905
- # mix of effort and duration task in a meaningful way. So, we
1906
- # just go by duration.
1907
- completion = ((@project['now'] - a('start')) /
1908
- (a('end') - a('start'))) * 100.0
1909
- end
1968
+ # Length/duration leaf tasks.
1969
+ completion = ((@project['now'] - a('start')) /
1970
+ (a('end') - a('start'))) * 100.0
1910
1971
  end
1911
1972
  @property['complete', @scenarioIdx] = completion
1912
1973
  calcStatus
1913
1974
  end
1975
+
1976
+ completion
1914
1977
  end
1915
1978
 
1916
1979
  # Calculate the status of the task based on the 'complete' attribute.
@@ -1927,20 +1990,35 @@ class TaskJuggler
1927
1990
 
1928
1991
  # Recursively compile a list of Task properties which depend on the
1929
1992
  # current task.
1930
- def targets(list)
1993
+ def targets(list, includeChildren)
1994
+ # Ignore tasks that we have already included in the list.
1995
+ return if list.include?(@property)
1996
+
1931
1997
  # A target must be a leaf function that has no direct or indirect
1932
- # (through parent) following tasks.
1933
- if @property.leaf? && !hasSuccessors && !list.include?(@property)
1998
+ # (through parent) following tasks. Only milestones are recognized as
1999
+ # targets.
2000
+ if @property.leaf? && !hasSuccessors && a('milestone')
1934
2001
  list << @property
1935
2002
  return
1936
2003
  end
1937
2004
 
1938
2005
  a('endsuccs').each do |t, onEnd|
1939
- t.targets(@scenarioIdx, list)
2006
+ t.targets(@scenarioIdx, list, false)
2007
+ end
2008
+
2009
+ # Check for indirect followers.
2010
+ if @property.parent
2011
+ @property.parent.targets(@scenarioIdx, list, false)
1940
2012
  end
1941
2013
 
1942
- # Check of indirect followers.
1943
- @property.parent.targets(@scenarioIdx, list) if @property.parent
2014
+ # Also include targets of child tasks. The recursive iteration of child
2015
+ # tasks is limited to the tested task only. The followers are not
2016
+ # iterated.
2017
+ if includeChildren
2018
+ @property.children.each do |child|
2019
+ child.targets(@scenarioIdx, list, true)
2020
+ end
2021
+ end
1944
2022
  end
1945
2023
 
1946
2024
  # Compute the turnover generated by this Task for a given Account _account_