taskjuggler 0.0.2 → 0.0.3

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 (432) hide show
  1. data/Rakefile +1 -0
  2. data/benchmarks/depends.tjp +2 -1
  3. data/benchmarks/htmltaskreport.tjp +2 -1
  4. data/doc/classes/AppConfig.html +124 -120
  5. data/doc/classes/Arguments.html +10 -6
  6. data/doc/classes/Object.html +229 -0
  7. data/doc/classes/String.html +35 -31
  8. data/doc/classes/TaskJuggler/Account.html +18 -18
  9. data/doc/classes/TaskJuggler/AccountAttribute.html +261 -0
  10. data/doc/classes/TaskJuggler/AccountScenario.html +12 -12
  11. data/doc/classes/TaskJuggler/Allocation.html +34 -30
  12. data/doc/classes/TaskJuggler/AllocationAttribute.html +70 -70
  13. data/doc/classes/TaskJuggler/AttributeBase.html +131 -147
  14. data/doc/classes/TaskJuggler/AttributeDefinition.html +38 -21
  15. data/doc/classes/TaskJuggler/BatchProcessor.html +313 -0
  16. data/doc/classes/TaskJuggler/Booking.html +22 -18
  17. data/doc/classes/TaskJuggler/BookingListAttribute.html +42 -42
  18. data/doc/classes/TaskJuggler/BooleanAttribute.html +40 -40
  19. data/doc/classes/TaskJuggler/CSVFile.html +28 -24
  20. data/doc/classes/TaskJuggler/Charge.html +22 -18
  21. data/doc/classes/TaskJuggler/ChargeListAttribute.html +30 -30
  22. data/doc/classes/TaskJuggler/ChargeSet.html +41 -37
  23. data/doc/classes/TaskJuggler/ChargeSetListAttribute.html +46 -46
  24. data/doc/classes/TaskJuggler/ColumnListAttribute.html +231 -0
  25. data/doc/classes/TaskJuggler/ColumnTable.html +23 -21
  26. data/doc/classes/TaskJuggler/DateAttribute.html +20 -20
  27. data/doc/classes/TaskJuggler/DefinitionListAttribute.html +162 -0
  28. data/doc/classes/TaskJuggler/DependencyListAttribute.html +46 -46
  29. data/doc/classes/TaskJuggler/DurationAttribute.html +30 -30
  30. data/doc/classes/TaskJuggler/FixnumAttribute.html +20 -20
  31. data/doc/classes/TaskJuggler/FlagListAttribute.html +42 -42
  32. data/doc/classes/TaskJuggler/FloatAttribute.html +30 -30
  33. data/doc/classes/TaskJuggler/FormatListAttribute.html +197 -0
  34. data/doc/classes/TaskJuggler/GanttChart.html +236 -207
  35. data/doc/classes/TaskJuggler/GanttContainer.html +46 -42
  36. data/doc/classes/TaskJuggler/GanttHeader.html +16 -12
  37. data/doc/classes/TaskJuggler/GanttHeaderScaleItem.html +16 -12
  38. data/doc/classes/TaskJuggler/GanttLine.html +28 -24
  39. data/doc/classes/TaskJuggler/GanttLoadStack.html +22 -18
  40. data/doc/classes/TaskJuggler/GanttMilestone.html +46 -42
  41. data/doc/classes/TaskJuggler/GanttRouter.html +104 -98
  42. data/doc/classes/TaskJuggler/GanttTaskBar.html +46 -42
  43. data/doc/classes/TaskJuggler/HTMLDocument.html +12 -12
  44. data/doc/classes/TaskJuggler/HTMLGraphics.html +12 -12
  45. data/doc/classes/TaskJuggler/Interval.html +126 -120
  46. data/doc/classes/TaskJuggler/IntervalListAttribute.html +46 -46
  47. data/doc/classes/TaskJuggler/JobInfo.html +284 -0
  48. data/doc/classes/TaskJuggler/Journal.html +197 -0
  49. data/doc/classes/TaskJuggler/JournalEntry.html +218 -0
  50. data/doc/classes/TaskJuggler/KeywordArray.html +179 -0
  51. data/doc/classes/TaskJuggler/KeywordDocumentation.html +445 -396
  52. data/doc/classes/TaskJuggler/Limits/Limit.html +34 -30
  53. data/doc/classes/TaskJuggler/Limits.html +68 -62
  54. data/doc/classes/TaskJuggler/LimitsAttribute.html +40 -40
  55. data/doc/classes/TaskJuggler/ListAttributeBase.html +207 -0
  56. data/doc/classes/TaskJuggler/Log.html +72 -68
  57. data/doc/classes/TaskJuggler/LogicalAttribute.html +38 -34
  58. data/doc/classes/TaskJuggler/LogicalExpression.html +16 -12
  59. data/doc/classes/TaskJuggler/LogicalExpressionAttribute.html +194 -0
  60. data/doc/classes/TaskJuggler/LogicalFlag.html +32 -32
  61. data/doc/classes/TaskJuggler/LogicalFunction.html +28 -24
  62. data/doc/classes/TaskJuggler/LogicalOperation.html +17 -13
  63. data/doc/classes/TaskJuggler/Macro.html +10 -6
  64. data/doc/classes/TaskJuggler/MacroParser.html +36 -36
  65. data/doc/classes/TaskJuggler/MacroTable.html +40 -36
  66. data/doc/classes/TaskJuggler/Message.html +16 -12
  67. data/doc/classes/TaskJuggler/MessageHandler.html +16 -12
  68. data/doc/classes/TaskJuggler/Navigator.html +249 -0
  69. data/doc/classes/TaskJuggler/OnShiftCache.html +316 -0
  70. data/doc/classes/TaskJuggler/Project.html +1064 -678
  71. data/doc/classes/TaskJuggler/ProjectFileParser.html +90 -85
  72. data/doc/classes/TaskJuggler/PropertyAttribute.html +194 -0
  73. data/doc/classes/TaskJuggler/PropertyList.html +114 -113
  74. data/doc/classes/TaskJuggler/PropertySet.html +355 -312
  75. data/doc/classes/TaskJuggler/PropertyTreeNode.html +527 -474
  76. data/doc/classes/TaskJuggler/Query.html +90 -85
  77. data/doc/classes/TaskJuggler/RTPNavigator.html +292 -0
  78. data/doc/classes/TaskJuggler/RTPReport.html +301 -0
  79. data/doc/classes/TaskJuggler/RealFormat.html +114 -57
  80. data/doc/classes/TaskJuggler/RealFormatAttribute.html +162 -0
  81. data/doc/classes/TaskJuggler/ReferenceAttribute.html +87 -20
  82. data/doc/classes/TaskJuggler/Report.html +82 -291
  83. data/doc/classes/TaskJuggler/ReportBase.html +448 -0
  84. data/doc/classes/TaskJuggler/ReportContext.html +243 -0
  85. data/doc/classes/TaskJuggler/ReportTable.html +158 -129
  86. data/doc/classes/TaskJuggler/ReportTableCell.html +30 -26
  87. data/doc/classes/TaskJuggler/ReportTableColumn.html +29 -25
  88. data/doc/classes/TaskJuggler/ReportTableLegend.html +28 -24
  89. data/doc/classes/TaskJuggler/ReportTableLine.html +34 -30
  90. data/doc/classes/TaskJuggler/Resource.html +12 -12
  91. data/doc/classes/TaskJuggler/ResourceListAttribute.html +46 -46
  92. data/doc/classes/TaskJuggler/ResourceListRE.html +49 -57
  93. data/doc/classes/TaskJuggler/ResourceScenario.html +126 -126
  94. data/doc/classes/TaskJuggler/RichText.html +52 -48
  95. data/doc/classes/TaskJuggler/RichTextAttribute.html +30 -30
  96. data/doc/classes/TaskJuggler/RichTextDocument.html +41 -37
  97. data/doc/classes/TaskJuggler/RichTextElement.html +274 -264
  98. data/doc/classes/TaskJuggler/RichTextException.html +13 -13
  99. data/doc/classes/TaskJuggler/RichTextParser.html +48 -47
  100. data/doc/classes/TaskJuggler/RichTextProtocolExample.html +52 -55
  101. data/doc/classes/TaskJuggler/RichTextProtocolHandler.html +55 -10
  102. data/doc/classes/TaskJuggler/RichTextScanner.html +106 -245
  103. data/doc/classes/TaskJuggler/RichTextSnip.html +28 -24
  104. data/doc/classes/TaskJuggler/RichTextSyntaxRules.html +381 -301
  105. data/doc/classes/TaskJuggler/Scenario.html +6 -6
  106. data/doc/classes/TaskJuggler/ScenarioData.html +40 -36
  107. data/doc/classes/TaskJuggler/ScenarioListAttribute.html +229 -0
  108. data/doc/classes/TaskJuggler/Scoreboard.html +70 -66
  109. data/doc/classes/TaskJuggler/Shift.html +18 -18
  110. data/doc/classes/TaskJuggler/ShiftAssignment.html +58 -54
  111. data/doc/classes/TaskJuggler/ShiftAssignments.html +82 -78
  112. data/doc/classes/TaskJuggler/ShiftAssignmentsAttribute.html +40 -40
  113. data/doc/classes/TaskJuggler/ShiftScenario.html +24 -24
  114. data/doc/classes/TaskJuggler/SortListAttribute.html +196 -0
  115. data/doc/classes/TaskJuggler/SourceFileInfo.html +16 -12
  116. data/doc/classes/TaskJuggler/StringAttribute.html +30 -30
  117. data/doc/classes/TaskJuggler/SymbolAttribute.html +20 -20
  118. data/doc/classes/TaskJuggler/SyntaxReference.html +46 -42
  119. data/doc/classes/TaskJuggler/TOCEntry.html +16 -12
  120. data/doc/classes/TaskJuggler/TableColumnDefinition.html +48 -33
  121. data/doc/classes/TaskJuggler/TableOfContents.html +22 -18
  122. data/doc/classes/TaskJuggler/TableReport.html +1036 -0
  123. data/doc/classes/TaskJuggler/Task.html +12 -12
  124. data/doc/classes/TaskJuggler/TaskDependency.html +16 -12
  125. data/doc/classes/TaskJuggler/TaskListAttribute.html +46 -46
  126. data/doc/classes/TaskJuggler/TaskListRE.html +49 -58
  127. data/doc/classes/TaskJuggler/TaskScenario.html +1270 -1180
  128. data/doc/classes/TaskJuggler/TextParser/Pattern.html +100 -96
  129. data/doc/classes/TaskJuggler/TextParser/Rule.html +88 -84
  130. data/doc/classes/TaskJuggler/TextParser/StackElement.html +16 -12
  131. data/doc/classes/TaskJuggler/TextParser/TextParserResultArray.html +12 -12
  132. data/doc/classes/TaskJuggler/TextParser/TokenDoc.html +10 -6
  133. data/doc/classes/TaskJuggler/TextParser.html +203 -140
  134. data/doc/classes/TaskJuggler/TextReport.html +364 -0
  135. data/doc/classes/TaskJuggler/TextScanner/BufferStreamHandle.html +70 -70
  136. data/doc/classes/TaskJuggler/TextScanner/FileStreamHandle.html +50 -42
  137. data/doc/classes/TaskJuggler/TextScanner/StreamHandle.html +16 -12
  138. data/doc/classes/TaskJuggler/TextScanner.html +334 -240
  139. data/doc/classes/TaskJuggler/TjException.html +6 -6
  140. data/doc/classes/TaskJuggler/TjTime.html +547 -497
  141. data/doc/classes/TaskJuggler/TjpExample.html +29 -25
  142. data/doc/classes/TaskJuggler/TjpExportRE.html +77 -97
  143. data/doc/classes/TaskJuggler/TjpSyntaxRules.html +3911 -3886
  144. data/doc/classes/TaskJuggler/UserManual.html +54 -54
  145. data/doc/classes/TaskJuggler/WorkingHours.html +53 -49
  146. data/doc/classes/TaskJuggler/WorkingHoursAttribute.html +53 -85
  147. data/doc/classes/TaskJuggler/XMLBlob.html +21 -21
  148. data/doc/classes/TaskJuggler/XMLComment.html +21 -21
  149. data/doc/classes/TaskJuggler/XMLDocument.html +28 -24
  150. data/doc/classes/TaskJuggler/XMLElement.html +70 -58
  151. data/doc/classes/TaskJuggler/XMLNamedText.html +11 -11
  152. data/doc/classes/TaskJuggler/XMLText.html +36 -36
  153. data/doc/classes/TaskJuggler.html +266 -183
  154. data/doc/files/COPYING.html +1 -1
  155. data/doc/files/README.html +1 -1
  156. data/doc/files/lib/AccountScenario_rb.html +1 -1
  157. data/doc/files/lib/Account_rb.html +1 -1
  158. data/doc/files/lib/Allocation_rb.html +1 -1
  159. data/doc/files/lib/AppConfig_rb.html +1 -1
  160. data/doc/files/lib/AttributeBase_rb.html +11 -1
  161. data/doc/files/lib/AttributeDefinition_rb.html +1 -1
  162. data/doc/files/lib/Attributes_rb.html +1 -1
  163. data/doc/files/lib/{LogicalFlag_rb.html → BatchProcessor_rb.html} +8 -6
  164. data/doc/files/lib/Booking_rb.html +1 -1
  165. data/doc/files/lib/ChargeSet_rb.html +1 -1
  166. data/doc/files/lib/Charge_rb.html +1 -1
  167. data/doc/files/lib/HTMLDocument_rb.html +1 -1
  168. data/doc/files/lib/Interval_rb.html +1 -1
  169. data/doc/files/lib/Journal_rb.html +106 -0
  170. data/doc/files/lib/KeywordArray_rb.html +106 -0
  171. data/doc/files/lib/KeywordDocumentation_rb.html +1 -1
  172. data/doc/files/lib/Limits_rb.html +1 -1
  173. data/doc/files/lib/Log_rb.html +1 -1
  174. data/doc/files/lib/LogicalExpression_rb.html +1 -3
  175. data/doc/files/lib/LogicalFunction_rb.html +1 -1
  176. data/doc/files/lib/LogicalOperation_rb.html +1 -1
  177. data/doc/files/lib/MacroParser_rb.html +1 -1
  178. data/doc/files/lib/MacroTable_rb.html +1 -1
  179. data/doc/files/lib/MessageHandler_rb.html +1 -1
  180. data/doc/files/lib/Message_rb.html +1 -1
  181. data/doc/files/lib/ProjectFileParser_rb.html +5 -1
  182. data/doc/files/lib/Project_rb.html +5 -1
  183. data/doc/files/lib/PropertyList_rb.html +1 -1
  184. data/doc/files/lib/PropertySet_rb.html +1 -1
  185. data/doc/files/lib/PropertyTreeNode_rb.html +1 -1
  186. data/doc/files/lib/Query_rb.html +1 -1
  187. data/doc/files/lib/RTPNavigator_rb.html +120 -0
  188. data/doc/files/lib/RTPReport_rb.html +118 -0
  189. data/doc/files/lib/RealFormat_rb.html +1 -1
  190. data/doc/files/lib/ResourceScenario_rb.html +1 -1
  191. data/doc/files/lib/Resource_rb.html +1 -1
  192. data/doc/files/lib/RichTextDocument_rb.html +1 -1
  193. data/doc/files/lib/RichTextElement_rb.html +1 -1
  194. data/doc/files/lib/RichTextParser_rb.html +1 -1
  195. data/doc/files/lib/RichTextProtocolExample_rb.html +1 -1
  196. data/doc/files/lib/RichTextProtocolHandler_rb.html +1 -1
  197. data/doc/files/lib/RichTextScanner_rb.html +1 -1
  198. data/doc/files/lib/RichTextSnip_rb.html +1 -1
  199. data/doc/files/lib/RichTextSyntaxRules_rb.html +1 -1
  200. data/doc/files/lib/RichText_rb.html +1 -1
  201. data/doc/files/lib/ScenarioData_rb.html +1 -1
  202. data/doc/files/lib/Scenario_rb.html +1 -1
  203. data/doc/files/lib/Scoreboard_rb.html +1 -1
  204. data/doc/files/lib/ShiftAssignments_rb.html +1 -1
  205. data/doc/files/lib/ShiftScenario_rb.html +1 -1
  206. data/doc/files/lib/Shift_rb.html +1 -1
  207. data/doc/files/lib/SourceFileInfo_rb.html +1 -1
  208. data/doc/files/lib/SyntaxReference_rb.html +1 -1
  209. data/doc/files/lib/TOCEntry_rb.html +1 -1
  210. data/doc/files/lib/TableColumnDefinition_rb.html +1 -1
  211. data/doc/files/lib/TableOfContents_rb.html +1 -1
  212. data/doc/files/lib/TaskDependency_rb.html +1 -1
  213. data/doc/files/lib/TaskJuggler_rb.html +1 -1
  214. data/doc/files/lib/TaskScenario_rb.html +1 -1
  215. data/doc/files/lib/Task_rb.html +1 -1
  216. data/doc/files/lib/TextParser/Pattern_rb.html +1 -1
  217. data/doc/files/lib/TextParser/Rule_rb.html +1 -1
  218. data/doc/files/lib/TextParser/StackElement_rb.html +1 -1
  219. data/doc/files/lib/TextParser/TokenDoc_rb.html +1 -1
  220. data/doc/files/lib/TextParser_rb.html +1 -1
  221. data/doc/files/lib/TextScanner_rb.html +1 -1
  222. data/doc/files/lib/Tj3Config_rb.html +1 -1
  223. data/doc/files/lib/TjException_rb.html +1 -1
  224. data/doc/files/lib/TjTime_rb.html +1 -1
  225. data/doc/files/lib/TjpExample_rb.html +1 -1
  226. data/doc/files/lib/TjpSyntaxRules_rb.html +1 -1
  227. data/doc/files/lib/UTF8String_rb.html +1 -1
  228. data/doc/files/lib/UserManual_rb.html +1 -1
  229. data/doc/files/lib/WorkingHours_rb.html +1 -1
  230. data/doc/files/lib/XMLDocument_rb.html +1 -1
  231. data/doc/files/lib/XMLElement_rb.html +1 -1
  232. data/doc/files/lib/deep_copy_rb.html +106 -0
  233. data/doc/files/lib/ms_test_rb.html +90 -0
  234. data/doc/files/lib/reports/CSVFile_rb.html +1 -1
  235. data/doc/files/lib/reports/ColumnTable_rb.html +1 -1
  236. data/doc/files/lib/reports/GanttChart_rb.html +1 -1
  237. data/doc/files/lib/reports/GanttContainer_rb.html +1 -1
  238. data/doc/files/lib/reports/GanttHeaderScaleItem_rb.html +1 -1
  239. data/doc/files/lib/reports/GanttHeader_rb.html +1 -1
  240. data/doc/files/lib/reports/GanttLine_rb.html +1 -1
  241. data/doc/files/lib/reports/GanttLoadStack_rb.html +1 -1
  242. data/doc/files/lib/reports/GanttMilestone_rb.html +1 -1
  243. data/doc/files/lib/reports/GanttRouter_rb.html +1 -1
  244. data/doc/files/lib/reports/GanttTaskBar_rb.html +1 -1
  245. data/doc/files/lib/reports/HTMLGraphics_rb.html +1 -1
  246. data/doc/files/lib/reports/{ReportElement_rb.html → Navigator_rb.html} +6 -8
  247. data/doc/files/lib/reports/ReportBase_rb.html +106 -0
  248. data/doc/files/lib/reports/ReportContext_rb.html +106 -0
  249. data/doc/files/lib/reports/ReportTableCell_rb.html +1 -1
  250. data/doc/files/lib/reports/ReportTableColumn_rb.html +1 -1
  251. data/doc/files/lib/reports/ReportTableLegend_rb.html +1 -1
  252. data/doc/files/lib/reports/ReportTableLine_rb.html +1 -1
  253. data/doc/files/lib/reports/ReportTable_rb.html +1 -1
  254. data/doc/files/lib/reports/Report_rb.html +8 -2
  255. data/doc/files/lib/reports/ResourceListRE_rb.html +2 -2
  256. data/doc/files/lib/reports/{ReportTableElement_rb.html → TableReport_rb.html} +7 -5
  257. data/doc/files/lib/reports/TaskListRE_rb.html +2 -2
  258. data/doc/files/lib/reports/TextReport_rb.html +116 -0
  259. data/doc/files/lib/reports/TjpExportRE_rb.html +2 -2
  260. data/doc/files/lib/taskjuggler3_rb.html +61 -56
  261. data/doc/files/lib/tj3man_rb.html +1 -1
  262. data/doc/fr_class_index.html +41 -3
  263. data/doc/fr_file_index.html +21 -5
  264. data/doc/fr_method_index.html +1069 -959
  265. data/examples/ContactList.html +1467 -0
  266. data/examples/Deliveries.html +485 -0
  267. data/examples/Development.html +2525 -0
  268. data/examples/Overview.html +747 -0
  269. data/examples/Resource Graph.html +616 -0
  270. data/examples/tutorial.tjp +63 -67
  271. data/lib/AttributeBase.rb +27 -31
  272. data/lib/AttributeDefinition.rb +12 -7
  273. data/lib/Attributes.rb +134 -34
  274. data/lib/Interval.rb +2 -0
  275. data/lib/Journal.rb +44 -0
  276. data/lib/{LogicalFlag.rb → KeywordArray.rb} +5 -13
  277. data/lib/KeywordDocumentation.rb +84 -47
  278. data/lib/Limits.rb +7 -5
  279. data/lib/LogicalExpression.rb +1 -1
  280. data/lib/LogicalOperation.rb +33 -0
  281. data/lib/Project.rb +313 -99
  282. data/lib/ProjectFileParser.rb +88 -11
  283. data/lib/PropertyList.rb +2 -1
  284. data/lib/PropertySet.rb +13 -4
  285. data/lib/PropertyTreeNode.rb +34 -15
  286. data/lib/Query.rb +2 -1
  287. data/lib/RTPNavigator.rb +53 -0
  288. data/lib/RTPReport.rb +62 -0
  289. data/lib/RealFormat.rb +28 -10
  290. data/lib/RichTextElement.rb +18 -12
  291. data/lib/RichTextParser.rb +1 -0
  292. data/lib/RichTextProtocolExample.rb +8 -11
  293. data/lib/RichTextProtocolHandler.rb +11 -1
  294. data/lib/RichTextScanner.rb +308 -164
  295. data/lib/RichTextSyntaxRules.rb +24 -0
  296. data/lib/TableColumnDefinition.rb +5 -1
  297. data/lib/TaskJuggler.rb +3 -2
  298. data/lib/TaskScenario.rb +123 -31
  299. data/lib/TextParser.rb +14 -3
  300. data/lib/TextScanner.rb +210 -34
  301. data/lib/Tj3Config.rb +1 -1
  302. data/lib/TjTime.rb +15 -0
  303. data/lib/TjpExample.rb +1 -1
  304. data/lib/TjpSyntaxRules.rb +674 -473
  305. data/lib/WorkingHours.rb +1 -1
  306. data/lib/XMLElement.rb +11 -3
  307. data/lib/deep_copy.rb +72 -0
  308. data/lib/ms_test.rb +27 -0
  309. data/lib/reports/ColumnTable.rb +7 -5
  310. data/lib/reports/GanttChart.rb +60 -34
  311. data/lib/reports/GanttHeader.rb +1 -1
  312. data/lib/reports/GanttRouter.rb +7 -5
  313. data/lib/reports/Navigator.rb +72 -0
  314. data/lib/reports/Report.rb +58 -73
  315. data/lib/reports/ReportBase.rb +241 -0
  316. data/lib/reports/ReportContext.rb +41 -0
  317. data/lib/reports/ReportTable.rb +7 -2
  318. data/lib/reports/ReportTableCell.rb +3 -3
  319. data/lib/reports/ResourceListRE.rb +19 -26
  320. data/lib/reports/{ReportTableElement.rb → TableReport.rb} +297 -97
  321. data/lib/reports/TaskListRE.rb +16 -24
  322. data/lib/reports/TextReport.rb +87 -0
  323. data/lib/reports/TjpExportRE.rb +55 -50
  324. data/lib/taskjuggler3.rb +6 -1
  325. data/manual/Getting_Started +57 -6
  326. data/manual/How_To_Contribute +2 -4
  327. data/manual/Intro +2 -2
  328. data/manual/Reporting_Bugs +9 -2
  329. data/manual/Rich_Text_Attributes +41 -0
  330. data/manual/Tutorial +219 -173
  331. data/tasks/test.rake +3 -0
  332. data/test/TestSuite/CSV-Reports/celltext.tjp +2 -1
  333. data/test/TestSuite/CSV-Reports/resourcereport.tjp +2 -1
  334. data/test/TestSuite/CSV-Reports/resourcereport_with_tasks.tjp +2 -1
  335. data/test/TestSuite/CSV-Reports/sortByTree.tjp +2 -1
  336. data/test/TestSuite/CSV-Reports/sortBy_duration.down.tjp +2 -1
  337. data/test/TestSuite/CSV-Reports/sortBy_effort.up.tjp +2 -1
  338. data/test/TestSuite/CSV-Reports/sortBy_plan.start.down.tjp +2 -1
  339. data/test/TestSuite/CSV-Reports/taskreport.tjp +2 -1
  340. data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +2 -1
  341. data/test/TestSuite/HTML-Reports/depArrows.tjp +72 -0
  342. data/test/TestSuite/HTML-Reports/reference-export.html +187 -0
  343. data/test/TestSuite/HTML-Reports/reference.tjp +21 -0
  344. data/test/TestSuite/Scheduler/Correct/Allocate.tjp +2 -1
  345. data/test/TestSuite/Scheduler/Correct/AutomaticMilestones.tjp +3 -3
  346. data/test/TestSuite/Scheduler/Correct/Booking.tjp +3 -3
  347. data/test/TestSuite/Scheduler/Correct/Container-2.tjp +37 -0
  348. data/test/TestSuite/Scheduler/Correct/Container.tjp +40 -0
  349. data/test/TestSuite/Scheduler/Correct/Depends.tjp +9 -14
  350. data/test/TestSuite/Scheduler/Correct/Duration.tjp +2 -1
  351. data/test/TestSuite/Scheduler/Correct/InheritStartEnd.tjp +20 -29
  352. data/test/TestSuite/Scheduler/Correct/Limits.tjp +11 -13
  353. data/test/TestSuite/Scheduler/Correct/Optimize-1.tjp +6 -5
  354. data/test/TestSuite/Scheduler/Correct/Optimize-2.tjp +10 -6
  355. data/test/TestSuite/Scheduler/Correct/Optimize-3.tjp +9 -6
  356. data/test/TestSuite/Scheduler/Correct/Optimize-4.tjp +9 -6
  357. data/test/TestSuite/Scheduler/Correct/Optimize-5.tjp +13 -10
  358. data/test/TestSuite/Scheduler/Correct/Precedes.tjp +9 -14
  359. data/test/TestSuite/Scheduler/Correct/Shift.tjp +9 -8
  360. data/test/TestSuite/Scheduler/Correct/checks.tji +4 -0
  361. data/test/TestSuite/Scheduler/Errors/weak_end_dep.tjp +16 -0
  362. data/test/TestSuite/Scheduler/Errors/weak_start_dep.tjp +16 -0
  363. data/test/TestSuite/Syntax/Correct/Account.tjp +1 -1
  364. data/test/TestSuite/Syntax/Correct/AutoID.tjp +21 -0
  365. data/test/TestSuite/Syntax/Correct/AutoMacros.tjp +2 -1
  366. data/test/TestSuite/Syntax/Correct/Caption.tjp +7 -6
  367. data/test/TestSuite/Syntax/Correct/Celltext.tjp +7 -4
  368. data/test/TestSuite/Syntax/Correct/Comments.tjp +1 -1
  369. data/test/TestSuite/Syntax/Correct/CompletedWork.tji +11 -19
  370. data/test/TestSuite/Syntax/Correct/CriticalPath.tjp +4 -3
  371. data/test/TestSuite/Syntax/Correct/Export.tjp +3 -1
  372. data/test/TestSuite/Syntax/Correct/Flags.tjp +2 -1
  373. data/test/TestSuite/Syntax/Correct/HtmlTaskReport.tjp +2 -1
  374. data/test/TestSuite/Syntax/Correct/Journal.tjp +18 -0
  375. data/test/TestSuite/Syntax/Correct/LoadUnits.tjp +2 -1
  376. data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +16 -0
  377. data/test/TestSuite/Syntax/Correct/Period.tjp +2 -1
  378. data/test/TestSuite/Syntax/Correct/RawHTML.tjp +4 -2
  379. data/test/TestSuite/Syntax/Correct/Reports.tjp +4 -2
  380. data/test/TestSuite/Syntax/Correct/ResourcePrefix.tji +2 -0
  381. data/test/TestSuite/Syntax/Correct/ResourcePrefix.tjp +23 -0
  382. data/test/TestSuite/Syntax/Correct/Responsible.tjp +1 -1
  383. data/test/TestSuite/Syntax/Correct/Simple.tjp +1 -1
  384. data/test/TestSuite/Syntax/Correct/String.tjp +1 -1
  385. data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +2 -1
  386. data/test/TestSuite/Syntax/Correct/tutorial.tjp +92 -70
  387. data/test/TestSuite/Syntax/Errors/bad_comment.tjp +7 -0
  388. data/test/TestSuite/Syntax/Errors/bad_include.tjp +1 -1
  389. data/test/TestSuite/Syntax/Errors/bad_time_zone.tjp +6 -0
  390. data/test/TestSuite/Syntax/Errors/bad_timing_res.tjp +5 -0
  391. data/test/TestSuite/Syntax/Errors/chargeset_master.tjp +1 -1
  392. data/test/TestSuite/Syntax/Errors/container_attribute.tjp +1 -1
  393. data/test/TestSuite/Syntax/Errors/cost_acct_no_top.tjp +3 -2
  394. data/test/TestSuite/Syntax/Errors/cost_rev_same.tjp +1 -1
  395. data/test/TestSuite/Syntax/Errors/eof_in_istring1.tjp +5 -0
  396. data/test/TestSuite/Syntax/Errors/eof_in_istring2.tjp +5 -0
  397. data/test/TestSuite/Syntax/Errors/eof_in_istring3.tjp +6 -0
  398. data/test/TestSuite/Syntax/Errors/eof_in_istring4.tjp +6 -0
  399. data/test/TestSuite/Syntax/Errors/eof_in_istring5.tjp +6 -0
  400. data/test/TestSuite/Syntax/Errors/include_recursion.tji +1 -0
  401. data/test/TestSuite/Syntax/Errors/include_recursion.tjp +7 -0
  402. data/test/TestSuite/Syntax/Errors/junk_after_cut.tjp +6 -0
  403. data/test/TestSuite/Syntax/Errors/navigator_exists.tjp +10 -0
  404. data/test/TestSuite/Syntax/Errors/operand_unkn_flag.tjp +1 -1
  405. data/test/TestSuite/Syntax/Errors/report_end.tjp +1 -1
  406. data/test/TestSuite/Syntax/Errors/report_exists.tjp +10 -0
  407. data/test/TestSuite/Syntax/Errors/report_start.tjp +1 -1
  408. data/test/TestSuite/Syntax/Errors/rev_acct_no_top.tjp +1 -1
  409. data/test/TestSuite/Syntax/Errors/sort_direction.tjp +1 -1
  410. data/test/TestSuite/Syntax/Errors/sort_unknown_scen.tjp +1 -1
  411. data/test/TestSuite/Syntax/Errors/sorting_crit_exptd1.tjp +1 -1
  412. data/test/TestSuite/Syntax/Errors/sorting_crit_exptd2.tjp +1 -1
  413. data/test/TestSuite/Syntax/Errors/sorting_wbs.tjp +1 -1
  414. data/test/TestSuite/Syntax/Errors/too_large_timing_res.tjp +7 -0
  415. data/test/TestSuite/Syntax/Errors/unknown_scenario_idx.tjp +1 -1
  416. data/test/TestSuite/Syntax/Errors/unknown_task.tjp +1 -1
  417. data/test/all.rb +1 -16
  418. data/test/test_CSV-Reports.rb +8 -5
  419. data/test/test_Query.rb +2 -2
  420. data/test/test_RichText.rb +95 -0
  421. data/test/test_Scheduler.rb +8 -4
  422. data/test/test_Syntax.rb +8 -4
  423. data/test/test_deep_copy.rb +83 -0
  424. metadata +549 -487
  425. data/benchmarks/UTF-8-Strings.rb +0 -58
  426. data/doc/classes/TaskJuggler/ReportElement.html +0 -1070
  427. data/doc/classes/TaskJuggler/ReportTableElement.html +0 -644
  428. data/lib/reports/ReportElement.rb +0 -427
  429. data/test/TestSuite/Syntax/Correct/csvtest +0 -16
  430. data/test/TestSuite/Syntax/Errors/no_csv_suffix.tjp +0 -10
  431. data/test/TestSuite/Syntax/Errors/no_html_suffix.tjp +0 -10
  432. data/test/TestSuite/Syntax/Errors/report_redifinition.tjp +0 -10
