taskjuggler 0.0.2

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 (571) hide show
  1. data/COPYING +280 -0
  2. data/README +31 -0
  3. data/Rakefile +20 -0
  4. data/benchmarks/UTF-8-Strings.rb +58 -0
  5. data/benchmarks/allocate.tjp +30 -0
  6. data/benchmarks/booking.tjp +62 -0
  7. data/benchmarks/depends.tjp +112 -0
  8. data/benchmarks/htmltaskreport.tjp +45 -0
  9. data/benchmarks/runbench.rb +24 -0
  10. data/bin/tj3 +3 -0
  11. data/bin/tj3man +3 -0
  12. data/doc/classes/AppConfig.html +808 -0
  13. data/doc/classes/Arguments.html +226 -0
  14. data/doc/classes/String.html +395 -0
  15. data/doc/classes/TaskJuggler.html +1358 -0
  16. data/doc/classes/TaskJuggler/Account.html +257 -0
  17. data/doc/classes/TaskJuggler/AccountScenario.html +218 -0
  18. data/doc/classes/TaskJuggler/Allocation.html +419 -0
  19. data/doc/classes/TaskJuggler/AllocationAttribute.html +291 -0
  20. data/doc/classes/TaskJuggler/AttributeBase.html +608 -0
  21. data/doc/classes/TaskJuggler/AttributeDefinition.html +259 -0
  22. data/doc/classes/TaskJuggler/Booking.html +307 -0
  23. data/doc/classes/TaskJuggler/BookingListAttribute.html +263 -0
  24. data/doc/classes/TaskJuggler/BooleanAttribute.html +261 -0
  25. data/doc/classes/TaskJuggler/CSVFile.html +325 -0
  26. data/doc/classes/TaskJuggler/Charge.html +279 -0
  27. data/doc/classes/TaskJuggler/ChargeListAttribute.html +229 -0
  28. data/doc/classes/TaskJuggler/ChargeSet.html +440 -0
  29. data/doc/classes/TaskJuggler/ChargeSetListAttribute.html +276 -0
  30. data/doc/classes/TaskJuggler/ColumnTable.html +260 -0
  31. data/doc/classes/TaskJuggler/DateAttribute.html +194 -0
  32. data/doc/classes/TaskJuggler/DependencyListAttribute.html +267 -0
  33. data/doc/classes/TaskJuggler/DurationAttribute.html +229 -0
  34. data/doc/classes/TaskJuggler/FixnumAttribute.html +194 -0
  35. data/doc/classes/TaskJuggler/FlagListAttribute.html +263 -0
  36. data/doc/classes/TaskJuggler/FloatAttribute.html +229 -0
  37. data/doc/classes/TaskJuggler/GanttChart.html +667 -0
  38. data/doc/classes/TaskJuggler/GanttContainer.html +441 -0
  39. data/doc/classes/TaskJuggler/GanttHeader.html +280 -0
  40. data/doc/classes/TaskJuggler/GanttHeaderScaleItem.html +245 -0
  41. data/doc/classes/TaskJuggler/GanttLine.html +398 -0
  42. data/doc/classes/TaskJuggler/GanttLoadStack.html +327 -0
  43. data/doc/classes/TaskJuggler/GanttMilestone.html +415 -0
  44. data/doc/classes/TaskJuggler/GanttRouter.html +425 -0
  45. data/doc/classes/TaskJuggler/GanttTaskBar.html +429 -0
  46. data/doc/classes/TaskJuggler/HTMLDocument.html +240 -0
  47. data/doc/classes/TaskJuggler/HTMLGraphics.html +231 -0
  48. data/doc/classes/TaskJuggler/Interval.html +552 -0
  49. data/doc/classes/TaskJuggler/IntervalListAttribute.html +267 -0
  50. data/doc/classes/TaskJuggler/KeywordDocumentation.html +796 -0
  51. data/doc/classes/TaskJuggler/Limits.html +416 -0
  52. data/doc/classes/TaskJuggler/Limits/Limit.html +381 -0
  53. data/doc/classes/TaskJuggler/LimitsAttribute.html +261 -0
  54. data/doc/classes/TaskJuggler/Log.html +613 -0
  55. data/doc/classes/TaskJuggler/LogicalAttribute.html +226 -0
  56. data/doc/classes/TaskJuggler/LogicalExpression.html +251 -0
  57. data/doc/classes/TaskJuggler/LogicalFlag.html +229 -0
  58. data/doc/classes/TaskJuggler/LogicalFunction.html +324 -0
  59. data/doc/classes/TaskJuggler/LogicalOperation.html +299 -0
  60. data/doc/classes/TaskJuggler/Macro.html +194 -0
  61. data/doc/classes/TaskJuggler/MacroParser.html +360 -0
  62. data/doc/classes/TaskJuggler/MacroTable.html +366 -0
  63. data/doc/classes/TaskJuggler/Message.html +281 -0
  64. data/doc/classes/TaskJuggler/MessageHandler.html +215 -0
  65. data/doc/classes/TaskJuggler/Project.html +1606 -0
  66. data/doc/classes/TaskJuggler/ProjectFileParser.html +412 -0
  67. data/doc/classes/TaskJuggler/PropertyList.html +597 -0
  68. data/doc/classes/TaskJuggler/PropertySet.html +1200 -0
  69. data/doc/classes/TaskJuggler/PropertyTreeNode.html +1449 -0
  70. data/doc/classes/TaskJuggler/Query.html +600 -0
  71. data/doc/classes/TaskJuggler/RealFormat.html +252 -0
  72. data/doc/classes/TaskJuggler/ReferenceAttribute.html +194 -0
  73. data/doc/classes/TaskJuggler/Report.html +528 -0
  74. data/doc/classes/TaskJuggler/ReportElement.html +1070 -0
  75. data/doc/classes/TaskJuggler/ReportTable.html +497 -0
  76. data/doc/classes/TaskJuggler/ReportTableCell.html +518 -0
  77. data/doc/classes/TaskJuggler/ReportTableColumn.html +364 -0
  78. data/doc/classes/TaskJuggler/ReportTableElement.html +644 -0
  79. data/doc/classes/TaskJuggler/ReportTableLegend.html +343 -0
  80. data/doc/classes/TaskJuggler/ReportTableLine.html +431 -0
  81. data/doc/classes/TaskJuggler/Resource.html +211 -0
  82. data/doc/classes/TaskJuggler/ResourceListAttribute.html +267 -0
  83. data/doc/classes/TaskJuggler/ResourceListRE.html +249 -0
  84. data/doc/classes/TaskJuggler/ResourceScenario.html +1137 -0
  85. data/doc/classes/TaskJuggler/RichText.html +537 -0
  86. data/doc/classes/TaskJuggler/RichTextAttribute.html +229 -0
  87. data/doc/classes/TaskJuggler/RichTextDocument.html +418 -0
  88. data/doc/classes/TaskJuggler/RichTextElement.html +829 -0
  89. data/doc/classes/TaskJuggler/RichTextException.html +212 -0
  90. data/doc/classes/TaskJuggler/RichTextParser.html +317 -0
  91. data/doc/classes/TaskJuggler/RichTextProtocolExample.html +303 -0
  92. data/doc/classes/TaskJuggler/RichTextProtocolHandler.html +194 -0
  93. data/doc/classes/TaskJuggler/RichTextScanner.html +561 -0
  94. data/doc/classes/TaskJuggler/RichTextSnip.html +364 -0
  95. data/doc/classes/TaskJuggler/RichTextSyntaxRules.html +883 -0
  96. data/doc/classes/TaskJuggler/Scenario.html +163 -0
  97. data/doc/classes/TaskJuggler/ScenarioData.html +354 -0
  98. data/doc/classes/TaskJuggler/Scoreboard.html +638 -0
  99. data/doc/classes/TaskJuggler/Shift.html +255 -0
  100. data/doc/classes/TaskJuggler/ShiftAssignment.html +488 -0
  101. data/doc/classes/TaskJuggler/ShiftAssignments.html +715 -0
  102. data/doc/classes/TaskJuggler/ShiftAssignmentsAttribute.html +261 -0
  103. data/doc/classes/TaskJuggler/ShiftScenario.html +282 -0
  104. data/doc/classes/TaskJuggler/SourceFileInfo.html +247 -0
  105. data/doc/classes/TaskJuggler/StringAttribute.html +229 -0
  106. data/doc/classes/TaskJuggler/SymbolAttribute.html +194 -0
  107. data/doc/classes/TaskJuggler/SyntaxReference.html +516 -0
  108. data/doc/classes/TaskJuggler/TOCEntry.html +242 -0
  109. data/doc/classes/TaskJuggler/TableColumnDefinition.html +273 -0
  110. data/doc/classes/TaskJuggler/TableOfContents.html +256 -0
  111. data/doc/classes/TaskJuggler/Task.html +203 -0
  112. data/doc/classes/TaskJuggler/TaskDependency.html +251 -0
  113. data/doc/classes/TaskJuggler/TaskListAttribute.html +267 -0
  114. data/doc/classes/TaskJuggler/TaskListRE.html +250 -0
  115. data/doc/classes/TaskJuggler/TaskScenario.html +2206 -0
  116. data/doc/classes/TaskJuggler/TextParser.html +670 -0
  117. data/doc/classes/TaskJuggler/TextParser/Pattern.html +923 -0
  118. data/doc/classes/TaskJuggler/TextParser/Rule.html +779 -0
  119. data/doc/classes/TaskJuggler/TextParser/StackElement.html +267 -0
  120. data/doc/classes/TaskJuggler/TextParser/TextParserResultArray.html +212 -0
  121. data/doc/classes/TaskJuggler/TextParser/TokenDoc.html +221 -0
  122. data/doc/classes/TaskJuggler/TextScanner.html +708 -0
  123. data/doc/classes/TaskJuggler/TextScanner/BufferStreamHandle.html +355 -0
  124. data/doc/classes/TaskJuggler/TextScanner/FileStreamHandle.html +341 -0
  125. data/doc/classes/TaskJuggler/TextScanner/StreamHandle.html +260 -0
  126. data/doc/classes/TaskJuggler/TjException.html +185 -0
  127. data/doc/classes/TaskJuggler/TjTime.html +1845 -0
  128. data/doc/classes/TaskJuggler/TjpExample.html +310 -0
  129. data/doc/classes/TaskJuggler/TjpExportRE.html +329 -0
  130. data/doc/classes/TaskJuggler/TjpSyntaxRules.html +8928 -0
  131. data/doc/classes/TaskJuggler/UserManual.html +606 -0
  132. data/doc/classes/TaskJuggler/WorkingHours.html +582 -0
  133. data/doc/classes/TaskJuggler/WorkingHoursAttribute.html +284 -0
  134. data/doc/classes/TaskJuggler/XMLBlob.html +207 -0
  135. data/doc/classes/TaskJuggler/XMLComment.html +206 -0
  136. data/doc/classes/TaskJuggler/XMLDocument.html +293 -0
  137. data/doc/classes/TaskJuggler/XMLElement.html +341 -0
  138. data/doc/classes/TaskJuggler/XMLNamedText.html +174 -0
  139. data/doc/classes/TaskJuggler/XMLText.html +221 -0
  140. data/doc/files/COPYING.html +448 -0
  141. data/doc/files/README.html +134 -0
  142. data/doc/files/lib/AccountScenario_rb.html +116 -0
  143. data/doc/files/lib/Account_rb.html +118 -0
  144. data/doc/files/lib/Allocation_rb.html +118 -0
  145. data/doc/files/lib/AppConfig_rb.html +116 -0
  146. data/doc/files/lib/AttributeBase_rb.html +106 -0
  147. data/doc/files/lib/AttributeDefinition_rb.html +106 -0
  148. data/doc/files/lib/Attributes_rb.html +130 -0
  149. data/doc/files/lib/Booking_rb.html +106 -0
  150. data/doc/files/lib/ChargeSet_rb.html +116 -0
  151. data/doc/files/lib/Charge_rb.html +116 -0
  152. data/doc/files/lib/HTMLDocument_rb.html +116 -0
  153. data/doc/files/lib/Interval_rb.html +116 -0
  154. data/doc/files/lib/KeywordDocumentation_rb.html +122 -0
  155. data/doc/files/lib/Limits_rb.html +116 -0
  156. data/doc/files/lib/Log_rb.html +116 -0
  157. data/doc/files/lib/LogicalExpression_rb.html +122 -0
  158. data/doc/files/lib/LogicalFlag_rb.html +116 -0
  159. data/doc/files/lib/LogicalFunction_rb.html +116 -0
  160. data/doc/files/lib/LogicalOperation_rb.html +116 -0
  161. data/doc/files/lib/MacroParser_rb.html +118 -0
  162. data/doc/files/lib/MacroTable_rb.html +122 -0
  163. data/doc/files/lib/MessageHandler_rb.html +106 -0
  164. data/doc/files/lib/Message_rb.html +116 -0
  165. data/doc/files/lib/ProjectFileParser_rb.html +122 -0
  166. data/doc/files/lib/Project_rb.html +148 -0
  167. data/doc/files/lib/PropertyList_rb.html +106 -0
  168. data/doc/files/lib/PropertySet_rb.html +118 -0
  169. data/doc/files/lib/PropertyTreeNode_rb.html +106 -0
  170. data/doc/files/lib/Query_rb.html +116 -0
  171. data/doc/files/lib/RealFormat_rb.html +106 -0
  172. data/doc/files/lib/ResourceScenario_rb.html +116 -0
  173. data/doc/files/lib/Resource_rb.html +118 -0
  174. data/doc/files/lib/RichTextDocument_rb.html +120 -0
  175. data/doc/files/lib/RichTextElement_rb.html +120 -0
  176. data/doc/files/lib/RichTextParser_rb.html +120 -0
  177. data/doc/files/lib/RichTextProtocolExample_rb.html +120 -0
  178. data/doc/files/lib/RichTextProtocolHandler_rb.html +106 -0
  179. data/doc/files/lib/RichTextScanner_rb.html +116 -0
  180. data/doc/files/lib/RichTextSnip_rb.html +118 -0
  181. data/doc/files/lib/RichTextSyntaxRules_rb.html +106 -0
  182. data/doc/files/lib/RichText_rb.html +118 -0
  183. data/doc/files/lib/ScenarioData_rb.html +118 -0
  184. data/doc/files/lib/Scenario_rb.html +116 -0
  185. data/doc/files/lib/Scoreboard_rb.html +106 -0
  186. data/doc/files/lib/ShiftAssignments_rb.html +116 -0
  187. data/doc/files/lib/ShiftScenario_rb.html +116 -0
  188. data/doc/files/lib/Shift_rb.html +118 -0
  189. data/doc/files/lib/SourceFileInfo_rb.html +106 -0
  190. data/doc/files/lib/SyntaxReference_rb.html +122 -0
  191. data/doc/files/lib/TOCEntry_rb.html +118 -0
  192. data/doc/files/lib/TableColumnDefinition_rb.html +106 -0
  193. data/doc/files/lib/TableOfContents_rb.html +118 -0
  194. data/doc/files/lib/TaskDependency_rb.html +106 -0
  195. data/doc/files/lib/TaskJuggler_rb.html +120 -0
  196. data/doc/files/lib/TaskScenario_rb.html +116 -0
  197. data/doc/files/lib/Task_rb.html +118 -0
  198. data/doc/files/lib/TextParser/Pattern_rb.html +116 -0
  199. data/doc/files/lib/TextParser/Rule_rb.html +106 -0
  200. data/doc/files/lib/TextParser/StackElement_rb.html +106 -0
  201. data/doc/files/lib/TextParser/TokenDoc_rb.html +106 -0
  202. data/doc/files/lib/TextParser_rb.html +124 -0
  203. data/doc/files/lib/TextScanner_rb.html +128 -0
  204. data/doc/files/lib/Tj3Config_rb.html +118 -0
  205. data/doc/files/lib/TjException_rb.html +106 -0
  206. data/doc/files/lib/TjTime_rb.html +118 -0
  207. data/doc/files/lib/TjpExample_rb.html +116 -0
  208. data/doc/files/lib/TjpSyntaxRules_rb.html +106 -0
  209. data/doc/files/lib/UTF8String_rb.html +132 -0
  210. data/doc/files/lib/UserManual_rb.html +124 -0
  211. data/doc/files/lib/WorkingHours_rb.html +116 -0
  212. data/doc/files/lib/XMLDocument_rb.html +116 -0
  213. data/doc/files/lib/XMLElement_rb.html +116 -0
  214. data/doc/files/lib/reports/CSVFile_rb.html +116 -0
  215. data/doc/files/lib/reports/ColumnTable_rb.html +116 -0
  216. data/doc/files/lib/reports/GanttChart_rb.html +122 -0
  217. data/doc/files/lib/reports/GanttContainer_rb.html +116 -0
  218. data/doc/files/lib/reports/GanttHeaderScaleItem_rb.html +106 -0
  219. data/doc/files/lib/reports/GanttHeader_rb.html +116 -0
  220. data/doc/files/lib/reports/GanttLine_rb.html +126 -0
  221. data/doc/files/lib/reports/GanttLoadStack_rb.html +116 -0
  222. data/doc/files/lib/reports/GanttMilestone_rb.html +116 -0
  223. data/doc/files/lib/reports/GanttRouter_rb.html +106 -0
  224. data/doc/files/lib/reports/GanttTaskBar_rb.html +116 -0
  225. data/doc/files/lib/reports/HTMLGraphics_rb.html +106 -0
  226. data/doc/files/lib/reports/ReportElement_rb.html +118 -0
  227. data/doc/files/lib/reports/ReportTableCell_rb.html +106 -0
  228. data/doc/files/lib/reports/ReportTableColumn_rb.html +106 -0
  229. data/doc/files/lib/reports/ReportTableElement_rb.html +122 -0
  230. data/doc/files/lib/reports/ReportTableLegend_rb.html +106 -0
  231. data/doc/files/lib/reports/ReportTableLine_rb.html +116 -0
  232. data/doc/files/lib/reports/ReportTable_rb.html +118 -0
  233. data/doc/files/lib/reports/Report_rb.html +126 -0
  234. data/doc/files/lib/reports/ResourceListRE_rb.html +122 -0
  235. data/doc/files/lib/reports/TaskListRE_rb.html +122 -0
  236. data/doc/files/lib/reports/TjpExportRE_rb.html +116 -0
  237. data/doc/files/lib/taskjuggler3_rb.html +276 -0
  238. data/doc/files/lib/tj3man_rb.html +189 -0
  239. data/doc/fr_class_index.html +285 -0
  240. data/doc/fr_file_index.html +223 -0
  241. data/doc/fr_method_index.html +1953 -0
  242. data/doc/index.html +21 -0
  243. data/doc/rdoc-style.css +299 -0
  244. data/examples/tutorial.tjp +361 -0
  245. data/gem_spec.rb +30 -0
  246. data/lib/Account.rb +50 -0
  247. data/lib/AccountScenario.rb +39 -0
  248. data/lib/Allocation.rb +102 -0
  249. data/lib/AppConfig.rb +134 -0
  250. data/lib/AttributeBase.rb +131 -0
  251. data/lib/AttributeDefinition.rb +47 -0
  252. data/lib/Attributes.rb +478 -0
  253. data/lib/BatchProcessor.rb +209 -0
  254. data/lib/Booking.rb +59 -0
  255. data/lib/Charge.rb +71 -0
  256. data/lib/ChargeSet.rb +126 -0
  257. data/lib/HTMLDocument.rb +59 -0
  258. data/lib/Interval.rb +127 -0
  259. data/lib/KeywordDocumentation.rb +560 -0
  260. data/lib/Limits.rb +219 -0
  261. data/lib/Log.rb +160 -0
  262. data/lib/LogicalExpression.rb +71 -0
  263. data/lib/LogicalFlag.rb +34 -0
  264. data/lib/LogicalFunction.rb +102 -0
  265. data/lib/LogicalOperation.rb +118 -0
  266. data/lib/MacroParser.rb +77 -0
  267. data/lib/MacroTable.rb +84 -0
  268. data/lib/Message.rb +56 -0
  269. data/lib/MessageHandler.rb +34 -0
  270. data/lib/Project.rb +662 -0
  271. data/lib/ProjectFileParser.rb +333 -0
  272. data/lib/PropertyList.rb +181 -0
  273. data/lib/PropertySet.rb +304 -0
  274. data/lib/PropertyTreeNode.rb +461 -0
  275. data/lib/Query.rb +227 -0
  276. data/lib/RealFormat.rb +73 -0
  277. data/lib/Resource.rb +42 -0
  278. data/lib/ResourceScenario.rb +511 -0
  279. data/lib/RichText.rb +147 -0
  280. data/lib/RichTextDocument.rb +139 -0
  281. data/lib/RichTextElement.rb +391 -0
  282. data/lib/RichTextParser.rb +66 -0
  283. data/lib/RichTextProtocolExample.rb +65 -0
  284. data/lib/RichTextProtocolHandler.rb +35 -0
  285. data/lib/RichTextScanner.rb +390 -0
  286. data/lib/RichTextSnip.rb +104 -0
  287. data/lib/RichTextSyntaxRules.rb +265 -0
  288. data/lib/Scenario.rb +27 -0
  289. data/lib/ScenarioData.rb +65 -0
  290. data/lib/Scoreboard.rb +141 -0
  291. data/lib/Shift.rb +48 -0
  292. data/lib/ShiftAssignments.rb +291 -0
  293. data/lib/ShiftScenario.rb +46 -0
  294. data/lib/SourceFileInfo.rb +37 -0
  295. data/lib/SyntaxReference.rb +284 -0
  296. data/lib/TOCEntry.rb +76 -0
  297. data/lib/TableColumnDefinition.rb +54 -0
  298. data/lib/TableOfContents.rb +46 -0
  299. data/lib/Task.rb +37 -0
  300. data/lib/TaskDependency.rb +39 -0
  301. data/lib/TaskJuggler.rb +84 -0
  302. data/lib/TaskScenario.rb +1622 -0
  303. data/lib/TextParser.rb +416 -0
  304. data/lib/TextParser/Pattern.rb +263 -0
  305. data/lib/TextParser/Rule.rb +171 -0
  306. data/lib/TextParser/StackElement.rb +45 -0
  307. data/lib/TextParser/TokenDoc.rb +38 -0
  308. data/lib/TextScanner.rb +682 -0
  309. data/lib/Tj3Config.rb +27 -0
  310. data/lib/TjException.rb +27 -0
  311. data/lib/TjTime.rb +395 -0
  312. data/lib/TjpExample.rb +119 -0
  313. data/lib/TjpSyntaxRules.rb +4022 -0
  314. data/lib/UTF8String.rb +100 -0
  315. data/lib/UserManual.rb +282 -0
  316. data/lib/WorkingHours.rb +323 -0
  317. data/lib/XMLDocument.rb +54 -0
  318. data/lib/XMLElement.rb +175 -0
  319. data/lib/reports/CSVFile.rb +146 -0
  320. data/lib/reports/ColumnTable.rb +66 -0
  321. data/lib/reports/GanttChart.rb +308 -0
  322. data/lib/reports/GanttContainer.rb +107 -0
  323. data/lib/reports/GanttHeader.rb +141 -0
  324. data/lib/reports/GanttHeaderScaleItem.rb +42 -0
  325. data/lib/reports/GanttLine.rb +329 -0
  326. data/lib/reports/GanttLoadStack.rb +113 -0
  327. data/lib/reports/GanttMilestone.rb +80 -0
  328. data/lib/reports/GanttRouter.rb +375 -0
  329. data/lib/reports/GanttTaskBar.rb +95 -0
  330. data/lib/reports/HTMLGraphics.rb +65 -0
  331. data/lib/reports/Report.rb +344 -0
  332. data/lib/reports/ReportElement.rb +427 -0
  333. data/lib/reports/ReportTable.rb +144 -0
  334. data/lib/reports/ReportTableCell.rb +142 -0
  335. data/lib/reports/ReportTableColumn.rb +82 -0
  336. data/lib/reports/ReportTableElement.rb +852 -0
  337. data/lib/reports/ReportTableLegend.rb +167 -0
  338. data/lib/reports/ReportTableLine.rb +87 -0
  339. data/lib/reports/ResourceListRE.rb +72 -0
  340. data/lib/reports/TaskListRE.rb +73 -0
  341. data/lib/reports/TjpExportRE.rb +394 -0
  342. data/lib/taskjuggler3.rb +106 -0
  343. data/lib/tj3man.rb +88 -0
  344. data/manual/Day_To_Day_Juggling +168 -0
  345. data/manual/Getting_Started +61 -0
  346. data/manual/How_To_Contribute +185 -0
  347. data/manual/Installation +68 -0
  348. data/manual/Intro +102 -0
  349. data/manual/Reporting_Bugs +26 -0
  350. data/manual/Rich_Text_Attributes +90 -0
  351. data/manual/TaskJuggler_2x_Migration +40 -0
  352. data/manual/Tutorial +579 -0
  353. data/manual/fdl +450 -0
  354. data/prj_cfg.rb +43 -0
  355. data/setup.rb +1585 -0
  356. data/tasks/csts.rake +72 -0
  357. data/tasks/gem.rake +14 -0
  358. data/tasks/manual.rake +10 -0
  359. data/tasks/missing.rake +21 -0
  360. data/tasks/rcov.rake +14 -0
  361. data/tasks/rdoc.rake +17 -0
  362. data/tasks/rexml_fix.rb +16 -0
  363. data/tasks/rexml_fix_19.rb +49 -0
  364. data/tasks/show.rake +21 -0
  365. data/tasks/stats.rake +25 -0
  366. data/tasks/test.rake +11 -0
  367. data/test/MessageChecker.rb +53 -0
  368. data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -0
  369. data/test/TestSuite/CSV-Reports/celltext.tjp +7 -0
  370. data/test/TestSuite/CSV-Reports/genrefs +6 -0
  371. data/test/TestSuite/CSV-Reports/project-1.tji +57 -0
  372. data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -0
  373. data/test/TestSuite/CSV-Reports/resourcereport.tjp +10 -0
  374. data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -0
  375. data/test/TestSuite/CSV-Reports/resourcereport_with_tasks.tjp +11 -0
  376. data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -0
  377. data/test/TestSuite/CSV-Reports/sortByTree.tjp +8 -0
  378. data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -0
  379. data/test/TestSuite/CSV-Reports/sortBy_duration.down.tjp +10 -0
  380. data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -0
  381. data/test/TestSuite/CSV-Reports/sortBy_effort.up.tjp +10 -0
  382. data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -0
  383. data/test/TestSuite/CSV-Reports/sortBy_plan.start.down.tjp +10 -0
  384. data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -0
  385. data/test/TestSuite/CSV-Reports/taskreport.tjp +10 -0
  386. data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +24 -0
  387. data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +11 -0
  388. data/test/TestSuite/Scheduler/Correct/Allocate.tjp +86 -0
  389. data/test/TestSuite/Scheduler/Correct/AutomaticMilestones.tjp +63 -0
  390. data/test/TestSuite/Scheduler/Correct/Booking.tjp +161 -0
  391. data/test/TestSuite/Scheduler/Correct/Depends.tjp +50 -0
  392. data/test/TestSuite/Scheduler/Correct/Duration.tjp +34 -0
  393. data/test/TestSuite/Scheduler/Correct/InheritStartEnd.tjp +129 -0
  394. data/test/TestSuite/Scheduler/Correct/Limits.tjp +81 -0
  395. data/test/TestSuite/Scheduler/Correct/MultipleMandatories.tjp +43 -0
  396. data/test/TestSuite/Scheduler/Correct/Optimize-1.tjp +28 -0
  397. data/test/TestSuite/Scheduler/Correct/Optimize-2.tjp +33 -0
  398. data/test/TestSuite/Scheduler/Correct/Optimize-3.tjp +33 -0
  399. data/test/TestSuite/Scheduler/Correct/Optimize-4.tjp +34 -0
  400. data/test/TestSuite/Scheduler/Correct/Optimize-5.tjp +62 -0
  401. data/test/TestSuite/Scheduler/Correct/Precedes.tjp +50 -0
  402. data/test/TestSuite/Scheduler/Correct/Shift.tjp +102 -0
  403. data/test/TestSuite/Scheduler/Errors/account_no_leaf.tjp +13 -0
  404. data/test/TestSuite/Scheduler/Errors/booking_conflict.tjp +10 -0
  405. data/test/TestSuite/Scheduler/Errors/booking_no_duty.tjp +9 -0
  406. data/test/TestSuite/Scheduler/Errors/booking_on_vacation.tjp +9 -0
  407. data/test/TestSuite/Scheduler/Errors/container_booking.tjp +14 -0
  408. data/test/TestSuite/Scheduler/Errors/container_duration.tjp +11 -0
  409. data/test/TestSuite/Scheduler/Errors/effort_no_allocations.tjp +7 -0
  410. data/test/TestSuite/Scheduler/Errors/loop_detected_1.tjp +19 -0
  411. data/test/TestSuite/Scheduler/Errors/loop_detected_10.tjp +36 -0
  412. data/test/TestSuite/Scheduler/Errors/loop_detected_11.tjp +27 -0
  413. data/test/TestSuite/Scheduler/Errors/loop_detected_12.tjp +20 -0
  414. data/test/TestSuite/Scheduler/Errors/loop_detected_13.tjp +27 -0
  415. data/test/TestSuite/Scheduler/Errors/loop_detected_14.tjp +26 -0
  416. data/test/TestSuite/Scheduler/Errors/loop_detected_2.tjp +24 -0
  417. data/test/TestSuite/Scheduler/Errors/loop_detected_3.tjp +18 -0
  418. data/test/TestSuite/Scheduler/Errors/loop_detected_4.tjp +36 -0
  419. data/test/TestSuite/Scheduler/Errors/loop_detected_5.tjp +37 -0
  420. data/test/TestSuite/Scheduler/Errors/loop_detected_6.tjp +35 -0
  421. data/test/TestSuite/Scheduler/Errors/loop_detected_7.tjp +46 -0
  422. data/test/TestSuite/Scheduler/Errors/loop_detected_8.tjp +51 -0
  423. data/test/TestSuite/Scheduler/Errors/loop_detected_9.tjp +20 -0
  424. data/test/TestSuite/Scheduler/Errors/maxend.tjp +8 -0
  425. data/test/TestSuite/Scheduler/Errors/maxstart.tjp +8 -0
  426. data/test/TestSuite/Scheduler/Errors/milestone_booking.tjp +10 -0
  427. data/test/TestSuite/Scheduler/Errors/milestone_duration.tjp +8 -0
  428. data/test/TestSuite/Scheduler/Errors/milestone_start_end.tjp +8 -0
  429. data/test/TestSuite/Scheduler/Errors/minend.tjp +8 -0
  430. data/test/TestSuite/Scheduler/Errors/minstart.tjp +8 -0
  431. data/test/TestSuite/Scheduler/Errors/multiple_durations.tjp +11 -0
  432. data/test/TestSuite/Scheduler/Errors/no_tasks.tjp +6 -0
  433. data/test/TestSuite/Scheduler/Errors/not_scheduled.tjp +8 -0
  434. data/test/TestSuite/Scheduler/Errors/task_depend_child.tjp +10 -0
  435. data/test/TestSuite/Scheduler/Errors/task_depend_multi.tjp +13 -0
  436. data/test/TestSuite/Scheduler/Errors/task_depend_parent.tjp +11 -0
  437. data/test/TestSuite/Scheduler/Errors/task_depend_self.tjp +10 -0
  438. data/test/TestSuite/Scheduler/Errors/task_depend_unknown.tjp +10 -0
  439. data/test/TestSuite/Scheduler/Errors/task_overspecified_1.tjp +9 -0
  440. data/test/TestSuite/Scheduler/Errors/task_overspecified_2.tjp +14 -0
  441. data/test/TestSuite/Scheduler/Errors/task_overspecified_3.tjp +14 -0
  442. data/test/TestSuite/Scheduler/Errors/task_underspecified_1.tjp +8 -0
  443. data/test/TestSuite/Scheduler/Errors/task_underspecified_2.tjp +8 -0
  444. data/test/TestSuite/Scheduler/Errors/task_underspecified_3.tjp +9 -0
  445. data/test/TestSuite/Syntax/Correct/Account.tjp +53 -0
  446. data/test/TestSuite/Syntax/Correct/Allocate-1.tjp +24 -0
  447. data/test/TestSuite/Syntax/Correct/Alternative.tjp +13 -0
  448. data/test/TestSuite/Syntax/Correct/AutoMacros.tjp +14 -0
  449. data/test/TestSuite/Syntax/Correct/Booking.tjp +26 -0
  450. data/test/TestSuite/Syntax/Correct/Caption.tjp +33 -0
  451. data/test/TestSuite/Syntax/Correct/Celltext.tjp +28 -0
  452. data/test/TestSuite/Syntax/Correct/Comments.tjp +29 -0
  453. data/test/TestSuite/Syntax/Correct/Complete.tjp +16 -0
  454. data/test/TestSuite/Syntax/Correct/CompletedWork.tji +20 -0
  455. data/test/TestSuite/Syntax/Correct/CriticalPath.tjp +31 -0
  456. data/test/TestSuite/Syntax/Correct/Currencyformat.tjp +12 -0
  457. data/test/TestSuite/Syntax/Correct/CustomAttributes.tjp +14 -0
  458. data/test/TestSuite/Syntax/Correct/Depends1.tjp +22 -0
  459. data/test/TestSuite/Syntax/Correct/Durations.tjp +29 -0
  460. data/test/TestSuite/Syntax/Correct/Efficiency.tjp +19 -0
  461. data/test/TestSuite/Syntax/Correct/Export.tjp +40 -0
  462. data/test/TestSuite/Syntax/Correct/Flags.tjp +32 -0
  463. data/test/TestSuite/Syntax/Correct/Freeze.tjp +28 -0
  464. data/test/TestSuite/Syntax/Correct/Gap.tjp +15 -0
  465. data/test/TestSuite/Syntax/Correct/HtmlTaskReport.tjp +33 -0
  466. data/test/TestSuite/Syntax/Correct/Limits-1.tjp +71 -0
  467. data/test/TestSuite/Syntax/Correct/LoadUnits.tjp +31 -0
  468. data/test/TestSuite/Syntax/Correct/Macro-1.tjp +19 -0
  469. data/test/TestSuite/Syntax/Correct/Mandatory.tjp +17 -0
  470. data/test/TestSuite/Syntax/Correct/Milestone.tjp +12 -0
  471. data/test/TestSuite/Syntax/Correct/MinMax.tjp +17 -0
  472. data/test/TestSuite/Syntax/Correct/Numberformat.tjp +12 -0
  473. data/test/TestSuite/Syntax/Correct/Period.tjp +16 -0
  474. data/test/TestSuite/Syntax/Correct/Persistent.tjp +11 -0
  475. data/test/TestSuite/Syntax/Correct/Precedes1.tjp +17 -0
  476. data/test/TestSuite/Syntax/Correct/Priority.tjp +30 -0
  477. data/test/TestSuite/Syntax/Correct/Project.tjp +21 -0
  478. data/test/TestSuite/Syntax/Correct/ProjectIDs.tjp +23 -0
  479. data/test/TestSuite/Syntax/Correct/RawHTML.tjp +29 -0
  480. data/test/TestSuite/Syntax/Correct/Reports.tjp +54 -0
  481. data/test/TestSuite/Syntax/Correct/Resource.tjp +20 -0
  482. data/test/TestSuite/Syntax/Correct/Responsible.tjp +16 -0
  483. data/test/TestSuite/Syntax/Correct/Scenario.tjp +15 -0
  484. data/test/TestSuite/Syntax/Correct/Scheduling.tjp +26 -0
  485. data/test/TestSuite/Syntax/Correct/Select.tjp +27 -0
  486. data/test/TestSuite/Syntax/Correct/Shift.tjp +55 -0
  487. data/test/TestSuite/Syntax/Correct/Simple.tjp +25 -0
  488. data/test/TestSuite/Syntax/Correct/String.tjp +12 -0
  489. data/test/TestSuite/Syntax/Correct/Supplement.tjp +24 -0
  490. data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +34 -0
  491. data/test/TestSuite/Syntax/Correct/TimeFrame.tjp +19 -0
  492. data/test/TestSuite/Syntax/Correct/Timezone.tjp +8 -0
  493. data/test/TestSuite/Syntax/Correct/Vacation.tjp +33 -0
  494. data/test/TestSuite/Syntax/Correct/csvtest +16 -0
  495. data/test/TestSuite/Syntax/Correct/manual2example.rb +24 -0
  496. data/test/TestSuite/Syntax/Correct/tutorial.tjp +485 -0
  497. data/test/TestSuite/Syntax/Errors/bad_include.tjp +11 -0
  498. data/test/TestSuite/Syntax/Errors/booking_group.tjp +14 -0
  499. data/test/TestSuite/Syntax/Errors/booking_milestone.tjp +13 -0
  500. data/test/TestSuite/Syntax/Errors/booking_no_leaf.tjp +13 -0
  501. data/test/TestSuite/Syntax/Errors/chargeset.tjp +14 -0
  502. data/test/TestSuite/Syntax/Errors/chargeset_master.tjp +15 -0
  503. data/test/TestSuite/Syntax/Errors/container_attribute.tjp +13 -0
  504. data/test/TestSuite/Syntax/Errors/cost_acct_no_top.tjp +24 -0
  505. data/test/TestSuite/Syntax/Errors/cost_rev_same.tjp +24 -0
  506. data/test/TestSuite/Syntax/Errors/date_in_range.tjp +7 -0
  507. data/test/TestSuite/Syntax/Errors/effort_zero.tjp +8 -0
  508. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -0
  509. data/test/TestSuite/Syntax/Errors/export_bad_extn.tjp +9 -0
  510. data/test/TestSuite/Syntax/Errors/extend_id_cap.tjp +7 -0
  511. data/test/TestSuite/Syntax/Errors/interval_end_in_range.tjp +7 -0
  512. data/test/TestSuite/Syntax/Errors/interval_start_in_range.tjp +7 -0
  513. data/test/TestSuite/Syntax/Errors/leaf_resource_id_expected.tjp +12 -0
  514. data/test/TestSuite/Syntax/Errors/misaligned_date.tjp +7 -0
  515. data/test/TestSuite/Syntax/Errors/no_csv_suffix.tjp +10 -0
  516. data/test/TestSuite/Syntax/Errors/no_html_suffix.tjp +10 -0
  517. data/test/TestSuite/Syntax/Errors/operand_attribute.tjp +11 -0
  518. data/test/TestSuite/Syntax/Errors/operand_unkn_flag.tjp +11 -0
  519. data/test/TestSuite/Syntax/Errors/operand_unkn_scen.tjp +11 -0
  520. data/test/TestSuite/Syntax/Errors/overtime_range.tjp +13 -0
  521. data/test/TestSuite/Syntax/Errors/purge_no_list.tjp +8 -0
  522. data/test/TestSuite/Syntax/Errors/purge_unknown_id.tjp +8 -0
  523. data/test/TestSuite/Syntax/Errors/report_end.tjp +10 -0
  524. data/test/TestSuite/Syntax/Errors/report_redifinition.tjp +10 -0
  525. data/test/TestSuite/Syntax/Errors/report_start.tjp +10 -0
  526. data/test/TestSuite/Syntax/Errors/resource_exists.tjp +7 -0
  527. data/test/TestSuite/Syntax/Errors/resource_id_expected.tjp +8 -0
  528. data/test/TestSuite/Syntax/Errors/rev_acct_no_top.tjp +24 -0
  529. data/test/TestSuite/Syntax/Errors/scenario_exists.tjp +7 -0
  530. data/test/TestSuite/Syntax/Errors/shift_assignment_overlap.tjp +15 -0
  531. data/test/TestSuite/Syntax/Errors/shift_exists.tjp +7 -0
  532. data/test/TestSuite/Syntax/Errors/shift_id_expected.tjp +7 -0
  533. data/test/TestSuite/Syntax/Errors/sloppy_range.tjp +13 -0
  534. data/test/TestSuite/Syntax/Errors/sort_direction.tjp +11 -0
  535. data/test/TestSuite/Syntax/Errors/sort_unknown_scen.tjp +11 -0
  536. data/test/TestSuite/Syntax/Errors/sorting_crit_exptd1.tjp +11 -0
  537. data/test/TestSuite/Syntax/Errors/sorting_crit_exptd2.tjp +11 -0
  538. data/test/TestSuite/Syntax/Errors/sorting_wbs.tjp +11 -0
  539. data/test/TestSuite/Syntax/Errors/start_before_end1.tjp +7 -0
  540. data/test/TestSuite/Syntax/Errors/start_before_end2.tjp +6 -0
  541. data/test/TestSuite/Syntax/Errors/task_complete.tjp +8 -0
  542. data/test/TestSuite/Syntax/Errors/task_exists.tjp +7 -0
  543. data/test/TestSuite/Syntax/Errors/task_priority.tjp +8 -0
  544. data/test/TestSuite/Syntax/Errors/task_without_chargeset.tjp +9 -0
  545. data/test/TestSuite/Syntax/Errors/time_interval.tjp +12 -0
  546. data/test/TestSuite/Syntax/Errors/too_many_bangs.tjp +10 -0
  547. data/test/TestSuite/Syntax/Errors/undecl_flag.tjp +6 -0
  548. data/test/TestSuite/Syntax/Errors/unknown_projectid.tjp +7 -0
  549. data/test/TestSuite/Syntax/Errors/unknown_scenario_id.tjp +6 -0
  550. data/test/TestSuite/Syntax/Errors/unknown_scenario_idx.tjp +11 -0
  551. data/test/TestSuite/Syntax/Errors/unknown_task.tjp +10 -0
  552. data/test/all.rb +31 -0
  553. data/test/test_BatchProcessor.rb +54 -0
  554. data/test/test_CSV-Reports.rb +101 -0
  555. data/test/test_Limits.rb +104 -0
  556. data/test/test_LogicalExpression.rb +110 -0
  557. data/test/test_MacroTable.rb +51 -0
  558. data/test/test_Project.rb +57 -0
  559. data/test/test_PropertySet.rb +71 -0
  560. data/test/test_Query.rb +83 -0
  561. data/test/test_RealFormat.rb +83 -0
  562. data/test/test_RichText.rb +869 -0
  563. data/test/test_Scheduler.rb +42 -0
  564. data/test/test_ShiftAssignments.rb +77 -0
  565. data/test/test_Syntax.rb +41 -0
  566. data/test/test_TextScanner.rb +95 -0
  567. data/test/test_TjTime.rb +114 -0
  568. data/test/test_TjpExample.rb +169 -0
  569. data/test/test_UTF8String.rb +84 -0
  570. data/test/test_WorkingHours.rb +56 -0
  571. metadata +649 -0
