taskjuggler 0.0.5 → 0.0.6

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 (544) hide show
  1. data/CHANGELOG +2086 -0
  2. data/benchmarks/666tasks.tjp +3183 -0
  3. data/benchmarks/booking.tjp +14 -10
  4. data/doc/AppConfig.html +95 -73
  5. data/doc/Arguments.html +22 -2
  6. data/doc/CHANGELOG.html +2587 -0
  7. data/doc/COPYING.html +21 -1
  8. data/doc/Object.html +161 -122
  9. data/doc/README.html +21 -1
  10. data/doc/RuntimeConfig.html +26 -6
  11. data/doc/String.html +38 -18
  12. data/doc/StringIO.html +579 -0
  13. data/doc/TaskJuggler.html +251 -143
  14. data/doc/TaskJuggler/Account.html +26 -6
  15. data/doc/TaskJuggler/AccountAttribute.html +28 -8
  16. data/doc/TaskJuggler/AccountScenario.html +24 -4
  17. data/doc/TaskJuggler/Allocation.html +30 -10
  18. data/doc/TaskJuggler/AllocationAttribute.html +28 -8
  19. data/doc/TaskJuggler/AttributeBase.html +46 -26
  20. data/doc/TaskJuggler/AttributeDefinition.html +22 -2
  21. data/doc/TaskJuggler/BatchProcessor.html +40 -20
  22. data/doc/TaskJuggler/Booking.html +26 -6
  23. data/doc/TaskJuggler/BookingListAttribute.html +28 -8
  24. data/doc/TaskJuggler/BooleanAttribute.html +28 -8
  25. data/doc/TaskJuggler/CSVFile.html +308 -146
  26. data/doc/TaskJuggler/CellSettingPattern.html +22 -2
  27. data/doc/TaskJuggler/CellSettingPatternList.html +26 -6
  28. data/doc/TaskJuggler/Charge.html +26 -6
  29. data/doc/TaskJuggler/ChargeListAttribute.html +26 -6
  30. data/doc/TaskJuggler/ChargeSet.html +33 -13
  31. data/doc/TaskJuggler/ChargeSetListAttribute.html +28 -8
  32. data/doc/TaskJuggler/ColumnListAttribute.html +26 -6
  33. data/doc/TaskJuggler/ColumnTable.html +24 -4
  34. data/doc/TaskJuggler/Daemon.html +26 -6
  35. data/doc/TaskJuggler/DateAttribute.html +26 -6
  36. data/doc/TaskJuggler/DefinitionListAttribute.html +22 -2
  37. data/doc/TaskJuggler/DependencyListAttribute.html +28 -8
  38. data/doc/TaskJuggler/DurationAttribute.html +28 -8
  39. data/doc/TaskJuggler/FixnumAttribute.html +24 -4
  40. data/doc/TaskJuggler/FlagListAttribute.html +28 -8
  41. data/doc/TaskJuggler/FloatAttribute.html +26 -6
  42. data/doc/TaskJuggler/FormatListAttribute.html +24 -4
  43. data/doc/TaskJuggler/GanttChart.html +147 -126
  44. data/doc/TaskJuggler/GanttContainer.html +34 -14
  45. data/doc/TaskJuggler/GanttHeader.html +28 -8
  46. data/doc/TaskJuggler/GanttHeaderScaleItem.html +24 -4
  47. data/doc/TaskJuggler/GanttLine.html +38 -18
  48. data/doc/TaskJuggler/GanttLoadStack.html +26 -6
  49. data/doc/TaskJuggler/GanttMilestone.html +34 -14
  50. data/doc/TaskJuggler/GanttRouter.html +50 -30
  51. data/doc/TaskJuggler/GanttTaskBar.html +34 -14
  52. data/doc/TaskJuggler/HTMLDocument.html +26 -6
  53. data/doc/TaskJuggler/HTMLGraphics.html +30 -10
  54. data/doc/TaskJuggler/Interval.html +40 -22
  55. data/doc/TaskJuggler/IntervalListAttribute.html +28 -8
  56. data/doc/TaskJuggler/JobInfo.html +24 -4
  57. data/doc/TaskJuggler/Journal.html +226 -147
  58. data/doc/TaskJuggler/JournalEntry.html +22 -2
  59. data/doc/TaskJuggler/JournalEntryList.html +129 -112
  60. data/doc/TaskJuggler/KeywordArray.html +26 -6
  61. data/doc/TaskJuggler/KeywordDocumentation.html +46 -26
  62. data/doc/TaskJuggler/Limits.html +152 -123
  63. data/doc/TaskJuggler/Limits/Limit.html +149 -70
  64. data/doc/TaskJuggler/LimitsAttribute.html +36 -51
  65. data/doc/TaskJuggler/ListAttributeBase.html +24 -4
  66. data/doc/TaskJuggler/Log.html +50 -32
  67. data/doc/TaskJuggler/LogFile.html +37 -17
  68. data/doc/TaskJuggler/LogicalAttribute.html +53 -33
  69. data/doc/TaskJuggler/LogicalExpression.html +26 -6
  70. data/doc/TaskJuggler/LogicalExpressionAttribute.html +32 -12
  71. data/doc/TaskJuggler/LogicalFlag.html +42 -22
  72. data/doc/TaskJuggler/LogicalFunction.html +204 -140
  73. data/doc/TaskJuggler/LogicalOperation.html +135 -111
  74. data/doc/TaskJuggler/Macro.html +22 -2
  75. data/doc/TaskJuggler/MacroParser.html +32 -12
  76. data/doc/TaskJuggler/MacroTable.html +32 -12
  77. data/doc/TaskJuggler/ManagerResponsibilities.html +24 -4
  78. data/doc/TaskJuggler/ManagerStatusRecord.html +24 -4
  79. data/doc/TaskJuggler/Message.html +24 -4
  80. data/doc/TaskJuggler/MessageHandler.html +24 -4
  81. data/doc/TaskJuggler/Navigator.html +104 -71
  82. data/doc/TaskJuggler/NavigatorElement.html +32 -12
  83. data/doc/TaskJuggler/NikuProject.html +22 -2
  84. data/doc/TaskJuggler/NikuReport.html +310 -228
  85. data/doc/TaskJuggler/NikuResource.html +22 -2
  86. data/doc/TaskJuggler/NodeListAttribute.html +615 -0
  87. data/doc/TaskJuggler/OnShiftCache.html +32 -12
  88. data/doc/TaskJuggler/ProcessIntercom.html +205 -78
  89. data/doc/TaskJuggler/ProcessIntercomIface.html +26 -6
  90. data/doc/TaskJuggler/Project.html +708 -660
  91. data/doc/TaskJuggler/ProjectBroker.html +506 -304
  92. data/doc/TaskJuggler/ProjectBrokerIface.html +61 -41
  93. data/doc/TaskJuggler/ProjectFileParser.html +429 -373
  94. data/doc/TaskJuggler/ProjectFileScanner.html +1790 -0
  95. data/doc/TaskJuggler/ProjectRecord.html +80 -60
  96. data/doc/TaskJuggler/ProjectServer.html +312 -237
  97. data/doc/TaskJuggler/ProjectServerIface.html +101 -43
  98. data/doc/TaskJuggler/PropertyAttribute.html +32 -12
  99. data/doc/TaskJuggler/PropertyList.html +166 -145
  100. data/doc/TaskJuggler/PropertySet.html +254 -224
  101. data/doc/TaskJuggler/PropertyTreeNode.html +670 -536
  102. data/doc/TaskJuggler/Query.html +169 -148
  103. data/doc/TaskJuggler/RTFHandlers.html +622 -0
  104. data/doc/TaskJuggler/RTFNavigator.html +28 -8
  105. data/doc/TaskJuggler/RTFQuery.html +40 -20
  106. data/doc/TaskJuggler/RTFReport.html +62 -25
  107. data/doc/TaskJuggler/RTFReportLink.html +765 -0
  108. data/doc/TaskJuggler/RealFormat.html +26 -6
  109. data/doc/TaskJuggler/RealFormatAttribute.html +26 -6
  110. data/doc/TaskJuggler/ReferenceAttribute.html +59 -39
  111. data/doc/TaskJuggler/Report.html +402 -251
  112. data/doc/TaskJuggler/ReportBase.html +162 -137
  113. data/doc/TaskJuggler/ReportContext.html +112 -29
  114. data/doc/TaskJuggler/ReportServer.html +89 -64
  115. data/doc/TaskJuggler/ReportServerIface.html +75 -55
  116. data/doc/TaskJuggler/ReportServerRecord.html +54 -31
  117. data/doc/TaskJuggler/ReportServlet.html +980 -0
  118. data/doc/TaskJuggler/ReportTable.html +41 -21
  119. data/doc/TaskJuggler/ReportTableCell.html +214 -170
  120. data/doc/TaskJuggler/ReportTableColumn.html +30 -10
  121. data/doc/TaskJuggler/ReportTableLegend.html +36 -16
  122. data/doc/TaskJuggler/ReportTableLine.html +32 -12
  123. data/doc/TaskJuggler/Resource.html +99 -87
  124. data/doc/TaskJuggler/ResourceListAttribute.html +59 -39
  125. data/doc/TaskJuggler/ResourceListRE.html +47 -26
  126. data/doc/TaskJuggler/ResourceScenario.html +403 -437
  127. data/doc/TaskJuggler/RichText.html +26 -6
  128. data/doc/TaskJuggler/RichTextAttribute.html +50 -30
  129. data/doc/TaskJuggler/RichTextDocument.html +37 -17
  130. data/doc/TaskJuggler/RichTextElement.html +475 -413
  131. data/doc/TaskJuggler/RichTextException.html +22 -2
  132. data/doc/TaskJuggler/RichTextFunctionExample.html +28 -8
  133. data/doc/TaskJuggler/RichTextFunctionHandler.html +24 -4
  134. data/doc/TaskJuggler/RichTextImage.html +22 -2
  135. data/doc/TaskJuggler/RichTextIntermediate.html +38 -18
  136. data/doc/TaskJuggler/RichTextParser.html +56 -34
  137. data/doc/TaskJuggler/RichTextScanner.html +82 -61
  138. data/doc/TaskJuggler/RichTextSnip.html +34 -14
  139. data/doc/TaskJuggler/RichTextSyntaxRules.html +507 -353
  140. data/doc/TaskJuggler/Scenario.html +22 -2
  141. data/doc/TaskJuggler/ScenarioData.html +30 -46
  142. data/doc/TaskJuggler/ScenarioListAttribute.html +38 -18
  143. data/doc/TaskJuggler/Scoreboard.html +42 -22
  144. data/doc/TaskJuggler/SheetHandlerBase.html +40 -20
  145. data/doc/TaskJuggler/SheetReceiver.html +333 -295
  146. data/doc/TaskJuggler/SheetSender.html +253 -230
  147. data/doc/TaskJuggler/Shift.html +26 -6
  148. data/doc/TaskJuggler/ShiftAssignment.html +89 -73
  149. data/doc/TaskJuggler/ShiftAssignments.html +226 -234
  150. data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +39 -54
  151. data/doc/TaskJuggler/ShiftScenario.html +28 -8
  152. data/doc/TaskJuggler/SortListAttribute.html +34 -14
  153. data/doc/TaskJuggler/SourceFileInfo.html +24 -4
  154. data/doc/TaskJuggler/StatusSheetReceiver.html +24 -3
  155. data/doc/TaskJuggler/StatusSheetReport.html +168 -153
  156. data/doc/TaskJuggler/StatusSheetSender.html +24 -3
  157. data/doc/TaskJuggler/StringAttribute.html +38 -18
  158. data/doc/TaskJuggler/SymbolAttribute.html +32 -12
  159. data/doc/TaskJuggler/SyntaxReference.html +40 -20
  160. data/doc/TaskJuggler/TOCEntry.html +26 -6
  161. data/doc/TaskJuggler/TSResourceRecord.html +22 -2
  162. data/doc/TaskJuggler/TSTaskRecord.html +22 -2
  163. data/doc/TaskJuggler/TableColumnDefinition.html +59 -22
  164. data/doc/TaskJuggler/TableOfContents.html +26 -6
  165. data/doc/TaskJuggler/TableReport.html +937 -904
  166. data/doc/TaskJuggler/Task.html +55 -36
  167. data/doc/TaskJuggler/TaskDependency.html +24 -4
  168. data/doc/TaskJuggler/TaskListAttribute.html +50 -30
  169. data/doc/TaskJuggler/TaskListRE.html +27 -7
  170. data/doc/TaskJuggler/TaskScenario.html +1273 -1153
  171. data/doc/TaskJuggler/TextFormatter.html +28 -8
  172. data/doc/TaskJuggler/TextParser.html +585 -338
  173. data/doc/TaskJuggler/TextParser/Pattern.html +54 -34
  174. data/doc/TaskJuggler/TextParser/Rule.html +95 -73
  175. data/doc/TaskJuggler/TextParser/StackElement.html +39 -17
  176. data/doc/TaskJuggler/TextParser/TextParserResultArray.html +24 -4
  177. data/doc/TaskJuggler/TextParser/TokenDoc.html +22 -2
  178. data/doc/TaskJuggler/TextReport.html +28 -8
  179. data/doc/TaskJuggler/TextScanner.html +400 -1404
  180. data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +28 -240
  181. data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +37 -184
  182. data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +682 -0
  183. data/doc/TaskJuggler/TextScanner/StreamHandle.html +342 -67
  184. data/doc/TaskJuggler/TimeSheet.html +48 -28
  185. data/doc/TaskJuggler/TimeSheetReceiver.html +24 -3
  186. data/doc/TaskJuggler/TimeSheetRecord.html +47 -27
  187. data/doc/TaskJuggler/TimeSheetReport.html +154 -133
  188. data/doc/TaskJuggler/TimeSheetSender.html +24 -3
  189. data/doc/TaskJuggler/TimeSheetSummary.html +137 -91
  190. data/doc/TaskJuggler/TimeSheets.html +26 -6
  191. data/doc/TaskJuggler/Tj3AppBase.html +85 -58
  192. data/doc/TaskJuggler/Tj3Client.html +292 -238
  193. data/doc/TaskJuggler/Tj3Daemon.html +159 -74
  194. data/doc/TaskJuggler/Tj3SheetAppBase.html +26 -6
  195. data/doc/TaskJuggler/Tj3SsReceiver.html +26 -6
  196. data/doc/TaskJuggler/Tj3SsSender.html +53 -26
  197. data/doc/TaskJuggler/Tj3TsReceiver.html +28 -7
  198. data/doc/TaskJuggler/Tj3TsSender.html +26 -6
  199. data/doc/TaskJuggler/Tj3TsSummary.html +26 -6
  200. data/doc/TaskJuggler/TjException.html +22 -2
  201. data/doc/TaskJuggler/TjTime.html +216 -160
  202. data/doc/TaskJuggler/TjpExample.html +34 -14
  203. data/doc/TaskJuggler/TjpExportRE.html +403 -407
  204. data/doc/TaskJuggler/TjpSyntaxRules.html +4805 -4408
  205. data/doc/TaskJuggler/URLParameter.html +649 -0
  206. data/doc/TaskJuggler/UserManual.html +42 -22
  207. data/doc/TaskJuggler/WebServer.html +702 -0
  208. data/doc/TaskJuggler/WorkingHours.html +38 -18
  209. data/doc/TaskJuggler/WorkingHoursAttribute.html +61 -41
  210. data/doc/TaskJuggler/XMLBlob.html +24 -4
  211. data/doc/TaskJuggler/XMLComment.html +24 -4
  212. data/doc/TaskJuggler/XMLDocument.html +30 -10
  213. data/doc/TaskJuggler/XMLElement.html +34 -14
  214. data/doc/TaskJuggler/XMLNamedText.html +22 -2
  215. data/doc/TaskJuggler/XMLText.html +24 -4
  216. data/doc/index.html +1841 -1666
  217. data/doc/lib/AccountScenario_rb.html +1 -1
  218. data/doc/lib/Account_rb.html +1 -1
  219. data/doc/lib/Allocation_rb.html +1 -1
  220. data/doc/lib/AppConfig_rb.html +2 -2
  221. data/doc/lib/AttributeBase_rb.html +1 -1
  222. data/doc/lib/AttributeDefinition_rb.html +1 -1
  223. data/doc/lib/Attributes_rb.html +2 -2
  224. data/doc/lib/BatchProcessor_rb.html +1 -1
  225. data/doc/lib/Booking_rb.html +1 -1
  226. data/doc/lib/ChargeSet_rb.html +1 -1
  227. data/doc/lib/Charge_rb.html +1 -1
  228. data/doc/lib/HTMLDocument_rb.html +1 -1
  229. data/doc/lib/Interval_rb.html +1 -1
  230. data/doc/lib/Journal_rb.html +2 -2
  231. data/doc/lib/KeywordArray_rb.html +1 -1
  232. data/doc/lib/KeywordDocumentation_rb.html +1 -1
  233. data/doc/lib/Limits_rb.html +2 -2
  234. data/doc/lib/LogFile_rb.html +2 -2
  235. data/doc/lib/Log_rb.html +1 -1
  236. data/doc/lib/LogicalExpression_rb.html +1 -1
  237. data/doc/lib/LogicalFunction_rb.html +2 -2
  238. data/doc/lib/LogicalOperation_rb.html +2 -2
  239. data/doc/lib/MacroParser_rb.html +1 -1
  240. data/doc/lib/MacroTable_rb.html +1 -1
  241. data/doc/lib/MessageHandler_rb.html +1 -1
  242. data/doc/lib/Message_rb.html +1 -1
  243. data/doc/lib/ProjectFileParser_rb.html +4 -8
  244. data/doc/lib/ProjectFileScanner_rb.html +67 -0
  245. data/doc/lib/Project_rb.html +2 -2
  246. data/doc/lib/PropertyList_rb.html +2 -2
  247. data/doc/lib/PropertySet_rb.html +2 -2
  248. data/doc/lib/PropertyTreeNode_rb.html +2 -2
  249. data/doc/lib/Query_rb.html +2 -2
  250. data/doc/lib/RTFHandlers_rb.html +73 -0
  251. data/doc/lib/RTFNavigator_rb.html +1 -1
  252. data/doc/lib/RTFQuery_rb.html +1 -1
  253. data/doc/lib/RTFReportLink_rb.html +71 -0
  254. data/doc/lib/RTFReport_rb.html +2 -2
  255. data/doc/lib/RealFormat_rb.html +1 -1
  256. data/doc/lib/ResourceScenario_rb.html +2 -2
  257. data/doc/lib/Resource_rb.html +2 -2
  258. data/doc/lib/RichTextDocument_rb.html +1 -1
  259. data/doc/lib/RichTextElement_rb.html +2 -2
  260. data/doc/lib/RichTextFunctionExample_rb.html +1 -1
  261. data/doc/lib/RichTextFunctionHandler_rb.html +1 -1
  262. data/doc/lib/RichTextParser_rb.html +2 -2
  263. data/doc/lib/RichTextScanner_rb.html +2 -2
  264. data/doc/lib/RichTextSnip_rb.html +1 -1
  265. data/doc/lib/RichTextSyntaxRules_rb.html +2 -2
  266. data/doc/lib/RichText_rb.html +1 -1
  267. data/doc/lib/RuntimeConfig_rb.html +1 -1
  268. data/doc/lib/ScenarioData_rb.html +2 -2
  269. data/doc/lib/Scenario_rb.html +1 -1
  270. data/doc/lib/Scoreboard_rb.html +1 -1
  271. data/doc/lib/SheetHandlerBase_rb.html +1 -1
  272. data/doc/lib/SheetReceiver_rb.html +2 -2
  273. data/doc/lib/SheetSender_rb.html +4 -2
  274. data/doc/lib/ShiftAssignments_rb.html +4 -2
  275. data/doc/lib/ShiftScenario_rb.html +1 -1
  276. data/doc/lib/Shift_rb.html +1 -1
  277. data/doc/lib/SourceFileInfo_rb.html +1 -1
  278. data/doc/lib/StatusSheetReceiver_rb.html +2 -2
  279. data/doc/lib/StatusSheetSender_rb.html +2 -2
  280. data/doc/lib/SyntaxReference_rb.html +1 -1
  281. data/doc/lib/TOCEntry_rb.html +1 -1
  282. data/doc/lib/TableColumnDefinition_rb.html +2 -2
  283. data/doc/lib/TableOfContents_rb.html +1 -1
  284. data/doc/lib/TaskDependency_rb.html +1 -1
  285. data/doc/lib/TaskJuggler_rb.html +2 -2
  286. data/doc/lib/TaskScenario_rb.html +2 -2
  287. data/doc/lib/Task_rb.html +2 -2
  288. data/doc/lib/TextFormatter_rb.html +1 -1
  289. data/doc/lib/TextParser/Pattern_rb.html +1 -1
  290. data/doc/lib/TextParser/Rule_rb.html +2 -2
  291. data/doc/lib/TextParser/StackElement_rb.html +2 -2
  292. data/doc/lib/TextParser/TokenDoc_rb.html +1 -1
  293. data/doc/lib/TextParser_rb.html +2 -2
  294. data/doc/lib/TextScanner_rb.html +6 -2
  295. data/doc/lib/TimeSheetReceiver_rb.html +2 -2
  296. data/doc/lib/TimeSheetSender_rb.html +2 -2
  297. data/doc/lib/TimeSheetSummary_rb.html +2 -2
  298. data/doc/lib/TimeSheets_rb.html +2 -2
  299. data/doc/lib/Tj3AppBase_rb.html +2 -2
  300. data/doc/lib/Tj3Config_rb.html +2 -2
  301. data/doc/lib/Tj3SheetAppBase_rb.html +2 -2
  302. data/doc/lib/TjException_rb.html +1 -1
  303. data/doc/lib/TjTime_rb.html +2 -2
  304. data/doc/lib/TjpExample_rb.html +1 -1
  305. data/doc/lib/TjpSyntaxRules_rb.html +2 -2
  306. data/doc/lib/URLParameter_rb.html +67 -0
  307. data/doc/lib/UTF8String_rb.html +1 -1
  308. data/doc/lib/UserManual_rb.html +1 -1
  309. data/doc/lib/WorkingHours_rb.html +1 -1
  310. data/doc/lib/XMLDocument_rb.html +2 -2
  311. data/doc/lib/XMLElement_rb.html +1 -1
  312. data/doc/lib/daemon/Daemon_rb.html +1 -1
  313. data/doc/lib/daemon/ProcessIntercom_rb.html +2 -2
  314. data/doc/lib/daemon/ProjectBroker_rb.html +4 -2
  315. data/doc/lib/daemon/ProjectServer_rb.html +2 -2
  316. data/doc/lib/daemon/ReportServer_rb.html +2 -2
  317. data/doc/lib/daemon/WebServer_rb.html +75 -0
  318. data/doc/lib/deep_copy_rb.html +2 -2
  319. data/doc/lib/reports/CSVFile_rb.html +2 -2
  320. data/doc/lib/reports/ColumnTable_rb.html +1 -1
  321. data/doc/lib/reports/GanttChart_rb.html +2 -2
  322. data/doc/lib/reports/GanttContainer_rb.html +1 -1
  323. data/doc/lib/reports/GanttHeaderScaleItem_rb.html +1 -1
  324. data/doc/lib/reports/GanttHeader_rb.html +1 -1
  325. data/doc/lib/reports/GanttLine_rb.html +1 -1
  326. data/doc/lib/reports/GanttLoadStack_rb.html +1 -1
  327. data/doc/lib/reports/GanttMilestone_rb.html +1 -1
  328. data/doc/lib/reports/GanttRouter_rb.html +1 -1
  329. data/doc/lib/reports/GanttTaskBar_rb.html +1 -1
  330. data/doc/lib/reports/HTMLGraphics_rb.html +1 -1
  331. data/doc/lib/reports/Navigator_rb.html +2 -2
  332. data/doc/lib/reports/NikuReport_rb.html +2 -2
  333. data/doc/lib/reports/ReportBase_rb.html +2 -2
  334. data/doc/lib/reports/ReportContext_rb.html +2 -2
  335. data/doc/lib/reports/ReportTableCell_rb.html +2 -2
  336. data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
  337. data/doc/lib/reports/ReportTableLegend_rb.html +1 -1
  338. data/doc/lib/reports/ReportTableLine_rb.html +1 -1
  339. data/doc/lib/reports/ReportTable_rb.html +2 -2
  340. data/doc/lib/reports/Report_rb.html +2 -2
  341. data/doc/lib/reports/ResourceListRE_rb.html +2 -2
  342. data/doc/lib/reports/StatusSheetReport_rb.html +2 -2
  343. data/doc/lib/reports/TableReport_rb.html +2 -2
  344. data/doc/lib/reports/TaskListRE_rb.html +2 -2
  345. data/doc/lib/reports/TextReport_rb.html +1 -1
  346. data/doc/lib/reports/TimeSheetReport_rb.html +2 -2
  347. data/doc/lib/reports/TjpExportRE_rb.html +2 -2
  348. data/doc/lib/ruby-signal-bug_rb.html +1 -1
  349. data/doc/lib/taskjuggler3_rb.html +2 -2
  350. data/doc/lib/tj3client_rb.html +2 -2
  351. data/doc/lib/tj3d_rb.html +2 -2
  352. data/doc/lib/tj3man_rb.html +1 -1
  353. data/doc/lib/tj3ss_receiver_rb.html +1 -1
  354. data/doc/lib/tj3ss_sender_rb.html +2 -2
  355. data/doc/lib/tj3ts_receiver_rb.html +2 -2
  356. data/doc/lib/tj3ts_sender_rb.html +1 -1
  357. data/doc/lib/tj3ts_summary_rb.html +1 -1
  358. data/doc/rdoc.css +9 -4
  359. data/examples/tutorial.tjp +17 -15
  360. data/gem_spec.rb +3 -0
  361. data/lib/AppConfig.rb +3 -1
  362. data/lib/Attributes.rb +10 -8
  363. data/lib/Journal.rb +55 -20
  364. data/lib/Limits.rb +72 -46
  365. data/lib/LogFile.rb +3 -3
  366. data/lib/LogicalFunction.rb +19 -6
  367. data/lib/LogicalOperation.rb +5 -1
  368. data/lib/Project.rb +37 -9
  369. data/lib/ProjectFileParser.rb +25 -22
  370. data/lib/ProjectFileScanner.rb +365 -0
  371. data/lib/PropertyList.rb +2 -1
  372. data/lib/PropertySet.rb +14 -4
  373. data/lib/PropertyTreeNode.rb +42 -29
  374. data/lib/Query.rb +3 -1
  375. data/lib/RTFHandlers.rb +35 -0
  376. data/lib/RTFReport.rb +23 -6
  377. data/lib/RTFReportLink.rb +72 -0
  378. data/lib/Resource.rb +8 -16
  379. data/lib/ResourceScenario.rb +1 -22
  380. data/lib/RichTextElement.rb +42 -0
  381. data/lib/RichTextParser.rb +6 -4
  382. data/lib/RichTextScanner.rb +5 -5
  383. data/lib/RichTextSyntaxRules.rb +48 -10
  384. data/lib/ScenarioData.rb +5 -3
  385. data/lib/SheetReceiver.rb +24 -6
  386. data/lib/SheetSender.rb +17 -13
  387. data/lib/ShiftAssignments.rb +56 -52
  388. data/lib/StatusSheetReceiver.rb +1 -0
  389. data/lib/StatusSheetSender.rb +1 -0
  390. data/lib/TableColumnDefinition.rb +4 -2
  391. data/lib/Task.rb +8 -9
  392. data/lib/TaskJuggler.rb +21 -11
  393. data/lib/TaskScenario.rb +61 -26
  394. data/lib/TextParser.rb +268 -106
  395. data/lib/TextParser/Rule.rb +4 -2
  396. data/lib/TextParser/StackElement.rb +6 -4
  397. data/lib/TextScanner.rb +283 -700
  398. data/lib/TimeSheetReceiver.rb +1 -0
  399. data/lib/TimeSheetSender.rb +1 -0
  400. data/lib/TimeSheetSummary.rb +51 -26
  401. data/lib/TimeSheets.rb +1 -1
  402. data/lib/Tj3AppBase.rb +8 -1
  403. data/lib/Tj3Config.rb +1 -1
  404. data/lib/TjTime.rb +5 -0
  405. data/lib/TjpSyntaxRules.rb +360 -144
  406. data/lib/URLParameter.rb +30 -0
  407. data/lib/XMLDocument.rb +2 -2
  408. data/lib/daemon/ProcessIntercom.rb +50 -9
  409. data/lib/daemon/ProjectBroker.rb +63 -10
  410. data/lib/daemon/ProjectServer.rb +47 -16
  411. data/lib/daemon/ReportServer.rb +9 -4
  412. data/lib/daemon/WebServer.rb +204 -0
  413. data/lib/deep_copy.rb +4 -1
  414. data/lib/reports/CSVFile.rb +150 -66
  415. data/lib/reports/GanttChart.rb +2 -1
  416. data/lib/reports/Navigator.rb +18 -5
  417. data/lib/reports/NikuReport.rb +32 -2
  418. data/lib/reports/Report.rb +65 -37
  419. data/lib/reports/ReportBase.rb +14 -9
  420. data/lib/reports/ReportContext.rb +19 -4
  421. data/lib/reports/ReportTable.rb +2 -2
  422. data/lib/reports/ReportTableCell.rb +54 -30
  423. data/lib/reports/ResourceListRE.rb +4 -3
  424. data/lib/reports/StatusSheetReport.rb +8 -13
  425. data/lib/reports/TableReport.rb +47 -32
  426. data/lib/reports/TaskListRE.rb +3 -3
  427. data/lib/reports/TimeSheetReport.rb +14 -5
  428. data/lib/reports/TjpExportRE.rb +14 -19
  429. data/lib/taskjuggler3.rb +15 -0
  430. data/lib/tj3client.rb +9 -7
  431. data/lib/tj3d.rb +38 -10
  432. data/lib/tj3ss_sender.rb +7 -0
  433. data/lib/tj3ts_receiver.rb +1 -0
  434. data/manual/Day_To_Day_Juggling +1 -1
  435. data/manual/Rich_Text_Attributes +8 -0
  436. data/manual/TaskJuggler_2x_Migration +7 -0
  437. data/manual/The_TaskJuggler_Syntax +20 -6
  438. data/prj_cfg.rb +3 -2
  439. data/tasks/changelog.rake +36 -0
  440. data/tasks/csts.rake +2 -3
  441. data/tasks/gem.rake +10 -0
  442. data/tasks/missing.rake +0 -17
  443. data/test/TestSuite/ReportGenerator/Correct/Journal.html +63 -0
  444. data/test/TestSuite/ReportGenerator/Correct/Journal.tjp +14 -0
  445. data/test/TestSuite/{HTML-Reports/LogicalFunctions.tjp → ReportGenerator/Correct/LogicalFunctions1.tjp} +2 -2
  446. data/test/TestSuite/ReportGenerator/Correct/LogicalFunctions2.csv +3 -0
  447. data/test/TestSuite/ReportGenerator/Correct/LogicalFunctions2.tjp +19 -0
  448. data/test/TestSuite/ReportGenerator/Correct/css/tjmanual.css +66 -0
  449. data/test/TestSuite/ReportGenerator/Correct/css/tjreport.css +407 -0
  450. data/test/TestSuite/ReportGenerator/Correct/icons/details.png +0 -0
  451. data/test/TestSuite/ReportGenerator/Correct/icons/flag-green.png +0 -0
  452. data/test/TestSuite/ReportGenerator/Correct/icons/flag-red.png +0 -0
  453. data/test/TestSuite/ReportGenerator/Correct/icons/flag-yellow.png +0 -0
  454. data/test/TestSuite/ReportGenerator/Correct/icons/resource.png +0 -0
  455. data/test/TestSuite/ReportGenerator/Correct/icons/resourcegroup.png +0 -0
  456. data/test/TestSuite/ReportGenerator/Correct/icons/task.png +0 -0
  457. data/test/TestSuite/ReportGenerator/Correct/icons/taskgroup.png +0 -0
  458. data/test/TestSuite/ReportGenerator/Correct/icons/trend-down.png +0 -0
  459. data/test/TestSuite/ReportGenerator/Correct/icons/trend-flat.png +0 -0
  460. data/test/TestSuite/ReportGenerator/Correct/icons/trend-up.png +0 -0
  461. data/test/TestSuite/ReportGenerator/Correct/opennodes.csv +2 -0
  462. data/test/TestSuite/ReportGenerator/Correct/opennodes.tjp +26 -0
  463. data/test/TestSuite/ReportGenerator/Correct/refs/Journal-1.csv +6 -0
  464. data/test/TestSuite/ReportGenerator/Correct/refs/LogicalFunctions1-1.csv +7 -0
  465. data/test/TestSuite/ReportGenerator/Correct/refs/LogicalFunctions2-1.csv +2 -0
  466. data/test/TestSuite/ReportGenerator/Correct/refs/opennodes-1.csv +2 -0
  467. data/test/TestSuite/ReportGenerator/Correct/scripts/wz_tooltip.js +1301 -0
  468. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.tjp +20 -0
  469. data/test/TestSuite/Scheduler/Correct/Container.html +349 -0
  470. data/test/TestSuite/Scheduler/Correct/Limits.tjp +11 -4
  471. data/test/TestSuite/Scheduler/Correct/Shift2.html +464 -150
  472. data/test/TestSuite/Scheduler/Correct/TimeSheet2.html +108 -0
  473. data/test/TestSuite/Scheduler/Correct/TimeSheet2.tjp +7 -0
  474. data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +14 -0
  475. data/test/TestSuite/Scheduler/Correct/css/tjreport.css +233 -21
  476. data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +20 -20
  477. data/test/TestSuite/StatusSheetTemplates/project.tji +35 -0
  478. data/test/TestSuite/StatusSheetTemplates/project.tjp +56 -0
  479. data/test/TestSuite/StatusSheets/run +3 -2
  480. data/test/TestSuite/Syntax/Correct/Include.tjp +1 -1
  481. data/test/TestSuite/Syntax/Correct/Macro-1.tjp +1 -1
  482. data/test/TestSuite/Syntax/Correct/Macro-2.tjp +6 -0
  483. data/test/TestSuite/Syntax/Correct/Macro-3.tjp +14 -0
  484. data/test/TestSuite/Syntax/Correct/ResourcePrefix.html +32 -0
  485. data/test/TestSuite/Syntax/Correct/css/tjmanual.css +66 -0
  486. data/test/TestSuite/Syntax/Correct/css/tjreport.css +407 -0
  487. data/test/TestSuite/Syntax/Correct/icons/details.png +0 -0
  488. data/test/TestSuite/Syntax/Correct/icons/flag-green.png +0 -0
  489. data/test/TestSuite/Syntax/Correct/icons/flag-red.png +0 -0
  490. data/test/TestSuite/Syntax/Correct/icons/flag-yellow.png +0 -0
  491. data/test/TestSuite/Syntax/Correct/icons/resource.png +0 -0
  492. data/test/TestSuite/Syntax/Correct/icons/resourcegroup.png +0 -0
  493. data/test/TestSuite/Syntax/Correct/icons/task.png +0 -0
  494. data/test/TestSuite/Syntax/Correct/icons/taskgroup.png +0 -0
  495. data/test/TestSuite/Syntax/Correct/icons/trend-down.png +0 -0
  496. data/test/TestSuite/Syntax/Correct/icons/trend-flat.png +0 -0
  497. data/test/TestSuite/Syntax/Correct/icons/trend-up.png +0 -0
  498. data/test/TestSuite/Syntax/Correct/include/dir1/file2.tji +3 -0
  499. data/test/TestSuite/Syntax/Correct/include/dir1/file5.tji +2 -0
  500. data/test/TestSuite/Syntax/Correct/include/dir3/all.tji +3 -0
  501. data/test/TestSuite/Syntax/Correct/include/dir3/file1.tji +2 -0
  502. data/test/TestSuite/Syntax/Correct/include/dir3/file2.tji +1 -0
  503. data/test/TestSuite/Syntax/Correct/scripts/wz_tooltip.js +1301 -0
  504. data/test/TestSuite/Syntax/Correct/tutorial.tjp +13 -13
  505. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
  506. data/test/TestSuite/Syntax/Errors/include_recursion.tjp +1 -0
  507. data/test/TestSuite/Syntax/Errors/macro_stack_overflow.tjp +2 -1
  508. data/test/TestSuite/Syntax/Errors/{eof_in_istring1.tjp → no_token_match1.tjp} +2 -2
  509. data/test/TestSuite/Syntax/Errors/{eof_in_istring2.tjp → no_token_match2.tjp} +2 -2
  510. data/test/TestSuite/Syntax/Errors/{eof_in_istring3.tjp → no_token_match3.tjp} +1 -1
  511. data/test/TestSuite/Syntax/Errors/{eof_in_istring4.tjp → no_token_match4.tjp} +1 -1
  512. data/test/TestSuite/Syntax/Errors/{eof_in_istring5.tjp → no_token_match5.tjp} +1 -1
  513. data/test/TestSuite/Syntax/Errors/not_scheduled.tjp +13 -0
  514. data/test/TestSuite/Syntax/Errors/unsupported_token.tjp +1 -1
  515. data/test/TestSuite/TimeSheets/run +5 -5
  516. data/test/test_CSVFile.rb +75 -0
  517. data/test/test_Limits.rb +63 -5
  518. data/test/test_ProjectFileScanner.rb +163 -0
  519. data/test/test_ReportGenerator.rb +81 -0
  520. data/test/test_RichText.rb +21 -3
  521. data/test/test_Scheduler.rb +1 -1
  522. data/test/test_ShiftAssignments.rb +4 -4
  523. data/test/test_Syntax.rb +1 -1
  524. data/test/test_URLParameter.rb +30 -0
  525. metadata +126 -32
  526. data/test/TestSuite/Scheduler/Errors/not_scheduled.tjp +0 -8
  527. data/test/TestSuite/Syntax/Errors/bad_comment.tjp +0 -7
  528. data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/boss_2002-03-01.tji +0 -36
  529. data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/dev1_2002-03-01.tji +0 -48
  530. data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/dev2_2002-03-01.tji +0 -67
  531. data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/dev3_2002-03-01.tji +0 -67
  532. data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/doc_2002-03-01.tji +0 -48
  533. data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/resources.yml +0 -31
  534. data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/test_2002-03-01.tji +0 -36
  535. data/test/TestSuite/TimeSheets/TimeSheetTemplates/acceptable_intervals +0 -1
  536. data/test/TestSuite/TimeSheets/TimeSheets/2002-03-01/all.tji +0 -1
  537. data/test/TestSuite/TimeSheets/TimeSheets/2002-03-01/dev2_2002-03-01.tji +0 -54
  538. data/test/TestSuite/TimeSheets/TimeSheets/all.tji +0 -2
  539. data/test/TestSuite/TimeSheets/receiver.log +0 -102
  540. data/test/TestSuite/TimeSheets/sender.log +0 -794
  541. data/test/TestSuite/TimeSheets/summary.log +0 -884
  542. data/test/TestSuite/TimeSheets/timesheets.log +0 -45
  543. data/test/TestSuite/TimeSheets/tj3d.log +0 -292
  544. data/test/test_TextScanner.rb +0 -95