data/lib/WorkingHours.rb CHANGED
@@ -159,7 +159,7 @@ class TaskJuggler
159
159
  # Return true of the given WorkingHours object +wh+ is identical to this
160
160
  # object.
161
161
  def ==(wh)
162
- return false if @timezone != wh.timezone
162
+ return false if wh.nil? || @timezone != wh.timezone
163
163
 
164
164
  7.times do |d|
165
165
  return false if @days[d].length != wh.days[d].length
data/lib/XMLElement.rb CHANGED
@@ -45,11 +45,19 @@ class TaskJuggler
45
45
  if arg.is_a?(XMLElement)
46
46
  @children << arg
47
47
  elsif arg.is_a?(Array)
48
+ # Delete all nil entries
49
+ arg.delete_if { |i| i.nil? }
50
+ # Check that the rest are really all XMLElement objects.
51
+ arg.each do |i|
52
+ unless i.is_a?(XMLElement)
53
+ raise "Element must be of type XMLElement not #{i.class}"
54
+ end
55
+ end
48
56
  @children += arg
49
57
  elsif arg.nil?
50
58
  # do nothing
51
59
  else
52
- raise 'Elements must be of type XMLElement'
60
+ raise "Elements must be of type XMLElement not #{arg.class}"
53
61
  end