@@ -0,0 +1,304 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = PropertySet.rb -- The TaskJuggler III Project Management Software
5
+ #
6
+ # Copyright (c) 2006, 2007, 2008, 2009 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
+
14
+ require 'AttributeDefinition'
15
+ require 'PropertyTreeNode'
16
+
17
+ class TaskJuggler
18
+
19
+ # A PropertySet is a collection of properties of the same kind. Properties can
20
+ # be Task, Resources, Scenario, Shift or Accounts objects. All properties of
21
+ # the same kind belong to the same PropertySet. A property may only belong to
22
+ # one PropertySet in the Project. The PropertySet holds the definitions for
23
+ # the attributes. All Properties of the set will have a set of these
24
+ # attributes.
25
+ class PropertySet
26
+
27
+ attr_reader :project, :flatNamespace, :attributeDefinitions
28
+
29
+ def initialize(project, flatNamespace)
30
+ if $DEBUG && project.nil?
31
+ raise "project parameter may not be NIL"
32
+ end
33
+ # Indicates whether the namespace of this PropertySet is flat or not. In a
34
+ # flat namespace all property IDs must be unique. Otherwise only the IDs
35
+ # within a group of siblings must be unique. The full ID of the Property
36
+ # is then composed of the siblings ID prefixed by the parent ID. ID fields
37
+ # are separated by dots.
38
+ @flatNamespace = flatNamespace
39
+ # The main Project data structure reference.
40
+ @project = project
41
+ # This is the blueprint for PropertyTreeNode attribute sets. Whever a new
42
+ # PropertTreeNode is created, an attribute is created for each definition
43
+ # in this list.
44
+ @attributeDefinitions = Hash.new
45
+ # A list of all PropertyTreeNodes in this set.
46
+ @properties = Array.new
47
+ # A hash of all PropertyTreeNodes in this set, hashed by their ID. This is
48
+ # the same data as in @properties, but hashed by ID for faster access.
49
+ @propertyMap = Hash.new
50
+
51
+ # IDs and names of the built-in attributes. TODO: Check performance impact
52
+ # when making them normal attributes.
53
+ @@fixedAttributeNames = {
54
+ 'id' => 'ID',
55
+ 'name' => 'Name',
56
+ 'seqno' => 'Seq. No.'
57
+ }
58
+ # And their types.
59
+ @@fixedAttributesTypes = {
60
+ 'id' => :String,
61
+ 'name' => :String,
62
+ 'seqno' => :Fixnum
63
+ }
64
+ end
65
+
66
+ # Inherit all attributes of each property from the parent scenario.
67
+ def inheritAttributesFromScenario
68
+ @properties.each { |p| p.inheritAttributesFromScenario }
69
+ end
70
+
71
+ # Use the function to declare the various attributes that properties of this
72
+ # PropertySet can have. The attributes must be declared before the first
73
+ # property is added to the set.
74
+ def addAttributeType(attributeType)
75
+ if !@properties.empty?
76
+ raise "Fatal Error: Attribute types must be defined before " +
77
+ "properties are added."
78
+ end
79
+
80
+ @attributeDefinitions[attributeType.id] = attributeType
81
+ end
82
+
83
+ # Iterate over all attribute definitions.
84
+ def eachAttributeDefinition
85
+ @attributeDefinitions.each do |key, value|
86
+ yield(value)
87
+ end
88
+ end
89
+
90
+ # Return true if there is an AttributeDefinition for _attrId_.
91
+ def knownAttribute?(attrId)
92
+ @@fixedAttributeNames.include?(attrId) ||
93
+ @attributeDefinitions.include?(attrId)
94
+ end
95
+
96
+ # Return whether the attribute with _attrId_ is scenario specific or not.
97
+ def scenarioSpecific?(attrId)
98
+ # All hardwired attributes are not scenario specific.
99
+ return false if @attributeDefinitions[attrId].nil?
100
+
101
+ @attributeDefinitions[attrId].scenarioSpecific
102
+ end
103
+
104
+ # Return whether the attribute with _attrId_ is scenario specific or not.
105
+ def inheritable?(attrId)
106
+ # All hardwired attributes are not inheritable.
107
+ return false if @attributeDefinitions[attrId].nil?
108
+
109
+ @attributeDefinitions[attrId].inheritable
110
+ end
111
+
112
+ # Return whether or not the attribute was user defined.
113
+ def userDefined?(attrId)
114
+ return false if @attributeDefinitions[attrId].nil?
115
+
116
+ @attributeDefinitions[attrId].userDefined
117
+ end
118
+
119
+ # Return the default value of the attribute.
120
+ def defaultValue(attrId)
121
+ return nil if @attributeDefinitions[attrId].nil?
122
+
123
+ @attributeDefinitions[attrId].default
124
+ end
125
+
126
+ # Returns the name (human readable description) of the attribute with the
127
+ # Id specified by _attrId_.
128
+ def attributeName(attrId)
129
+ # Some attributes are hardwired into the properties. These need to be
130
+ # treated separately.
131
+ if @@fixedAttributeNames[attrId].nil?
132
+ if @attributeDefinitions.include?(attrId)
133
+ return @attributeDefinitions[attrId].name
134
+ end
135
+ else
136
+ return @@fixedAttributeNames[attrId]
137
+ end
138
+
139
+ nil
140
+ end
141
+
142
+ # Return the type of the attribute with the Id specified by _attrId_.
143
+ def attributeType(attrId)
144
+ # Hardwired attributes need special treatment.
145
+ if @@fixedAttributesTypes[attrId].nil?
146
+ if @attributeDefinitions.has_key?(attrId)
147
+ @attributeDefinitions[attrId].objClass
148
+ else
149
+ nil
150
+ end
151
+ else
152
+ @@fixedAttributesTypes[attrId]
153
+ end
154
+ end
155
+
156
+ # Add the new PropertyTreeNode object _property_ to the set. The set is
157
+ # indexed by ID. In case an object with the same ID already exists in the
158
+ # set it will be overwritten.
159
+ #
160
+ # Whenever the set has been extended, the 'wbs' and 'tree' attributes of the
161
+ # properties are no longer up-to-date. You must call index() before using
162
+ # these attributes.
163
+ def addProperty(property)
164
+ # The PropertySet defines the set of attribute that each PropertyTreeNode
165
+ # in this set has. Create these attributes with their default values.
166
+ @attributeDefinitions.each do |id, attributeType|
167
+ property.declareAttribute(attributeType)
168
+ end
169
+
170
+ # The PropertyTreeNode objects are indexed by ID or hierachical ID
171
+ # depending on the name space setting of this set.
172
+ if @flatNamespace
173
+ @propertyMap[property.id] = property
174
+ else
175
+ @propertyMap[property.fullId] = property
176
+ end
177
+ @properties << property
178
+ end
179
+
180
+ # Remove the PropertyTreeNode (and all its children) object from the set.
181
+ # _prop_ can either be a property ID or a reference to the PropertyTreeNode.
182
+ #
183
+ # TODO: This function does not take care of references to this PTN!
184
+ def removeProperty(prop)
185
+ if prop.is_a?(String)
186
+ property = @propertyMap[prop]
187
+ else
188
+ property = prop
189
+ end
190
+
191
+ # Recursively remove all sub-nodes. The children list is modified during
192
+ # the call, so we can't use an iterator here.
193
+ until property.children.empty? do
194
+ removeProperty(property.children.first)
195
+ end
196
+
197
+ @properties.delete(property)
198
+ @propertyMap.delete(property.fullId)
199
+
200
+ # Remove this node from the child list of the parent node.
201
+ property.parent.children.delete(property) if property.parent
202
+
203
+ property
204
+ end
205
+
206
+ # Call this function to delete all registered properties.
207
+ def clearProperties
208
+ @properties.clear
209
+ @propertyMap.clear
210
+ end
211
+
212
+ # Return the PropertyTreeNode object with ID _id_ from the set or nil if not
213
+ # present.
214
+ def [](id)
215
+ @propertyMap[id]
216
+ end
217
+
218
+ # Update the WBS and tree indicies. This method needs to be called whenever
219
+ # the set has been modified.
220
+ def index
221
+ each do |p|
222
+ wbsIdcs = p.getWBSIndicies
223
+ tree = ""
224
+ wbs = ""
225
+ first = true
226
+ wbsIdcs.each do |idx|
227
+ # Prefix the level index with zeros so that we always have a 5 digit
228
+ # long String. 5 digits should be large enough for all real-world
229
+ # projects.
230
+ tree += idx.to_s.rjust(5, '0')
231
+ if first
232
+ first = false
233
+ else
234
+ wbs += '.'
235
+ end
236
+ wbs += idx.to_s
237
+ end
238
+ p.set('wbs', wbs)
239
+ p.set('tree', tree)
240
+ end
241
+ end
242
+
243
+ # Return the index of the top-level _property_ in the set.
244
+ def levelSeqNo(property)
245
+ seqNo = 1
246
+ @properties.each do |p|
247
+ unless p.parent
248
+ return seqNo if p == property
249
+ seqNo += 1
250
+ end
251
+ end
252
+ raise "Fatal Error: Unknow property #{property}"
253
+ end
254
+
255
+ # Return the maximum used number of breakdown levels. A flat list has a
256
+ # maxDepth of 1. A list with one sub level has a maxDepth of 2 and so on.
257
+ def maxDepth
258
+ md = 0
259
+ each do |p|
260
+ md = p.level if p.level > md
261
+ end
262
+ md + 1
263
+ end
264
+
265
+ # Return the number of PropertyTreeNode objects in this set.
266
+ def items
267
+ @properties.length
268
+ end
269
+
270
+ # Return true if the set is empty.
271
+ def empty?
272
+ @properties.empty?
273
+ end
274
+
275
+ # Return the number of top-level PropertyTreeNode objects. Top-Level items
276
+ # are no children.
277
+ def topLevelItems
278
+ items = 0
279
+ @properties.each do |p|
280
+ items += 1 unless p.parent
281
+ end
282
+ items
283
+ end
284
+
285
+ # Iterator over all PropertyTreeNode objects in this set.
286
+ def each
287
+ @properties.each do |value|
288
+ yield(value)
289
+ end
290
+ end
291
+
292
+ # Return the set of PropertyTreeNode objects as flat Array.
293
+ def to_ary
294
+ @properties
295
+ end
296
+
297
+ def to_s
298
+ PropertyList.new(self).to_s
299
+ end
300
+
301
+ end
302
+
303
+ end
304
+
@@ -0,0 +1,461 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = PropertyTreeNode.rb -- The TaskJuggler III Project Management Software
5
+ #
6
+ # Copyright (c) 2006, 2007, 2008, 2009 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
+ class TaskJuggler
14
+
15
+ # This class is the base object for all Project properties. A Project property
16
+ # is a e. g. a Task, a Resource or other objects. Such properties can be
17
+ # arranged in tree form by assigning child properties to an existing property.
18
+ # The parent object needs to exist at object creation time. The
19
+ # PropertyTreeNode class holds all data and methods that are common to the
20
+ # different types of properties. Each property can have a set of predifined
21
+ # attributes. The PropertySet class holds collections of the same
22
+ # PropertyTreeNode objects and the defined attributes.
23
+ # Each PropertySet has a predefined set of attributes, but the attribute set
24
+ # can be extended by the user. E.g. a task has the predefined attribute
25
+ # 'start' and 'end' date. The user can extend tasks with a user defined
26
+ # attribute like an URL that contains more details about the task.
27
+ class PropertyTreeNode
28
+
29
+ attr_reader :propertySet, :id, :name, :parent, :project, :sequenceNo,
30
+ :children
31
+ attr_accessor :sourceFileInfo
32
+
33
+ # Create a new PropertyTreeNode object. _propertySet_ is the PropertySet
34
+ # that this PropertyTreeNode object belongs to. The PropertySet determines
35
+ # the attributes that are common to all Nodes in the set. _id_ is a String
36
+ # that is unique in the namespace of the set. _name_ is a user readable,
37
+ # short description of the object. _parent_ is the PropertyTreeNode that
38
+ # sits above this node in the object hierachy. A root object has a _parent_
39
+ # of nil. For sets with hierachical name spaces, parent can be nil and
40
+ # specified by a hierachical _id_ (e. g. 'father.son').
41
+ def initialize(propertySet, id, name, parent)
42
+ @propertySet = propertySet
43
+ if !@propertySet.flatNamespace && id.include?('.')
44
+ parentId = id[0..(id.rindex('.') - 1)]
45
+ # Set parent to the parent property if it's still nil.
46
+ parent = @propertySet[parentId] unless parent
47
+ if $DEBUG
48
+ if !parent || !@propertySet[parent.fullId]
49
+ raise "Fatal Error: parent must be member of same property set"
50
+ end
51
+ if parentId != parent.fullId
52
+ raise "Fatal Error: parent (#{parent.fullId}) and parent ID " +
53
+ "(#{parentId}) don't match"
54
+ end
55
+ end
56
+ @id = id[(id.rindex('.') + 1).. -1]
57
+ else
58
+ @id = id
59
+ end
60
+ @name = name
61
+ @project = propertySet.project
62
+ @level = -1
63
+ @sourceFileInfo = nil
64
+
65
+ @parent = parent
66
+ @sequenceNo = @propertySet.items + 1
67
+ @children = Array.new
68
+ # In case we have a parent object, we register this object as child of
69
+ # the parent.
70
+ if (@parent)
71
+ @parent.addChild(self)
72
+ end
73
+
74
+ @attributes = Hash.new
75
+ @scenarioAttributes = Array.new(@project.scenarioCount)
76
+ @project.scenarioCount.times do |i|
77
+ @scenarioAttributes[i] = Hash.new
78
+ end
79
+ # Scenario specific data
80
+ @data = nil
81
+ end
82
+
83
+ # Return the index of the child _node_.
84
+ def levelSeqNo(node)
85
+ @children.index(node) + 1
86
+ end
87
+
88
+ # Inherit values for the attributes from the parent node or the Project.
89
+ def inheritAttributes
90
+ # These attributes are being inherited from the Project.
91
+ whitelist = %w( limits priority projectid rate vacation workinghours )
92
+
93
+ # Inherit non-scenario-specific values
94
+ @propertySet.eachAttributeDefinition do |attrDef|
95
+ next if attrDef.scenarioSpecific || !attrDef.inheritable
96
+
97
+ aId = attrDef.id
98
+ if parent
99
+ # Inherit values from parent property
100
+ if parent.provided(aId) || parent.inherited(aId)
101
+ @attributes[aId].inherit(parent.get(aId))
102
+ end
103
+ else
104
+ # Inherit selected values from project if top-level property
105
+ if whitelist.index(aId)
106
+ if @project[aId]
107
+ @attributes[aId].inherit(@project[aId])
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ # Inherit scenario-specific values
114
+ @propertySet.eachAttributeDefinition do |attrDef|
115
+ next if !attrDef.scenarioSpecific || !attrDef.inheritable
116
+
117
+ @project.scenarioCount.times do |scenarioIdx|
118
+ if parent
119
+ # Inherit scenario specific values from parent property
120
+ if parent.provided(attrDef.id, scenarioIdx) ||
121
+ parent.inherited(attrDef.id, scenarioIdx)
122
+ @scenarioAttributes[scenarioIdx][attrDef.id].inherit(
123
+ parent[attrDef.id, scenarioIdx])
124
+ end
125
+ else
126
+ # Inherit selected values from project if top-level property
127
+ if whitelist.index(attrDef.id)
128
+ if @project[attrDef.id] &&
129
+ @scenarioAttributes[scenarioIdx][attrDef.id]
130
+ @scenarioAttributes[scenarioIdx][attrDef.id].inherit(
131
+ @project[attrDef.id])
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ # Inherit attribute values from the parent scenario. This is only being done
140
+ # for attributes that don't have a user-specified value already.
141
+ def inheritAttributesFromScenario
142
+ # Inherit scenario-specific values
143
+ @propertySet.eachAttributeDefinition do |attrDef|
144
+ next unless attrDef.scenarioSpecific
145
+
146
+ # We know that parent scenarios precede their children in the list. So
147
+ # it's safe to iterate over the list instead of recursively descend
148
+ # the tree.
149
+ @project.scenarioCount.times do |scenarioIdx|
150
+ scenario = @project.scenario(scenarioIdx)
151
+ next if scenario.parent.nil?
152
+ parentScenarioIdx = scenario.parent.sequenceNo - 1
153
+ # We copy only provided or inherited values from parent scenario when
154
+ # we don't have a provided or inherited value in this scenario.
155
+ if (provided(attrDef.id, parentScenarioIdx) ||
156
+ inherited(attrDef.id, parentScenarioIdx)) &&
157
+ !(provided(attrDef.id, scenarioIdx) ||
158
+ inherited(attrDef.id, scenarioIdx))
159
+ @scenarioAttributes[scenarioIdx][attrDef.id].inherit(
160
+ @scenarioAttributes[parentScenarioIdx][attrDef.id].get)
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ # Returns a list of this node and all transient sub nodes.
167
+ def all
168
+ res = [ self ]
169
+ @children.each do |c|
170
+ res = res.concat(c.all)
171
+ end
172
+ res
173
+ end
174
+
175
+ # Return a list of all leaf nodes of this node.
176
+ def allLeaves
177
+ if leaf?
178
+ res = [ self ]
179
+ else
180
+ res = []
181
+ @children.each do |c|
182
+ res += c.allLeaves
183
+ end
184
+ end
185
+ res
186
+ end
187
+
188
+ # Iterator over all non-scenario-specific attributes of this node.
189
+ def eachAttribute
190
+ @attributes.each do |attr|
191
+ yield attr
192
+ end
193
+ end
194
+
195
+ # Iterator over all scenario-specific attributes of this node.
196
+ def eachScenarioAttribute(scenario)
197
+ @scenarioAttributes[scenario].each_value do |attr|
198
+ yield attr
199
+ end
200
+ end
201
+
202
+ # Return the full id of this node. For PropertySet objects with a flat
203
+ # namespace, this is just the ID. Otherwise, the full ID is composed of all
204
+ # IDs from the root node to this node, separating the IDs by a dot.
205
+ def fullId
206
+ res = @id
207
+ unless @propertySet.flatNamespace
208
+ t = self
209
+ until (t = t.parent).nil?
210
+ res = t.id + "." + res
211
+ end
212
+ end
213
+ res
214
+ end
215
+
216
+ # Returns the level that this property is on. Top-level properties return
217
+ # 0, their children 1 and so on. This value is cached internally, so it does
218
+ # not have to be calculated each time the function is called.
219
+ def level
220
+ return @level if @level >= 0
221
+
222
+ t = self
223
+ @level = 0
224
+ until (t = t.parent).nil?
225
+ @level += 1
226
+ end
227
+ @level
228
+ end
229
+
230
+ # Return the hierarchical index of this node. In project management lingo
231
+ # this is called the Work Breakdown Structure (WBS). The result is an Array
232
+ # with an index for each level from the root to this node.
233
+ def getWBSIndicies
234
+ idcs = []
235
+ p = self
236
+ begin
237
+ parent = p.parent
238
+ idcs.insert(0, parent ? parent.levelSeqNo(p) :
239
+ @propertySet.levelSeqNo(p))
240
+ p = parent
241
+ end while p
242
+ idcs
243
+ end
244
+
245
+ # Add _child_ node as child to this node.
246
+ def addChild(child)
247
+ if $DEBUG && child.propertySet != @propertySet
248
+ raise "Child nodes must belong to the same property set as the parent"
249
+ end
250
+ @children.push(child)
251
+ end
252
+
253
+ # Find out if this property is a direct or indirect child of _ancestor_.
254
+ def isChildOf?(ancestor)
255
+ parent = self
256
+ while parent = parent.parent
257
+ return true if (parent == ancestor)
258
+ end
259
+ false
260
+ end
261
+
262
+ # Return true if the node is a leaf node (has no children).
263
+ def leaf?
264
+ @children.empty?
265
+ end
266
+
267
+ # Return true if the node has children.
268
+ def container?
269
+ !@children.empty?
270
+ end
271
+
272
+ # Return the top-level node for this node.
273
+ def root
274
+ n = self
275
+ while n.parent
276
+ n = n.parent
277
+ end
278
+ n
279
+ end
280
+
281
+ # Register a new attribute with the PropertyTreeNode and create the
282
+ # instances for each scenario.
283
+ def declareAttribute(attributeType)
284
+ if attributeType.scenarioSpecific
285
+ @project.scenarioCount.times do |i|
286
+ attribute = newAttribute(attributeType)
287
+ @scenarioAttributes[i][attribute.id] = attribute
288
+ end
289
+ else
290
+ attribute = newAttribute(attributeType)
291
+ @attributes[attribute.id] = attribute
292
+ end
293
+ end
294
+
295
+ # Return the type of the attribute with ID _attributeId_.
296
+ def attributeDefinition(attributeId)
297
+ @propertySet.attributeDefinitions[attributeId]
298
+ end
299
+
300
+ # Return the value of the non-scenario-specific attribute with ID
301
+ # _attributeId_. In case the attribute does not exist, an exception is
302
+ # raised.
303
+ def get(attributeId)
304
+ case attributeId
305
+ when 'id'
306
+ @id
307
+ when 'name'
308
+ @name
309
+ when 'seqno'
310
+ @sequenceNo
311
+ else
312
+ unless @attributes.has_key?(attributeId)
313
+ raise TjException.new, "Unknown attribute #{attributeId}"
314
+ end
315
+ @attributes[attributeId].get
316
+ end
317
+ end
318
+
319
+ # Return the value of the attribute with ID _attributeId_. In case this is a
320
+ # scenario-specific attribute, the scenario index needs to be provided by
321
+ # _scenarioIdx_.
322
+ def getAttr(attributeId, scenarioIdx = nil)
323
+ if scenarioIdx.nil?
324
+ @attributes[attributeId]
325
+ else
326
+ @scenarioAttributes[scenarioIdx][attributeId]
327
+ end
328
+ end
329
+
330
+ # Set the non-scenario-specific attribute with ID _attributeId_ to _value_.
331
+ # In case the attribute does not exist, an exception is raised.
332
+ def set(attributeId, value)
333
+ unless @attributes.has_key?(attributeId)
334
+ raise TjException.new, "Unknown attribute #{attributeId}"
335
+ end
336
+ @attributes[attributeId].set(value)
337
+ end
338
+
339
+ # Set the scenario specific attribute with ID _attributeId_ for the scenario
340
+ # with index _scenario_ to _value_. In case the attribute does not exist, an
341
+ # exception is raised.
342
+ def []=(attributeId, scenario, value)
343
+ if @scenarioAttributes[scenario].has_key?(attributeId)
344
+ @scenarioAttributes[scenario][attributeId].set(value)
345
+ elsif @attributes.has_key?(attributeId)
346
+ @attributes[attributeId].set(value)
347
+ else
348
+ raise TjException.new, "Unknown attribute #{attributeId}"
349
+ end
350
+ @scenarioAttributes[scenario][attributeId].set(value)
351
+ end
352
+
353
+ # Return the value of the attribute with ID _attributeId_. For
354
+ # scenario-specific attributes, _scenario_ must indicate the index of the
355
+ # Scenario.
356
+ def [](attributeId, scenario)
357
+ if @scenarioAttributes[scenario].has_key?(attributeId)
358
+ @scenarioAttributes[scenario][attributeId].get
359
+ else
360
+ get(attributeId);
361
+ end
362
+ end
363
+
364
+ # This function returns true if the PropertyTreeNode has a query function
365
+ # for the given ID _queryId_. In case a _scenarioIdx_ is specified, the
366
+ # query function must be scenario specific.
367
+ def hasQuery?(queryId, scenarioIdx = nil)
368
+ methodName = 'query_' + queryId
369
+ if scenarioIdx
370
+ @data[scenarioIdx].respond_to?(methodName)
371
+ else
372
+ respond_to?(methodName)
373
+ end
374
+ end
375
+
376
+ # Returns true if the value of the attribute _attributeId_ (in scenario
377
+ # _scenarioIdx_) has been provided by the user.
378
+ def provided(attributeId, scenarioIdx = nil)
379
+ if scenarioIdx
380
+ return false if @scenarioAttributes[scenarioIdx][attributeId].nil?
381
+ @scenarioAttributes[scenarioIdx][attributeId].provided
382
+ else
383
+ return false if @attributes[attributeId].nil?
384
+ @attributes[attributeId].provided
385
+ end
386
+ end
387
+
388
+ # Returns true if the value of the attribute _attributeId_ (in scenario
389
+ # _scenarioIdx_) has been inherited from a parent node or scenario.
390
+ def inherited(attributeId, scenarioIdx = nil)
391
+ if scenarioIdx
392
+ return false if @scenarioAttributes[scenarioIdx][attributeId].nil?
393
+ @scenarioAttributes[scenarioIdx][attributeId].inherited
394
+ else
395
+ return false if @attributes[attributeId].nil?
396
+ @attributes[attributeId].inherited
397
+ end
398
+ end
399
+
400
+ # Dump the class data in human readable form. Used for debugging only.
401
+ def to_s # :nodoc:
402
+ res = "#{self.class} #{fullId} \"#{@name}\"\n" +
403
+ " Sequence No: #{@sequenceNo}\n"
404
+
405
+ res += " Parent: #{@parent.fullId}\n" if @parent
406
+ children = ""
407
+ @children.each do |c|
408
+ children += ', ' unless children.empty?
409
+ children += c.fullId
410
+ end
411
+ res += ' Children: ' + children + "\n" unless children.empty?
412
+ @attributes.sort.each do |key, attr|
413
+ if attr.get != @propertySet.defaultValue(key)
414
+ res += indent(" #{key}: ", attr.to_s)
415
+ end
416
+ end
417
+ unless @scenarioAttributes.empty?
418
+ project.scenarioCount.times do |sc|
419
+ headerShown = false
420
+ @scenarioAttributes[sc].sort.each do |key, attr|
421
+ if attr.get != @propertySet.defaultValue(key)
422
+ unless headerShown
423
+ res += " Scenario #{project.scenario(sc).get('id')} (#{sc})\n"
424
+ headerShown = true
425
+ end
426
+ res += indent(" #{key}: ", attr.to_s)
427
+ end
428
+ end
429
+ end
430
+ end
431
+ res += '-' * 75 + "\n"
432
+ end
433
+
434
+ # Many PropertyTreeNode functions are scenario specific. These functions are
435
+ # provided by the class *Scenario classes. In case we can't find a function
436
+ # called for the base class we try to find it in corresponding *Scenario
437
+ # class.
438
+ def method_missing(func, scenarioIdx, *args)
439
+ @data[scenarioIdx].method(func).call(*args)
440
+ end
441
+
442
+ private
443
+
444
+ def newAttribute(attributeType)
445
+ attribute = attributeType.objClass.new(self, attributeType)
446
+ # If the attribute requires a pointer to the project, we'll hand it over.
447
+ if !attribute.value.nil? && attribute.respond_to?('setProject')
448
+ attribute.setProject(@project)
449
+ end
450
+
451
+ attribute
452
+ end
453
+
454
+ def indent(tag, str)
455
+ tag + str.gsub(/\n/, "\n#{' ' * tag.length}") + "\n"
456
+ end
457
+
458
+ end
459
+
460
+ end
461
+