@@ -56,7 +56,7 @@ class TaskJuggler
56
56
  RichTextElement.new(@richTextI, :bulletlist1, @val[0])
57
57
  })
58
58
  pattern(%w( !numberList1 ), lambda {
59
- @numberListCounter = [ 0, 0, 0 ]
59
+ @numberListCounter = [ 0, 0, 0, 0 ]
60
60
  RichTextElement.new(@richTextI, :numberlist1, @val[0])
61
61
  })
62
62
  pattern(%w( !blockFunction !blankLines ), lambda {
@@ -74,12 +74,15 @@ class TaskJuggler
74
74
  pattern(%w( !title3 ), lambda {
75
75
  @val[0]
76
76
  })
77
+ pattern(%w( !title4 ), lambda {
78
+ @val[0]
79
+ })
77
80
  end
78
81
 
79
82
  def rule_title1
80
- pattern(%w( $TITLE1 !text $TITLE1END ), lambda {
81
- @val[1][-1].appendSpace = false
82
- el = RichTextElement.new(@richTextI, :title1, @val[1])
83
+ pattern(%w( $TITLE1 !space !text $TITLE1END ), lambda {
84
+ @val[2][-1].appendSpace = false
85
+ el = RichTextElement.new(@richTextI, :title1, @val[2])
83
86
  @sectionCounter[0] += 1
84
87
  @sectionCounter[1] = @sectionCounter[2] = 0
85
88
  el.data = @sectionCounter.dup
@@ -88,9 +91,9 @@ class TaskJuggler
88
91
  end
89
92
 
90
93
  def rule_title2
91
- pattern(%w( $TITLE2 !text $TITLE2END ), lambda {
92
- @val[1][-1].appendSpace = false
93
- el = RichTextElement.new(@richTextI, :title2, @val[1])
94
+ pattern(%w( $TITLE2 !space !text $TITLE2END ), lambda {
95
+ @val[2][-1].appendSpace = false
96
+ el = RichTextElement.new(@richTextI, :title2, @val[2])
94
97
  @sectionCounter[1] += 1
95
98
  @sectionCounter[2] = 0
96
99
  el.data = @sectionCounter.dup
@@ -99,10 +102,21 @@ class TaskJuggler
99
102
  end
100
103
 
101
104
  def rule_title3
102
- pattern(%w( $TITLE3 !text $TITLE3END ), lambda {
103
- @val[1][-1].appendSpace = false
104
- el = RichTextElement.new(@richTextI, :title3, @val[1])
105
+ pattern(%w( $TITLE3 !space !text $TITLE3END ), lambda {
106
+ @val[2][-1].appendSpace = false
107
+ el = RichTextElement.new(@richTextI, :title3, @val[2])
105
108
  @sectionCounter[2] += 1
109
+ @sectionCounter[3] = 0
110
+ el.data = @sectionCounter.dup
111
+ el
112
+ })
113
+ end
114
+
115
+ def rule_title4
116
+ pattern(%w( $TITLE4 !space !text $TITLE4END ), lambda {
117
+ @val[2][-1].appendSpace = false
118
+ el = RichTextElement.new(@richTextI, :title4, @val[2])
119
+ @sectionCounter[3] += 1
106
120
  el.data = @sectionCounter.dup
107
121
  el
108
122
  })
@@ -134,6 +148,16 @@ class TaskJuggler
134
148
  pattern(%w( $BULLET3 !text $LINEBREAK), lambda {
135
149
  RichTextElement.new(@richTextI, :bulletitem3, @val[1])
136
150
  })
151
+ pattern(%w( !bulletList4 ), lambda {
152
+ RichTextElement.new(@richTextI, :bulletlist4, @val[0])
153
+ })
154
+ end
155
+
156
+ def rule_bulletList4
157
+ repeatable
158
+ pattern(%w( $BULLET4 !text $LINEBREAK), lambda {
159
+ RichTextElement.new(@richTextI, :bulletitem4, @val[1])
160
+ })
137
161
  end
138
162
 
139
163
  def rule_numberList1
@@ -173,6 +197,20 @@ class TaskJuggler
173
197
  el.data = @numberListCounter.dup
174
198
  el
175
199
  })
200
+ pattern(%w( !numberList4 ), lambda {
201
+ @numberListCounter[3] = 0
202
+ RichTextElement.new(@richTextI, :numberlist4, @val[0])
203
+ })
204
+ end
205
+
206
+ def rule_numberList4
207
+ repeatable
208
+ pattern(%w( $NUMBER4 !text $LINEBREAK), lambda {
209
+ el = RichTextElement.new(@richTextI, :numberitem4, @val[1])
210
+ @numberListCounter[3] += 1
211
+ el.data = @numberListCounter.dup
212
+ el
213
+ })
176
214
  end
177
215
 
178
216
  def rule_paragraph
data/lib/ScenarioData.rb CHANGED
@@ -55,9 +55,11 @@ class TaskJuggler
55
55
  @project.sendMessage(message)
56
56
  end
57
57
 
58
- def query_id(query)
59
- query.sortable = query.string = @property.fullId
60
- end
58
+ # Not sure why this method was put there. If needed, it should in
59
+ # PropertyTreeNode!
60
+ #def query_id(query)
61
+ # query.sortable = query.string = @property.fullId
62
+ #end
61
63
 
62
64
  end
63
65
 
data/lib/SheetReceiver.rb CHANGED
@@ -39,11 +39,13 @@ class TaskJuggler
39
39
  @signatureFile = nil
40
40
  # The log file
41
41
  @logFile = nil
42
+ # The subject of the confirmation email
43
+ @emailSubject = nil
42
44
 
43
45
  # Regular expressions to identify a status sheet.
44
- @sheetHeader = /^[ ]*statussheet\s([a-z][a-z0-9_]*)\s([0-9]*-[0-9]*-[0-9]*)/
46
+ @sheetHeader = nil
45
47
  # Regular expression to extract the sheet signature (date).
46
- @signatureFilter = /^[ ]*statussheet\s[a-z][a-z0-9_]*\s([0-9:\-+]*)/
48
+ @signatureFilter = nil
47
49
  # The email address of the submitter of the sheet.
48
50
  @submitter = nil
49
51
  # The resource ID of the submitter.
@@ -73,7 +75,16 @@ class TaskJuggler
73
75
 
74
76
  createDirectories
75
77
 
76
- mail = Mail.new($stdin.read)
78
+ begin
79
+ rawMail = $stdin.read
80
+ mail = Mail.new(rawMail)
81
+ rescue
82
+ # Try to extract the mail sender the dirty way so we can at least send
83
+ # a response to the submitter.
84
+ fromLine = rawMail.match('^From: .*')[0]
85
+ @submitter = fromLine[6..-1] if fromLine.is_a?(String)
86
+ error("Incoming mail could not be processed: #{$!}")
87
+ end
77
88
 
78
89
  # Who sent this email?
79
90
  @submitter = mail.from.respond_to?('[]') ? mail.from[0] : mail.from
@@ -114,9 +125,16 @@ EOT
114
125
 
115
126
  # Isolate the actual syntax from _sheet_ and process it.
116
127
  def processSheet(sheet)
128
+ # Make sure the sheet is really valid UTF-8
129
+ begin
130
+ sheet.encode!('UTF-8')
131
+ rescue
132
+ error("The sheet contains badly encoded characters. #{$!}")
133
+ end
117
134
  # Store the detected sheet so we can include it with error reports if
118
135
  # needed.
119
- @sheet = cutOut(fixLineBreaks(sheet))
136
+ @sheet = fixLineBreaks(sheet)
137
+ @sheet = cutOut(@sheet) unless @sheetWasAttached
120
138
  # A valid sheet must have the poper header line.
121
139
  if @sheetHeader.match(@sheet)
122
140
  checkSignature(@sheet)
@@ -218,7 +236,7 @@ EOT
218
236
  text += @report
219
237
 
220
238
  # Send out the email.
221
- sendEmail(@submitter, "Report from #{getResourceName} for #{@date}", text,
239
+ sendEmail(@submitter, sprintf(@emailSubject, getResourceName, @date), text,
222
240
  nil, nil, @messageId)
223
241
  true
224
242
  end
@@ -294,7 +312,7 @@ EOT
294
312
  rescue
295
313
  end
296
314
 
297
- sendEmail(@submitter, 'Your time sheet submission failed!', message)
315
+ sendEmail(@submitter, "Your #{@sheetType} sheet submission failed!", message)
298
316
 
299
317
  exit 1
300
318
  end
data/lib/SheetSender.rb CHANGED
@@ -14,6 +14,7 @@ require 'open4'
14
14
  require 'mail'
15
15
  require 'yaml'
16
16
  require 'SheetHandlerBase'
17
+ require 'reports/CSVFile'
17
18
 
18
19
  class TaskJuggler
19
20
 
@@ -40,6 +41,9 @@ class TaskJuggler
40
41
  @force = false
41
42
 
42
43
  @signatureFilter = nil
44
+ # The subject of the template email.
45
+ @mailSubject = nil
46
+ # The into text of the template email.
43
47
  @introText = nil
44
48
 
45
49
  # The end date of the reported interval.
@@ -78,6 +82,9 @@ class TaskJuggler
78
82
  def genResourceList(resourceList)
79
83
  list = []
80
84
  info('Retrieving resource list...')
85
+ # Create a TJP report definition for a CSV report that contains the id,
86
+ # name, email, effort and free work for each resource that is not hidden
87
+ # by @hideResource.
81
88
  reportDef = <<"EOF"
82
89
  resourcereport rl_21497214 '.' {
83
90
  formats csv
@@ -89,19 +96,17 @@ resourcereport rl_21497214 '.' {
89
96
  }
90
97
  EOF
91
98
  report = generateReport('rl_21497214', reportDef)
92
- first = true
93
- report.each_line do |line|
94
- if first
95
- first = false
96
- next
97
- end
98
- id, name, email, effort, free = line.split(';')
99
- if email.empty?
99
+ # Parse the CSV report into an Array of Arrays
100
+ csv = CSVFile.new.parse(report)
101
+
102
+ # Get rid of the column title line
103
+ csv.delete_at(0)
104
+
105
+ # Process the CSV report line by line
106
+ csv.each do |id, name, email, effort, free|
107
+ if email.nil? || email.empty?
100
108
  error("Resource '#{id}' must have a valid email address")
101
109
  end
102
- # Convert effort and free values into Float objects.
103
- effort = effort.to_f
104
- free = free.to_f
105
110
 
106
111
  # Ignore resources that are on vacation for the whole period.
107
112
  if effort == 0.0 && free == 0.0
@@ -181,8 +186,7 @@ EOT
181
186
 
182
187
  message = " Hello #{name}!\n\n#{@introText}" + File.read(attachment)
183
188
 
184
- sendEmail(email, "Your weekly report template for #{@date}",
185
- message, attachment)
189
+ sendEmail(email, sprintf(@mailSubject, @date), message, attachment)
186
190
  end
187
191
  end
188
192
 
@@ -10,6 +10,7 @@
10
10
  # published by the Free Software Foundation.
11
11
  #
12
12
 
13
+ require 'monitor'
13
14
  require 'Scoreboard'
14
15
 
15
16
  class TaskJuggler
@@ -26,10 +27,8 @@ class TaskJuggler
26
27
  @interval = interval
27
28
  end
28
29
 
29
- # Returns true if the ShiftAssignment objects are similar enough.
30
- def ==(sa)
31
- return @shiftScenario.object_id == sa.shiftScenario.object_id &&
32
- @interval == sa.interval
30
+ def hashKey
31
+ return "#{@shiftScenario.object_id}|#{@interval.start}|#{@interval.end}"
33
32
  end
34
33
 
35
34
  # Return a deep copy of self.
@@ -91,28 +90,39 @@ class TaskJuggler
91
90
  # Bit 6: Reserved
92
91
  # Bit 7: 0: No global override
93
92
  # 1: Override global setting
94
- class ShiftAssignments
93
+ class ShiftAssignments < Monitor
95
94
 
96
95
  include ObjectSpace
97
96
 
98
- attr_reader :project, :assignments
97
+ attr_accessor :project
98
+ attr_reader :assignments
99
99
 
100
100
  # This class is sharing the Scoreboard instances for ShiftAssignments that
101
- # have identical assignement data. This class variable holds an array with
101
+ # have identical assignment data. This class variable holds a Hash with
102
102
  # records for each unique Scoreboard. A record is an array of references
103
103
  # to the owning ShiftAssignments objects and a reference to the Scoreboard
104
104
  # object.
105
- @@scoreboards = []
105
+ @@scoreboards = {}
106
106
 
107
107
  def initialize(sa = nil)
108
108
  define_finalizer(self, self.class.method(:deleteScoreboard).to_proc)
109
109
 
110
+ # An Array of ShiftAssignment objects.
110
111
  @assignments = []
112
+
113
+ # A String that uniquely identifies the content of this ShiftAssignment
114
+ # object.
115
+ @hashKey = nil
116
+
111
117
  if sa
118
+ # A ShiftAssignments object was passed to the contructor. We create a
119
+ # deep copy of it.
112
120
  @project = sa.project
113
121
  sa.assignments.each do |assignment|
114
122
  @assignments << assignment.copy
115
123
  end
124
+ # Create a new ScoreBoard or share one with a ShiftAssignments object
125
+ # that has the same set of shift assignments.
116
126
  @scoreboard = newScoreboard
117
127
  else
118
128
  @project = nil
@@ -120,11 +130,6 @@ class TaskJuggler
120
130
  end
121
131
  end
122
132
 
123
- # Some operations require access to the whole project.
124
- def setProject(project)
125
- @project = project
126
- end
127
-
128
133
  # Add a new assignment to the list. In case there was no overlap the
129
134
  # function returns true. Otherwise false.
130
135
  def addAssignment(shiftAssignment)
@@ -200,24 +205,12 @@ class TaskJuggler
200
205
  end
201
206
  end
202
207
 
203
- # Returns true if two ShiftAssignments object have the same assignment
204
- # pattern.
205
- def ==(shiftAssignments)
206
- return false if @assignments.size != shiftAssignments.assignments.size ||
207
- @project != shiftAssignments.project
208
-
209
- @assignments.size.times do |i|
210
- return false if @assignments[i] != shiftAssignments.assignments[i]
211
- end
212
- true
213
- end
214
-
215
208
  def ShiftAssignments.scoreboards
216
209
  @@scoreboards
217
210
  end
218
211
 
219
212
  def ShiftAssignments.sbClear
220
- @@scoreboards = []
213
+ @@scoreboards = {}
221
214
  end
222
215
 
223
216
  # This function is primarily used for debugging purposes.
@@ -237,52 +230,63 @@ class TaskJuggler
237
230
  out
238
231
  end
239
232
 
233
+ def hashKey
234
+ @hashKey if @hashKey
235
+
236
+ @hashKey = "#{@project.object_id}|"
237
+ @assignments.sort! { |a, b| a.interval.start <=> b.interval.start }
238
+ @assignments.each { |a| @hashKey += a.hashKey + '||' }
239
+ @hashKey
240
+ end
241
+
240
242
  private
241
243
 
242
244
  # This function either returns a new Scoreboard or a reference to an
243
245
  # existing one in case we already have one for the same assigment patterns.
244
246
  def newScoreboard
245
- @@scoreboards.each do |sbRecord|
246
- # We only have to look at the first ShiftAssignment for a comparison.
247
- # The others should match as well.
248
- if self == ObjectSpace._id2ref(sbRecord[0][0])
249
- # Register the ShiftAssignments object as a user of an existing
250
- # scoreboard. We have to store the object_id, not the reference. If
251
- # we'd store a reference, the GC will never destroy it.
252
- sbRecord[0] << object_id
253
- # Return a reference to the existing scoreboard.
254
- return sbRecord[1]
255
- end
247
+ if (record = @@scoreboards[hashKey])
248
+ # If we already have a Scoreboard object for the hashKey of this
249
+ # ShiftAssignments object, we can re-use this. We just need to
250
+ # register the object as a user of it.
251
+ record[0] << object_id
252
+
253
+ # Return the re-used Scoreboard object.
254
+ return record[1]
256
255
  end
256
+
257
257
  # We have not found a matching scoreboard, so we have to create a new one.
258
258
  newSb = Scoreboard.new(@project['start'], @project['end'],
259
259
  @project['scheduleGranularity'])
260
260
  # Create a new record for it and register the ShiftAssignments object as
261
- # first user.
262
- newRecord = [ [ object_id ], newSb ]
261
+ # first user. Add the record to the @@scoreboards list.
262
+ @@scoreboards[hashKey] = [ [ object_id ], newSb ]
263
+
263
264
  # Append the new record to the list.
264
- @@scoreboards << newRecord
265
265
  return newSb
266
266
  end
267
267
 
268
268
  # This function is called whenever a ShiftAssignments object gets destroyed
269
269
  # by the GC.
270
270
  def ShiftAssignments.deleteScoreboard(objId)
271
- # Attention: Due to the way this class is called, there will be no visible
272
- # exceptions here. All runtime errors will go unnoticed!
271
+ # Attention: Due to the way this class is called, there will be no
272
+ # visible exceptions here. All runtime errors will go unnoticed!
273
273
  #
274
- # Well search the @@scoreboards for an entry that holds a reference to the
275
- # deleted ShiftAssignments object. If it's the last in the record, we
276
- # delete the whole record. If not, we'll just remove it form the record.
277
- @@scoreboards.each do |sbRecord|
278
- assignmentObjectIDs = sbRecord[0]
279
- assignmentObjectIDs.delete_if { |id| id == objId }
280
- # No more ShiftAssignments in this record. Delete it from the list.
281
- break if assignmentObjectIDs.empty?
274
+ # We'll search the @@scoreboards for an entry that holds a reference to
275
+ # the deleted ShiftAssignments object. If it's the last in the record,
276
+ # we delete the whole record. If not, we'll just remove the reference
277
+ # form the record.
278
+ @@scoreboards.each_value do |record|
279
+ if record[0].include?(objId)
280
+ # Remove the ShiftAssignments object as user of this Scoreboard
281
+ # object.
282
+ record[0].delete(objId)
283
+ # We've found what we were looking for.
284
+ break
285
+ end
282
286
  end
287
+
283
288
  # Delete all entries which have empty reference lists.
284
- @@scoreboards.delete_if { |sbRecord| sbRecord[0].empty? }
285
- ObjectSpace.undefine_finalizer(self)
289
+ @@scoreboards.delete_if { |key, record| record[0].empty? }
286
290
  end
287
291
 
288
292
  # Returns true if the interval overlaps with any of the assignment periods.
@@ -37,6 +37,7 @@ class TaskJuggler
37
37
  @sheetHeader = /^[ ]*statussheet\s([a-z][a-z0-9_]*)\s[0-9\-:+]*\s-\s([0-9]*-[0-9]*-[0-9]*)/
38
38
  # Regular expression to extract the sheet signature (time period).
39
39
  @signatureFilter = /^[ ]*statussheet\s[a-z][a-z0-9_]*\s([0-9:\-+]*\s-\s[0-9:\-+]*)/
40
+ @emailSubject = "Status report from %s for %s"
40
41
  end
41
42
 
42
43
  end