54
62
  self
55
63
  end
@@ -57,8 +65,8 @@ class TaskJuggler
57
65
  # Return the element and all sub elements as properly formatted XML.
58
66
  def to_s(indent = 0)
59
67
  out = '<' + @name
60
- @attributes.each do |attrName, attrValue|
61
- out << ' ' + attrName + '="' + quoteAttr(attrValue) + '"'
68
+ @attributes.keys.sort.each do |attrName|
69
+ out << " #{attrName}=\"#{quoteAttr(@attributes[attrName])}\""
62
70
  end
63
71
  if @children.empty? && !@mayNotBeEmpty
64
72
  out << '/>'
data/lib/deep_copy.rb ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = deep_copy.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
+ # This file extends some Ruby core classes to add deep-copying support. I'm
14
+ # aware of the commonly suggested method using Marshal:
15
+ #
16
+ # class Object
17
+ # def deep_copy
18
+ # Marshal.load(Marshal.dump(self))
19
+ # end
20
+ # end
21
+ #
22
+ # But just because I program in Ruby, I don't have to write bloatware. It's
23
+ # like taking a trip to the moon and back to shop groceries at the store
24
+ # around the corner. I'm not sure if I need more special cases than Array and
25
+ # Hash, but this file works for me.
26
+ #
27
+ # In certain cases the full deep copy may not be desired. To preserve
28
+ # references to objects, you need to overload deep_clone and handle the
29
+ # special cases. Alternatively, an object can be frozen to prevent deep
30
+ # copies.
31
+
32
+ class Object
33
+
34
+ # This is a variant of Object#clone that returns a deep copy of an object.
35
+ def deep_clone
36
+ # We can't clone frozen objects. So just return a reference to them.
37
+ return self if frozen?
38
+
39
+ # In case we have loops in our graph, we return references, not
40
+ # deep-copied objects.
41
+ if RUBY_VERSION < '1.9.0'
42
+ return @clonedObject if instance_variables.include?('@clonedObject')
43
+ else
44
+ return @clonedObject if instance_variables.include?(:@clonedObject)
45
+ end
46
+
47
+ # Clone the current Object (shallow copy with internal state)
48
+ begin
49
+ @clonedObject = clone
50
+ rescue TypeError
51
+ return self
52
+ end
53
+ # Recursively copy all instance variables.
54
+ @clonedObject.instance_variables.each do |var|
55
+ val = instance_variable_get(var).deep_clone
56
+ @clonedObject.instance_variable_set(var, val)
57
+ end
58
+ if kind_of?(Array)
59
+ @clonedObject.collect! { |x| x.deep_clone }
60
+ elsif kind_of?(Hash)
61
+ @clonedObject.each { |key, val| store(key, val.deep_clone) }
62
+ end
63
+ # Remove the @clonedObject again.
64
+ if RUBY_VERSION < '1.9.0'
65
+ remove_instance_variable('@clonedObject')
66
+ else
67
+ remove_instance_variable(:@clonedObject)
68
+ end
69
+ end
70
+
71
+ end
72
+
data/lib/ms_test.rb ADDED
@@ -0,0 +1,27 @@
1
+ project mstest "Milestone test" "1.0" 2009-06-22 +1y {
2
+ extend task {
3
+ reference Url "URL"
4
+ }
5
+ }
6
+
7
+ resource tux "Tux" {
8
+ vacation 2009-06-29 +1.5w
9
+ }
10
+
11
+ task foo "Foo" {
12
+ task post_ms "Post MS" {
13
+ start 2009-06-22
14
+ }
15
+ task milestone "MS" {
16
+ effort 10d
17
+ allocate tux
18
+ Url "http://www.amd64.org"
19
+ }
20
+ }
21
+
22
+ resourcereport mstest "mstest" {
23
+ formats html
24
+ period 2009-06-25 +2m
25
+ columns no, name, weekly
26
+ hidetask 0
27
+ }
@@ -44,19 +44,21 @@ class TaskJuggler
44
44
  # Now we generate a 'div' that will contain the nested table. It has a
45
45
  # height that fits all lines but has a maximum width. In case the embedded
46
46
  # table is larger, a scrollbar will appear. We assume that the scrollbar
47
- # has a height of 18 pixels or less.
47
+ # has a height of SCROLLBARHEIGHT pixels or less.
48
48
  # Due to Firefoxes broken table rendering we have to specify a minimum
49
49
  # width. It may not excede the maxWidth value.
50
50
  mWidth = minWidth
51
51
  mWidth = @maxWidth if mWidth > @maxWidth
52
52
  td << (scrollDiv = XMLElement.new('div', 'class' => 'tabback',
53
53
  'style' => 'position:relative; overflow:auto; ' +
54
- "max-width:#{@maxWidth}px; " +
55
- "min-width:#{mWidth}px; " +
54
+ "width:#{mWidth}px; " +
56
55
  'margin-top:-1px; margin-bottom:-1px; ' +
57
- "height:#{height + 18 + 2}px;"))
56
+ "height:#{height + SCROLLBARHEIGHT + 2}px;"))
58
57
 
59
- scrollDiv << super
58
+ scrollDiv << (contentDiv = XMLElement.new('div',
59
+ 'style' => 'margin: 0px; padding: 0px; position: absolute; top: 0px;' +
60
+ "left: 0px; width: #{@maxWidth}px; height: #{height}px; "))
61
+ contentDiv << super
60
62
  td
61
63
  end
62
64
 
@@ -27,6 +27,10 @@ class TaskJuggler
27
27
  # created, the user must call generateByWidth or generateByResolution.
28
28
  class GanttChart
29
29
 
30
+ # The height in pixels of a horizontal scrollbar on an HTML page. This
31
+ # value should be large enough to work for all browsers.
32
+ SCROLLBARHEIGHT = 20
33
+
30
34
  include HTMLGraphics
31
35
 
32
36
  attr_reader :start, :end, :now, :weekStartsMonday, :header, :width,
@@ -37,7 +41,7 @@ class TaskJuggler
37
41
  # more information about the chart before we can actually generate it. _now_
38
42
  # is the date that should be used as current date. _weekStartsMonday_ is
39
43
  # true if the weeks should start on Mondays instead of Sundays. _table_ is a
40
- # reference to the ReportTableElement that the chart is part of.
44
+ # reference to the TableReport that the chart is part of.
41
45
  def initialize(now, weekStartsMonday, table = nil)
42
46
  # The start and end dates of the reported interval.
43
47
  @start = nil
@@ -146,15 +150,17 @@ class TaskJuggler
146
150
  'style' => 'padding:0px; vertical-align:top;')
147
151
  # Now we generate two 'div's nested into each other. The first div is the
148
152
  # view. It may contain a scrollbar if the second div is wider than the
149
- # first one. In case we need a scrollbar The outer div is 18 pixels
150
- # heigher to hold the scrollbar. Unfortunately this must be a hardcoded
151
- # value even though the height of the scrollbar varies from system to
152
- # system. This value should be good enough for most systems.
153
- td << (scrollDiv = XMLElement.new('div',
153
+ # first one. In case we need a scrollbar The outer div is
154
+ # SCROLLBARHEIGHT pixels heigher to hold the scrollbar. Unfortunately
155
+ # this must be a hardcoded value even though the height of the scrollbar
156
+ # varies from system to system. This value should be good enough for
157
+ # most systems.
158
+ td << (scrollDiv = XMLElement.new('div', 'class' => 'tabback',
154
159
  'style' => 'position:relative; ' +
155
160
  "overflow:auto; " +
156
161
  "width:#{hasScrollbar? ? @viewWidth : @width}px; " +
157
- "height:#{@height + (hasScrollbar? ? 18 : 0)}px;"))
162
+ "height:#{@height +
163
+ (hasScrollbar? ? SCROLLBARHEIGHT : 0)}px;"))
158
164
  scrollDiv << (div = XMLElement.new('div',
159
165
  'style' => "margin:0px; padding:0px; " +
160
166
  "position:absolute; " +
@@ -244,7 +250,7 @@ class TaskJuggler
244
250
  @router.addZone(@header.nowLineX - 1, 0, 3, @height - 1, false, true)
245
251
 
246
252
  @tasks.each do |task, lines|
247
- generateDepArrow(task, lines)
253
+ generateDepArrows(task, lines)
248
254
  end
249
255
  end
250
256
 
@@ -252,41 +258,61 @@ class TaskJuggler
252
258
  # for a specific _task_. _lines_ is a list of GanttLines that the tasks are
253
259
  # displayed on. Reports with multiple scenarios have multiple lines per
254
260
  # task.
255
- def generateDepArrow(task, lines)
261
+ def generateDepArrows(task, lines)
256
262
  # Since we need the line and the index we use an index iterator.
257
263
  lines.length.times do |lineIndex|
258
264
  line = lines[lineIndex]
259
265
  scenarioIdx = line.scenarioIdx
260
266
 
261
267
  # Generate the dependencies on the start of the task.
262
- startX, startY = line.getTask.startDepLineStart
263
- task['startsuccs', scenarioIdx].each do |t, onEnd|
264
- # Skip inherited dependencies and tasks that are not included in the
265
- # chart.
266
- if (t.parent &&
267
- task.hasDependency?(scenarioIdx, 'startsuccs', t.parent, onEnd)) ||
268
- !@tasks.include?(t)
269
- next
270
- end
271
- endX, endY = @tasks[t][lineIndex].getTask.send(
272
- onEnd ? :endDepLineEnd : :startDepLineEnd)
273
- routeArrow(startX, startY, endX, endY)
274
- end
268
+ collectAndSortArrows('startsuccs', task, scenarioIdx, lineIndex,
269
+ *line.getTask.startDepLineStart)
275
270
 
276
271
  # Generate the dependencies on the end of the task.
277
- startX, startY = line.getTask.endDepLineStart
278
- task['endsuccs', scenarioIdx].each do |t, onEnd|
279
- # Skip inherited dependencies and tasks that are not included in the
280
- # chart.
281
- if (t.parent &&
282
- task.hasDependency?(scenarioIdx, 'endsuccs', t.parent, onEnd)) ||
283
- !@tasks.include?(t)
284
- next
285
- end
286
- endX, endY = @tasks[t][lineIndex].getTask.send(
287
- onEnd ? :endDepLineEnd : :startDepLineEnd)
288
- routeArrow(startX, startY, endX, endY)
272
+ collectAndSortArrows('endsuccs', task, scenarioIdx, lineIndex,
273
+ *line.getTask.endDepLineStart)
274
+ end
275
+ end
276
+
277
+ # Generate the dependencies on the start or end of the task depending on
278
+ # _kind_. Use 'startsuccs' for the start and 'endsuccs' for end. _startX_
279
+ # and _startY_ are the graphic coordinates for the begin of the arrow
280
+ # line. _task_ references the Task in question and _scenarioIdx_ the
281
+ # scenario. _lineIndex_ specifies the line number in the chart.
282
+ def collectAndSortArrows(kind, task, scenarioIdx, lineIndex, startX, startY)
283
+ # We need to sort the arrows. This is an Array that holds 6 values for
284
+ # each entry: The x and y coordinates for start and end points, the
285
+ # sinus value of the angle between a vertical and the line specified by
286
+ # the points and the length of the line.
287
+ touples = []
288
+ task[kind, scenarioIdx].each do |t, onEnd|
289
+ # Skip inherited dependencies and tasks that are not included in the
290
+ # chart.
291
+ if (t.parent &&
292
+ task.hasDependency?(scenarioIdx, kind, t.parent, onEnd)) ||
293
+ !@tasks.include?(t)
294
+ next
289
295
  end
296
+ endX, endY = @tasks[t][lineIndex].getTask.send(
297
+ onEnd ? :endDepLineEnd : :startDepLineEnd)
298
+ # To make sure that we minimize the crossings of arrows that
299
+ # originate from the same position, we sort the arrows by the
300
+ # smallest angle between the vertical line through the task end
301
+ # and the line between the start and end of the arrow.
302
+ oppLeg = endX - startX
303
+ adjLeg = (startY - endY).abs
304
+ hypothenuse = Math.sqrt(adjLeg ** 2 + oppLeg ** 2)
305
+ # We can now calculate the sinus values of the angle between the
306
+ # vertical and a line through the coordinates.
307
+ touples << [ startX, startY, endX, endY,
308
+ (oppLeg / hypothenuse), hypothenuse ]
309
+ end
310
+ # We sort the arrows from small to a large angle. In case the angle is
311
+ # identical, we use the length of the line as second criteria.
312
+ touples.sort! { |t1, t2| t1[4] == t2[4] ? t1[5] <=> t2[5] :
313
+ t1[4] <=> t2[4] }
314
+ touples.each do |t|
315
+ routeArrow(*t[0, 4])
290
316
  end
291
317
  end
292
318
 
@@ -74,7 +74,7 @@ class TaskJuggler
74
74
  :hour)
75
75
  when 'day'
76
76
  genHeaderScale(@largeScale, 0, h, :beginOfMonth, :sameTimeNextMonth,
77
- :shortMonthName)
77
+ :monthAndYear)
78
78
  genHeaderScale(@smallScale, h + 1, h, :midnight, :sameTimeNextDay, :day)
79
79
  when 'week'
80
80
  genHeaderScale(@largeScale, 0, h, :beginOfMonth, :sameTimeNextMonth,
@@ -93,7 +93,8 @@ class TaskJuggler
93
93
  # 2------X end Point
94
94
  # |endGap|
95
95
  #
96
- xSeg = placeLine([ startPoint[1], endPoint[1] ],
96
+ xSeg = placeLine([ startPoint[1] + (startPoint[1] < endPoint[1] ?
97
+ 1 : -1), endPoint[1] ],
97
98
  false, startPoint[0] + startGap, 1)
98
99
  if xSeg && xSeg < endPoint[0] - endGap
99
100
  addLineTo(points, xSeg, startPoint[1]) # Point 1
@@ -108,7 +109,7 @@ class TaskJuggler
108
109
  #
109
110
  # x1
110
111
  # |startGap|
111
- # startPoint X--------1
112
+ # startPoint X--------1 yLS
112
113
  # |
113
114
  # 3---------------2 ySeg
114
115
  # |
@@ -119,11 +120,12 @@ class TaskJuggler
119
120
  # Place horizontal segue. We don't know the width yet, so we have to
120
121
  # assume full width. That's acceptable for horizontal lines.
121
122
  ySeg = placeLine([ 0, @width - 1 ], true, startPoint[1],
122
- startPoint[1] < endPoint[1] ? 1 : -1)
123
+ startPoint[1] < endPoint[1] ? 1 : -1)
123
124
  raise "Routing failed" unless ySeg
124
125
 
125
126
  # Place 1st vertical
126
- x1 = placeLine([ startPoint[1], ySeg ], false, startPoint[0] + startGap, 1)
127
+ x1 = placeLine([ startPoint[1] + (startPoint[1] < endPoint[1] ? 1 : -1),
128
+ ySeg ], false, startPoint[0] + startGap, 1)
127
129
  raise "Routing failed" unless x1
128
130
 
129
131
  # Place 2nd vertical
@@ -297,7 +299,7 @@ class TaskJuggler
297
299
  segment.sort!
298
300
  lines = horizontal ? @hLines : @vLines
299
301
  # TODO: Remove this check once the code becomes stable.
300
- checkLines(lines)
302
+ #checkLines(lines)
301
303
  while collision?(lines[pos], segment)
302
304
  pos += delta
303
305
  # Check if we have exceded the chart area towards top/left.
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = Navigator.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
+ require 'reports/ReportContext'
14
+
15
+ class TaskJuggler
16
+
17
+ class Navigator
18
+
19
+ attr_reader :id
20
+ attr_accessor :hideReport
21
+
22
+ def initialize(id, project)
23
+ @id = id
24
+ @project = project
25
+ @hideReport = LogicalExpression.new(LogicalOperation.new(0))
26
+ end
27
+
28
+ def to_html
29
+ reports = filterReports
30
+ return nil if reports.empty?
31
+
32
+ first = true
33
+ html = []
34
+ html << (div = XMLElement.new('div'))
35
+ reports.each do |report|
36
+ next unless report.get('formats').include?(:html)
37
+
38
+ if first
39
+ first = false
40
+ else
41
+ div << XMLText.new('|')
42
+ end
43
+ if report == @project.reportContext.report
44
+ div << (span = XMLElement.new('span',
45
+ 'style' => 'class:navbar_current'))
46
+ span << XMLText.new(report.name)
47
+ else
48
+ div << (span = XMLElement.new('span', 'style' => 'class:navbar_other'))
49
+ span << (a = XMLElement.new('a', 'href' => report.name + '.html'))
50
+ a << XMLText.new(report.name)
51
+ end
52
+ end
53
+ html
54
+ end
55
+
56
+ private
57
+
58
+ def filterReports
59
+ list = PropertyList.new(@project.reports)
60
+ list.setSorting([[ 'seqno', true, -1 ]])
61
+ list.sort!
62
+ # Remove all reports that the user doesn't want to have include.
63
+ list.delete_if do |property|
64
+ @hideReport.eval(property, nil)
65
+ end
66
+ list
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+
@@ -10,71 +10,33 @@
10
10
  # published by the Free Software Foundation.
11
11
  #
12
12
 
13
- require 'reports/ReportElement'
13
+ require 'PropertyTreeNode'
14
+ require 'reports/TextReport'
14
15
  require 'reports/TaskListRE'
15
16
  require 'reports/ResourceListRE'
16
17
  require 'reports/TjpExportRE'
17
18
  require 'reports/CSVFile'
19
+ require 'reports/Navigator'
20
+ require 'reports/ReportContext'
18
21
  require 'HTMLDocument'
19
22
 
20
23
  class TaskJuggler
21
24
 
22
- # The Report class holds the fundamental description and functionality to turn
23
- # the scheduled project into a user readable form. A report consists of one or
24
- # more ReportElement objects and some attributes that are global to all
25
- # elements.
26
- class Report
25
+ # The Report class holds the fundamental description and functionality to
26
+ # turn the scheduled project into a user readable form. A report may contain
27
+ # other reports.
28
+ class Report < PropertyTreeNode
27
29
 
28
- attr_reader :name, :project, :start, :end, :userDefinedPeriod,
29
- :sourceFileInfo
30
- attr_accessor :costAccount, :currencyformat, :loadUnit, :now,
31
- :numberformat, :resourceRoot, :revenueAccount,
32
- :shorttimeformat, :taskRoot, :timeformat, :timezone,
33
- :weekstartsmonday
30
+ attr_accessor :typeSpec, :content
34
31
 
35
32
  # Create a new report object.
36
- def initialize(project, name, format, sourceFileInfo)
37
- @project = project
38
- @name = name
39
- @project.addReport(self)
40
- @outputFormats = [ format ]
41
- @sourceFileInfo = sourceFileInfo
33
+ def initialize(project, id, name, parent)
34
+ super(project.reports, id, name, parent)
35
+ project.addReport(self)
42
36
 
43
- # The following attributes determine the content and look of the report.
44
- @costAccount = @project['costAccount']
45
- @currencyformat = @project['currencyformat']
46
- @loadUnit = @project['loadunit']
47
- @end = @project['end']
48
- @now = @project['now']
49
- @numberformat = @project['numberformat']
50
- @resourceRoot = nil
51
- @revenueAccount = @project['revenueAccount']
52
- @shorttimeformat = @project['shorttimeformat']
53
- @start = @project['start']
54
- @taskRoot = nil
55
- @timeformat = @project['timeformat']
56
- @timezone = @project['timezone']
57
- @userDefinedPeriod = false
58
- @weekstartsmonday = @project['weekstartsmonday']
59
-
60
- @elements = []
61
- end
62
-
63
- # Set the start _date_ of the report period and mark it as user defined.
64
- def start=(date)
65
- @start = date
66
- @userDefinedPeriod = true
67
- end
68
-
69
- # Set the end _date_ of the report period and mark it as user defined.
70
- def end=(date)
71
- @end = date
72
- @userDefinedPeriod = true
73
- end
74
-
75
- # Add new ouput format request.
76
- def addFormat(format)
77
- @outputFormats << format
37
+ # The type specifier must be set for every report. It tells whether this
38
+ # is a task, resource, text or other report.
39
+ @typeSpec = nil
78
40
  end
79
41
 
80
42
  # The generate function is where the action happens in this class. The
@@ -82,14 +44,26 @@ class TaskJuggler
82
44
  # generated according the the requested output format(s).
83
45
  def generate
84
46
  begin
47
+ @content = nil
48
+ case @typeSpec
49
+ when :export
50
+ # Does not have an intermediate representation. Nothing to do here.
51
+ when :resourcereport
52
+ @content = ResourceListRE.new(self)
53
+ when :textreport
54
+ @content = TextReport.new(self)
55
+ when :taskreport
56
+ @content = TaskListRE.new(self)
57
+ else
58
+ raise "Unknown report type"
59
+ end
60
+
85
61
  # Most output format can be generated from a common intermediate
86
62
  # representation of the elements. We generate that IR first.
87
- @elements.each do |element|
88
- element.generateIntermediateFormat
89
- end
63
+ @content.generateIntermediateFormat if @content
90
64
 
91
65
  # Then generate the actual output format.
92
- @outputFormats.each do |format|
66
+ get('formats').each do |format|
93
67
  case format
94
68
  when :html
95
69
  generateHTML
@@ -97,8 +71,6 @@ class TaskJuggler
97
71
  generateCSV
98
72
  when :export
99
73
  generateExport
100
- when :gui
101
- # TODO: Find a way to hook up the GUI here.
102
74
  else
103
75
  raise 'Unknown report output format.'
104
76
  end
@@ -110,13 +82,17 @@ class TaskJuggler
110
82
  end
111
83
  end
112
84
 
113
- # This function should only be called within the library. It's not a user
114
- # callable function.
115
- def addElement(element) # :nodoc:
116
- @elements << element
85
+ # Render the content of the report as HTML (without the framing).
86
+ def to_html
87
+ @content ? @content.to_html : nil
117
88
  end
118
89
 
90
+
119
91
  private
92
+ # Convenience function to access a report attribute
93
+ def a(attribute)
94
+ get(attribute)
95
+ end
120
96
 
121
97
  # Generate an HTML version of the report.
122
98
  def generateHTML
@@ -180,6 +156,7 @@ class TaskJuggler
180
156
  .tabline { color:#000000 }
181
157
  .tabcell {
182
158
  white-space:nowrap;
159
+ overflow:hidden;
183
160
  padding:0px;
184
161
  }
185
162
  .taskcell1 {
@@ -246,7 +223,7 @@ class TaskJuggler
246
223
  position:absolute;
247
224
  }
248
225
  .free {
249
- background-color:#a5ffb4;
226
+ background-color:#a5ffb5;
250
227
  position:absolute;
251
228
  }
252
229
  .busy {
@@ -286,17 +263,22 @@ EOT
286
263
  )
287
264
  html << (body = XMLElement.new('body'))
288
265
 
289
- @elements.each do |element|
290
- body << element.to_html
291
- end
266
+ # Make sure we have some margins around the report.
267
+ body << (frame = XMLElement.new('div',
268
+ 'style' => 'margin: 35px 5% 25px 5%; '))
292
269
 
293
- html.write(@name + '.html')
270
+ frame << @content.to_html if @content
271
+
272
+ html.write((@name[0] == '/' ? '' : @project.outputDir) +
273
+ @name + (@name == '.' ? '' : '.html'))
294
274
  end
295
275
 
296
276
  # Generate a CSV version of the report.
297
277
  def generateCSV
278
+ return nil unless @content
279
+
298
280
  # CSV format can only handle the first element.
299
- csv = @elements[0].to_csv
281
+ csv = @content.to_csv
300
282
  # Expand nested tables into the outer table.
301
283
  columnIdx = 0
302
284
  while columnIdx < csv[0].length do
@@ -328,14 +310,17 @@ EOT
328
310
 
329
311
  # Use the CSVFile class to write the Array of Arrays to a colon
330
312
  # separated file. Write to $stdout if the filename was set to '.'.
331
- CSVFile.new(csv, ';').write(@name)
313
+ CSVFile.new(csv, ';').write((@name[0] == '/' ? '' : @project.outputDir) +
314
+ @name + (@name == '.' ? '' : '.csv'))
332
315
  end
333
316
 
334
317
  # Generate an export report
335
318
  def generateExport
336
- extension = @elements[0].mainFile ? 'tjp' : 'tji'
337
- f = @name == '.' ? $stdout : File.new(@name + '.' + extension, 'w')
338
- f.puts "#{@elements[0].to_tjp}"
319
+ @content = TjpExportRE.new(self)
320
+ f = @name == '.' ? $stdout :
321
+ File.new((@name[0] == '/' ? '' : @project.outputDir) +
322
+ @name, 'w')
323
+ f.puts "#{@content.to_tjp}"
339
324
  end
340
325
 
341
326
  end