taskjuggler 0.0.7 → 0.0.8

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 (415) hide show
  1. data/CHANGELOG +119 -0
  2. data/benchmarks/allocatedSlots.tjp +1602 -0
  3. data/benchmarks/booking.tjp +40 -30
  4. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/css/tjmanual.css +0 -0
  5. data/{test/TestSuite/Scheduler/Correct → benchmarks}/css/tjreport.css +1 -0
  6. data/benchmarks/gantt.tjp +57 -0
  7. data/benchmarks/htmltaskreport.tjp +26 -1
  8. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/details.png +0 -0
  9. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-green.png +0 -0
  10. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-red.png +0 -0
  11. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-yellow.png +0 -0
  12. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resource.png +0 -0
  13. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resourcegroup.png +0 -0
  14. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/task.png +0 -0
  15. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/taskgroup.png +0 -0
  16. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-down.png +0 -0
  17. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-flat.png +0 -0
  18. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-up.png +0 -0
  19. data/benchmarks/profile.clt +36082 -0
  20. data/benchmarks/profile.html +58182 -0
  21. data/benchmarks/runbench.rb +6 -0
  22. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/scripts/wz_tooltip.js +0 -0
  23. data/doc/AppConfig.html +85 -37
  24. data/doc/Arguments.html +11 -1
  25. data/doc/CHANGELOG.html +131 -2
  26. data/doc/COPYING.html +11 -1
  27. data/doc/Object.html +12 -3
  28. data/doc/README.html +11 -1
  29. data/doc/RuntimeConfig.html +11 -1
  30. data/doc/String.html +11 -1
  31. data/doc/StringIO.html +11 -1
  32. data/doc/TaskJuggler.html +250 -219
  33. data/doc/TaskJuggler/Account.html +11 -1
  34. data/doc/TaskJuggler/AccountAttribute.html +11 -1
  35. data/doc/TaskJuggler/AccountScenario.html +11 -1
  36. data/doc/TaskJuggler/Allocation.html +11 -1
  37. data/doc/TaskJuggler/AllocationAttribute.html +11 -1
  38. data/doc/TaskJuggler/AttributeBase.html +11 -1
  39. data/doc/TaskJuggler/AttributeDefinition.html +11 -1
  40. data/doc/TaskJuggler/BatchProcessor.html +11 -1
  41. data/doc/TaskJuggler/Booking.html +11 -1
  42. data/doc/TaskJuggler/BookingListAttribute.html +11 -1
  43. data/doc/TaskJuggler/BooleanAttribute.html +11 -1
  44. data/doc/TaskJuggler/CSVFile.html +12 -2
  45. data/doc/TaskJuggler/CellSettingPattern.html +11 -1
  46. data/doc/TaskJuggler/CellSettingPatternList.html +11 -1
  47. data/doc/TaskJuggler/Charge.html +11 -1
  48. data/doc/TaskJuggler/ChargeListAttribute.html +11 -1
  49. data/doc/TaskJuggler/ChargeSet.html +11 -1
  50. data/doc/TaskJuggler/ChargeSetListAttribute.html +11 -1
  51. data/doc/TaskJuggler/CollisionDetector.html +1063 -0
  52. data/doc/TaskJuggler/ColumnListAttribute.html +11 -1
  53. data/doc/TaskJuggler/ColumnTable.html +11 -1
  54. data/doc/TaskJuggler/Daemon.html +11 -1
  55. data/doc/TaskJuggler/{OnShiftCache.html → DataCache.html} +127 -139
  56. data/doc/TaskJuggler/DataCacheEntry.html +711 -0
  57. data/doc/TaskJuggler/DateAttribute.html +11 -1
  58. data/doc/TaskJuggler/DefinitionListAttribute.html +11 -1
  59. data/doc/TaskJuggler/DependencyListAttribute.html +11 -1
  60. data/doc/TaskJuggler/DurationAttribute.html +16 -5
  61. data/doc/TaskJuggler/FileList.html +11 -1
  62. data/doc/TaskJuggler/FileRecord.html +11 -1
  63. data/doc/TaskJuggler/FixnumAttribute.html +19 -9
  64. data/doc/TaskJuggler/FlagListAttribute.html +29 -19
  65. data/doc/TaskJuggler/FloatAttribute.html +23 -13
  66. data/doc/TaskJuggler/FormatListAttribute.html +19 -9
  67. data/doc/TaskJuggler/GanttChart.html +94 -133
  68. data/doc/TaskJuggler/GanttContainer.html +11 -1
  69. data/doc/TaskJuggler/GanttHeader.html +11 -1
  70. data/doc/TaskJuggler/GanttHeaderScaleItem.html +11 -1
  71. data/doc/TaskJuggler/GanttLine.html +11 -1
  72. data/doc/TaskJuggler/GanttLoadStack.html +11 -1
  73. data/doc/TaskJuggler/GanttMilestone.html +11 -1
  74. data/doc/TaskJuggler/GanttRouter.html +247 -596
  75. data/doc/TaskJuggler/GanttTaskBar.html +11 -1
  76. data/doc/TaskJuggler/HTMLDocument.html +11 -1
  77. data/doc/TaskJuggler/HTMLGraphics.html +11 -1
  78. data/doc/TaskJuggler/Interval.html +11 -1
  79. data/doc/TaskJuggler/IntervalListAttribute.html +33 -23
  80. data/doc/TaskJuggler/JobInfo.html +11 -1
  81. data/doc/TaskJuggler/Journal.html +11 -1
  82. data/doc/TaskJuggler/JournalEntry.html +11 -1
  83. data/doc/TaskJuggler/JournalEntryList.html +11 -1
  84. data/doc/TaskJuggler/KeywordArray.html +11 -1
  85. data/doc/TaskJuggler/KeywordDocumentation.html +16 -6
  86. data/doc/TaskJuggler/Limits.html +11 -1
  87. data/doc/TaskJuggler/Limits/Limit.html +11 -1
  88. data/doc/TaskJuggler/LimitsAttribute.html +24 -14
  89. data/doc/TaskJuggler/ListAttributeBase.html +11 -1
  90. data/doc/TaskJuggler/Log.html +11 -1
  91. data/doc/TaskJuggler/LogFile.html +11 -1
  92. data/doc/TaskJuggler/LogicalAttribute.html +11 -1
  93. data/doc/TaskJuggler/LogicalExpression.html +11 -1
  94. data/doc/TaskJuggler/LogicalExpressionAttribute.html +19 -9
  95. data/doc/TaskJuggler/LogicalFlag.html +11 -1
  96. data/doc/TaskJuggler/LogicalFunction.html +11 -1
  97. data/doc/TaskJuggler/LogicalOperation.html +11 -1
  98. data/doc/TaskJuggler/Macro.html +11 -1
  99. data/doc/TaskJuggler/MacroTable.html +11 -1
  100. data/doc/TaskJuggler/ManagerResponsibilities.html +11 -1
  101. data/doc/TaskJuggler/ManagerStatusRecord.html +11 -1
  102. data/doc/TaskJuggler/Message.html +11 -1
  103. data/doc/TaskJuggler/MessageHandler.html +11 -1
  104. data/doc/TaskJuggler/Navigator.html +12 -2
  105. data/doc/TaskJuggler/NavigatorElement.html +11 -1
  106. data/doc/TaskJuggler/NikuProject.html +11 -1
  107. data/doc/TaskJuggler/NikuReport.html +11 -1
  108. data/doc/TaskJuggler/NikuResource.html +11 -1
  109. data/doc/TaskJuggler/NodeListAttribute.html +17 -7
  110. data/doc/TaskJuggler/PlaceHolderCell.html +722 -0
  111. data/doc/TaskJuggler/ProcessIntercom.html +11 -1
  112. data/doc/TaskJuggler/ProcessIntercomIface.html +11 -1
  113. data/doc/TaskJuggler/Project.html +587 -500
  114. data/doc/TaskJuggler/ProjectBroker.html +11 -1
  115. data/doc/TaskJuggler/ProjectBrokerIface.html +11 -1
  116. data/doc/TaskJuggler/ProjectFileParser.html +205 -192
  117. data/doc/TaskJuggler/ProjectFileScanner.html +230 -207
  118. data/doc/TaskJuggler/ProjectRecord.html +11 -1
  119. data/doc/TaskJuggler/ProjectServer.html +11 -1
  120. data/doc/TaskJuggler/ProjectServerIface.html +11 -1
  121. data/doc/TaskJuggler/PropertyAttribute.html +19 -9
  122. data/doc/TaskJuggler/PropertyList.html +95 -83
  123. data/doc/TaskJuggler/PropertySet.html +11 -1
  124. data/doc/TaskJuggler/PropertyTreeNode.html +11 -1
  125. data/doc/TaskJuggler/Query.html +234 -232
  126. data/doc/TaskJuggler/RTFHandlers.html +11 -1
  127. data/doc/TaskJuggler/RTFNavigator.html +11 -1
  128. data/doc/TaskJuggler/RTFQuery.html +11 -1
  129. data/doc/TaskJuggler/RTFReport.html +11 -1
  130. data/doc/TaskJuggler/RTFReportLink.html +11 -1
  131. data/doc/TaskJuggler/RTFWithQuerySupport.html +11 -1
  132. data/doc/TaskJuggler/RealFormat.html +12 -2
  133. data/doc/TaskJuggler/RealFormatAttribute.html +15 -5
  134. data/doc/TaskJuggler/ReferenceAttribute.html +38 -28
  135. data/doc/TaskJuggler/Report.html +96 -113
  136. data/doc/TaskJuggler/ReportBase.html +161 -152
  137. data/doc/TaskJuggler/ReportContext.html +11 -1
  138. data/doc/TaskJuggler/ReportServer.html +59 -48
  139. data/doc/TaskJuggler/ReportServerIface.html +51 -41
  140. data/doc/TaskJuggler/ReportServerRecord.html +11 -1
  141. data/doc/TaskJuggler/ReportServlet.html +11 -1
  142. data/doc/TaskJuggler/ReportTable.html +46 -25
  143. data/doc/TaskJuggler/ReportTableCell.html +296 -275
  144. data/doc/TaskJuggler/ReportTableColumn.html +14 -4
  145. data/doc/TaskJuggler/ReportTableLegend.html +11 -1
  146. data/doc/TaskJuggler/ReportTableLine.html +19 -7
  147. data/doc/TaskJuggler/Resource.html +12 -2
  148. data/doc/TaskJuggler/ResourceListAttribute.html +40 -30
  149. data/doc/TaskJuggler/ResourceListRE.html +11 -1
  150. data/doc/TaskJuggler/ResourceScenario.html +708 -565
  151. data/doc/TaskJuggler/RichText.html +54 -36
  152. data/doc/TaskJuggler/RichTextAttribute.html +31 -21
  153. data/doc/TaskJuggler/RichTextDocument.html +11 -1
  154. data/doc/TaskJuggler/RichTextElement.html +11 -1
  155. data/doc/TaskJuggler/RichTextFunctionExample.html +11 -1
  156. data/doc/TaskJuggler/RichTextFunctionHandler.html +11 -1
  157. data/doc/TaskJuggler/RichTextImage.html +11 -1
  158. data/doc/TaskJuggler/RichTextIntermediate.html +81 -71
  159. data/doc/TaskJuggler/RichTextParser.html +88 -33
  160. data/doc/TaskJuggler/RichTextScanner.html +45 -35
  161. data/doc/TaskJuggler/RichTextSnip.html +11 -1
  162. data/doc/TaskJuggler/RichTextSyntaxRules.html +436 -389
  163. data/doc/TaskJuggler/Scenario.html +11 -1
  164. data/doc/TaskJuggler/ScenarioData.html +11 -1
  165. data/doc/TaskJuggler/ScenarioListAttribute.html +23 -13
  166. data/doc/TaskJuggler/Scoreboard.html +92 -73
  167. data/doc/TaskJuggler/SheetHandlerBase.html +11 -1
  168. data/doc/TaskJuggler/SheetReceiver.html +11 -1
  169. data/doc/TaskJuggler/SheetSender.html +11 -1
  170. data/doc/TaskJuggler/Shift.html +11 -1
  171. data/doc/TaskJuggler/ShiftAssignment.html +11 -1
  172. data/doc/TaskJuggler/ShiftAssignments.html +11 -1
  173. data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +24 -14
  174. data/doc/TaskJuggler/ShiftScenario.html +11 -1
  175. data/doc/TaskJuggler/SimpleQueryExpander.html +11 -1
  176. data/doc/TaskJuggler/SortListAttribute.html +21 -11
  177. data/doc/TaskJuggler/SourceFileInfo.html +11 -1
  178. data/doc/TaskJuggler/StatusSheetReceiver.html +11 -1
  179. data/doc/TaskJuggler/StatusSheetReport.html +11 -1
  180. data/doc/TaskJuggler/StatusSheetSender.html +112 -11
  181. data/doc/TaskJuggler/StringAttribute.html +23 -13
  182. data/doc/TaskJuggler/SymbolAttribute.html +19 -9
  183. data/doc/TaskJuggler/SyntaxReference.html +80 -71
  184. data/doc/TaskJuggler/TOCEntry.html +11 -1
  185. data/doc/TaskJuggler/TSResourceRecord.html +11 -1
  186. data/doc/TaskJuggler/TSTaskRecord.html +11 -1
  187. data/doc/TaskJuggler/TableColumnDefinition.html +11 -1
  188. data/doc/TaskJuggler/TableOfContents.html +11 -1
  189. data/doc/TaskJuggler/TableReport.html +422 -411
  190. data/doc/TaskJuggler/Task.html +11 -1
  191. data/doc/TaskJuggler/TaskDependency.html +11 -1
  192. data/doc/TaskJuggler/TaskListAttribute.html +33 -23
  193. data/doc/TaskJuggler/TaskListRE.html +11 -1
  194. data/doc/TaskJuggler/TaskScenario.html +2007 -1919
  195. data/doc/TaskJuggler/TextFormatter.html +11 -1
  196. data/doc/TaskJuggler/TextParser.html +421 -612
  197. data/doc/TaskJuggler/TextParser/Pattern.html +410 -211
  198. data/doc/TaskJuggler/TextParser/Rule.html +224 -152
  199. data/doc/TaskJuggler/TextParser/StackElement.html +190 -28
  200. data/doc/TaskJuggler/TextParser/State.html +989 -0
  201. data/doc/TaskJuggler/TextParser/StateTransition.html +782 -0
  202. data/doc/TaskJuggler/TextParser/TextParserResultArray.html +25 -14
  203. data/doc/TaskJuggler/TextParser/TokenDoc.html +11 -1
  204. data/doc/TaskJuggler/TextReport.html +11 -1
  205. data/doc/TaskJuggler/TextScanner.html +285 -273
  206. data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +17 -7
  207. data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +24 -14
  208. data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +11 -1
  209. data/doc/TaskJuggler/TextScanner/StreamHandle.html +64 -52
  210. data/doc/TaskJuggler/TimeSheet.html +11 -1
  211. data/doc/TaskJuggler/TimeSheetReceiver.html +11 -1
  212. data/doc/TaskJuggler/TimeSheetRecord.html +11 -1
  213. data/doc/TaskJuggler/TimeSheetReport.html +11 -1
  214. data/doc/TaskJuggler/TimeSheetSender.html +11 -1
  215. data/doc/TaskJuggler/TimeSheetSummary.html +11 -1
  216. data/doc/TaskJuggler/TimeSheets.html +11 -1
  217. data/doc/TaskJuggler/Tj3AppBase.html +11 -1
  218. data/doc/TaskJuggler/Tj3Client.html +11 -1
  219. data/doc/TaskJuggler/Tj3Daemon.html +11 -1
  220. data/doc/TaskJuggler/Tj3SheetAppBase.html +11 -1
  221. data/doc/TaskJuggler/Tj3SsReceiver.html +11 -1
  222. data/doc/TaskJuggler/Tj3SsSender.html +11 -1
  223. data/doc/TaskJuggler/Tj3TsReceiver.html +11 -1
  224. data/doc/TaskJuggler/Tj3TsSender.html +11 -1
  225. data/doc/TaskJuggler/Tj3TsSummary.html +11 -1
  226. data/doc/TaskJuggler/TjException.html +11 -1
  227. data/doc/TaskJuggler/TjTime.html +474 -324
  228. data/doc/TaskJuggler/TjpExample.html +11 -1
  229. data/doc/TaskJuggler/TjpExportRE.html +11 -1
  230. data/doc/TaskJuggler/TjpSyntaxRules.html +3731 -3662
  231. data/doc/TaskJuggler/URLParameter.html +11 -1
  232. data/doc/TaskJuggler/UserManual.html +11 -1
  233. data/doc/TaskJuggler/VimSyntax.html +11 -1
  234. data/doc/TaskJuggler/WebServer.html +11 -1
  235. data/doc/TaskJuggler/WorkingHours.html +295 -221
  236. data/doc/TaskJuggler/WorkingHoursAttribute.html +11 -1
  237. data/doc/TaskJuggler/XMLBlob.html +11 -1
  238. data/doc/TaskJuggler/XMLComment.html +11 -1
  239. data/doc/TaskJuggler/XMLDocument.html +11 -1
  240. data/doc/TaskJuggler/XMLElement.html +11 -1
  241. data/doc/TaskJuggler/XMLNamedText.html +11 -1
  242. data/doc/TaskJuggler/XMLText.html +11 -1
  243. data/doc/index.html +694 -624
  244. data/doc/lib/AppConfig_rb.html +1 -1
  245. data/doc/lib/Attributes_rb.html +1 -1
  246. data/doc/lib/Booking_rb.html +1 -1
  247. data/doc/lib/DataCache_rb.html +69 -0
  248. data/doc/lib/KeywordDocumentation_rb.html +1 -1
  249. data/doc/lib/ProjectFileParser_rb.html +1 -1
  250. data/doc/lib/ProjectFileScanner_rb.html +1 -1
  251. data/doc/lib/Project_rb.html +1 -1
  252. data/doc/lib/PropertyList_rb.html +1 -1
  253. data/doc/lib/Query_rb.html +1 -1
  254. data/doc/lib/RealFormat_rb.html +1 -1
  255. data/doc/lib/ResourceScenario_rb.html +1 -1
  256. data/doc/lib/Resource_rb.html +1 -1
  257. data/doc/lib/RichTextParser_rb.html +1 -1
  258. data/doc/lib/RichTextScanner_rb.html +1 -1
  259. data/doc/lib/RichTextSyntaxRules_rb.html +1 -1
  260. data/doc/lib/RichText_rb.html +1 -1
  261. data/doc/lib/Scoreboard_rb.html +1 -1
  262. data/doc/lib/StatusSheetSender_rb.html +1 -1
  263. data/doc/lib/SyntaxReference_rb.html +1 -1
  264. data/doc/lib/TaskJuggler_rb.html +1 -1
  265. data/doc/lib/TaskScenario_rb.html +3 -1
  266. data/doc/lib/TextParser/Pattern_rb.html +3 -1
  267. data/doc/lib/TextParser/Rule_rb.html +3 -1
  268. data/doc/lib/TextParser/StackElement_rb.html +3 -1
  269. data/doc/lib/TextParser/State_rb.html +65 -0
  270. data/doc/lib/TextParser_rb.html +1 -1
  271. data/doc/lib/TextScanner_rb.html +1 -1
  272. data/doc/lib/Tj3Config_rb.html +1 -1
  273. data/doc/lib/TjTime_rb.html +1 -1
  274. data/doc/lib/TjpSyntaxRules_rb.html +1 -1
  275. data/doc/lib/WorkingHours_rb.html +3 -1
  276. data/doc/lib/daemon/ReportServer_rb.html +1 -1
  277. data/doc/lib/reports/CSVFile_rb.html +1 -1
  278. data/doc/lib/reports/CollisionDetector_rb.html +67 -0
  279. data/doc/lib/reports/GanttChart_rb.html +1 -1
  280. data/doc/lib/reports/GanttRouter_rb.html +3 -1
  281. data/doc/lib/reports/Navigator_rb.html +1 -1
  282. data/doc/lib/reports/ReportBase_rb.html +1 -1
  283. data/doc/lib/reports/ReportTableCell_rb.html +1 -1
  284. data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
  285. data/doc/lib/reports/ReportTableLine_rb.html +1 -1
  286. data/doc/lib/reports/ReportTable_rb.html +1 -1
  287. data/doc/lib/reports/Report_rb.html +1 -1
  288. data/doc/lib/reports/TableReport_rb.html +1 -1
  289. data/doc/lib/taskjuggler3_rb.html +1 -1
  290. data/examples/tutorial.tjp +1 -2
  291. data/lib/AppConfig.rb +10 -4
  292. data/lib/Attributes.rb +4 -4
  293. data/lib/DataCache.rb +124 -0
  294. data/lib/KeywordDocumentation.rb +5 -5
  295. data/lib/Project.rb +54 -10
  296. data/lib/ProjectFileParser.rb +10 -9
  297. data/lib/ProjectFileScanner.rb +38 -25
  298. data/lib/PropertyList.rb +6 -4
  299. data/lib/Query.rb +0 -8
  300. data/lib/RealFormat.rb +1 -1
  301. data/lib/Resource.rb +1 -1
  302. data/lib/ResourceScenario.rb +96 -31
  303. data/lib/RichText.rb +17 -5
  304. data/lib/RichTextParser.rb +22 -9
  305. data/lib/RichTextScanner.rb +34 -34
  306. data/lib/RichTextSyntaxRules.rb +41 -36
  307. data/lib/Scoreboard.rb +16 -7
  308. data/lib/StatusSheetSender.rb +63 -0
  309. data/lib/SyntaxReference.rb +9 -10
  310. data/lib/TaskJuggler.rb +28 -4
  311. data/lib/TaskScenario.rb +66 -19
  312. data/lib/TextParser.rb +219 -384
  313. data/lib/TextParser/Pattern.rb +168 -49
  314. data/lib/TextParser/Rule.rb +33 -17
  315. data/lib/TextParser/StackElement.rb +42 -2
  316. data/lib/TextParser/State.rb +175 -0
  317. data/lib/TextScanner.rb +19 -15
  318. data/lib/Tj3Config.rb +1 -1
  319. data/lib/TjTime.rb +111 -3
  320. data/lib/TjpSyntaxRules.rb +122 -66
  321. data/lib/WorkingHours.rb +91 -186
  322. data/lib/daemon/ReportServer.rb +3 -2
  323. data/lib/reports/CSVFile.rb +1 -1
  324. data/lib/reports/CollisionDetector.rb +177 -0
  325. data/lib/reports/GanttChart.rb +25 -41
  326. data/lib/reports/GanttRouter.rb +104 -233
  327. data/lib/reports/Navigator.rb +1 -1
  328. data/lib/reports/Report.rb +9 -33
  329. data/lib/reports/ReportBase.rb +0 -1
  330. data/lib/reports/ReportTable.rb +19 -8
  331. data/lib/reports/ReportTableCell.rb +61 -25
  332. data/lib/reports/ReportTableColumn.rb +2 -2
  333. data/lib/reports/ReportTableLine.rb +4 -2
  334. data/lib/reports/TableReport.rb +1 -0
  335. data/lib/taskjuggler3.rb +0 -1
  336. data/manual/Installation +7 -3
  337. data/manual/Intro +12 -10
  338. data/manual/The_TaskJuggler_Syntax +4 -4
  339. data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -14
  340. data/test/TestSuite/CSV-Reports/genrefs +1 -1
  341. data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -4
  342. data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -22
  343. data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -14
  344. data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -14
  345. data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -14
  346. data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -14
  347. data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -14
  348. data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +32 -24
  349. data/test/TestSuite/CSV-Reports/weekly-Reference.csv +13 -0
  350. data/test/TestSuite/CSV-Reports/weekly.tjp +9 -0
  351. data/test/TestSuite/HTML-Reports/css/tjreport.css +7 -2
  352. data/test/TestSuite/HTML-Reports/depArrows.html +839 -830
  353. data/test/TestSuite/HTML-Reports/depArrows.tjp +12 -12
  354. data/test/TestSuite/HTML-Reports/profile.html +37581 -0
  355. data/test/TestSuite/ReportGenerator/Errors/no_report_defined.tjp +7 -0
  356. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.tjp +1 -1
  357. data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/missing-reports +2 -0
  358. data/test/TestSuite/StatusSheets/run +2 -0
  359. data/test/TestSuite/Syntax/Correct/Booking.tjp +13 -5
  360. data/test/TestSuite/Syntax/Correct/ResourceRoot.tjp +21 -0
  361. data/test/TestSuite/Syntax/Correct/RollupResource.tjp +21 -0
  362. data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +1 -1
  363. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
  364. data/test/TestSuite/Syntax/Errors/include_before_project.tjp +2 -0
  365. data/test/TestSuite/Syntax/Errors/no_reduce.tjp +6 -0
  366. data/test/TestSuite/Syntax/Errors/unsupported_token.tjp +1 -1
  367. data/test/TestSuite/TimeSheets/run +1 -1
  368. data/test/test_CSV-Reports.rb +2 -4
  369. data/test/test_CollisionDetector.rb +85 -0
  370. data/test/test_Project.rb +2 -2
  371. data/test/test_ProjectFileScanner.rb +73 -31
  372. data/test/test_Query.rb +2 -2
  373. data/test/test_ReportGenerator.rb +1 -1
  374. data/test/test_RichText.rb +4 -4
  375. data/test/test_WorkingHours.rb +150 -11
  376. metadata +75 -67
  377. data/test/TestSuite/ReportGenerator/Errors/css/tjreport.css +0 -407
  378. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.html +0 -26
  379. data/test/TestSuite/Scheduler/Correct/Allocate.html +0 -3210
  380. data/test/TestSuite/Scheduler/Correct/Container.html +0 -349
  381. data/test/TestSuite/Scheduler/Correct/Limits.html +0 -4964
  382. data/test/TestSuite/Scheduler/Correct/Shift.html +0 -1719
  383. data/test/TestSuite/Scheduler/Correct/Shift2.html +0 -476
  384. data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +0 -66
  385. data/test/TestSuite/Scheduler/Correct/icons/details.png +0 -0
  386. data/test/TestSuite/Scheduler/Correct/icons/flag-green.png +0 -0
  387. data/test/TestSuite/Scheduler/Correct/icons/flag-red.png +0 -0
  388. data/test/TestSuite/Scheduler/Correct/icons/flag-yellow.png +0 -0
  389. data/test/TestSuite/Scheduler/Correct/icons/resource.png +0 -0
  390. data/test/TestSuite/Scheduler/Correct/icons/resourcegroup.png +0 -0
  391. data/test/TestSuite/Scheduler/Correct/icons/task.png +0 -0
  392. data/test/TestSuite/Scheduler/Correct/icons/taskgroup.png +0 -0
  393. data/test/TestSuite/Scheduler/Correct/icons/trend-down.png +0 -0
  394. data/test/TestSuite/Scheduler/Correct/icons/trend-flat.png +0 -0
  395. data/test/TestSuite/Scheduler/Correct/icons/trend-up.png +0 -0
  396. data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +0 -1301
  397. data/test/TestSuite/Scheduler/Errors/css/tjmanual.css +0 -66
  398. data/test/TestSuite/Scheduler/Errors/css/tjreport.css +0 -407
  399. data/test/TestSuite/Scheduler/Errors/icons/details.png +0 -0
  400. data/test/TestSuite/Scheduler/Errors/icons/flag-green.png +0 -0
  401. data/test/TestSuite/Scheduler/Errors/icons/flag-red.png +0 -0
  402. data/test/TestSuite/Scheduler/Errors/icons/flag-yellow.png +0 -0
  403. data/test/TestSuite/Scheduler/Errors/icons/resource.png +0 -0
  404. data/test/TestSuite/Scheduler/Errors/icons/resourcegroup.png +0 -0
  405. data/test/TestSuite/Scheduler/Errors/icons/task.png +0 -0
  406. data/test/TestSuite/Scheduler/Errors/icons/taskgroup.png +0 -0
  407. data/test/TestSuite/Scheduler/Errors/icons/trend-down.png +0 -0
  408. data/test/TestSuite/Scheduler/Errors/icons/trend-flat.png +0 -0
  409. data/test/TestSuite/Scheduler/Errors/icons/trend-up.png +0 -0
  410. data/test/TestSuite/Scheduler/Errors/scripts/wz_tooltip.js +0 -1301
  411. data/test/TestSuite/StatusSheets/resrep.tji +0 -7
  412. data/test/TestSuite/StatusSheets/tj3d.log +0 -312
  413. data/test/TestSuite/Syntax/Correct/Managers.html +0 -263
  414. data/test/TestSuite/TimeSheets/acceptable_intervals +0 -1
  415. data/test/TestSuite/TimeSheets/statussheets.log +0 -1
@@ -198,9 +198,9 @@ class TaskJuggler
198
198
  end
199
199
 
200
200
  # This is a noop function.
201
- def to_csv
201
+ def to_csv(csv, startColumn)
202
202
  # Can't put a Gantt chart into a CSV file.
203
- ''
203
+ 0
204
204
  end
205
205
 
206
206
  # Utility function that convers a date to the corresponding X-position in
@@ -240,16 +240,30 @@ class TaskJuggler
240
240
  @height = line.y + line.height if line.y + line.height > @height
241
241
  end
242
242
 
243
+ # To layout the dependency lines, we use a GanttRouter. We only provide
244
+ # the start and end coordinates of each line and it will do the layout
245
+ # and routing.
243
246
  @router = GanttRouter.new(@width, @height)
244
247
 
248
+ # We don't want horizontal lines to cross the task bars. So we block
249
+ # these chart zones. Milestones should not be crossed in any direction.
245
250
  @lines.each do |line|
246
251
  line.addBlockedZones(@router)
247
252
  end
248
253
 
254
+ # Also protect the current date line from other vertical lines.
249
255
  @router.addZone(@header.nowLineX - 1, 0, 3, @height - 1, false, true)
250
256
 
257
+ # Generate the dependency arrows for all visible tasks.
251
258
  @tasks.each do |task, lines|
252
- generateDepArrows(task, lines)
259
+ generateDepLines(task, lines)
260
+ end
261
+
262
+ # Make sure we have exactly one arrow head for each line end point even
263
+ # if the point is used by multiple lines.
264
+ @depArrows.each do |line|
265
+ endPoint = line.last
266
+ @arrowHeads << endPoint unless @arrowHeads.include?(endPoint)
253
267
  end
254
268
  end
255
269
 
@@ -257,18 +271,18 @@ class TaskJuggler
257
271
  # for a specific _task_. _lines_ is a list of GanttLines that the tasks are
258
272
  # displayed on. Reports with multiple scenarios have multiple lines per
259
273
  # task.
260
- def generateDepArrows(task, lines)
274
+ def generateDepLines(task, lines)
261
275
  # Since we need the line and the index we use an index iterator.
262
276
  lines.length.times do |lineIndex|
263
277
  line = lines[lineIndex]
264
278
  scenarioIdx = line.query.scenarioIdx
265
279
 
266
280
  # Generate the dependencies on the start of the task.
267
- collectAndSortArrows('startsuccs', task, scenarioIdx, lineIndex,
281
+ generateTaskDepLines('startsuccs', task, scenarioIdx, lineIndex,
268
282
  *line.getTask.startDepLineStart)
269
283
 
270
284
  # Generate the dependencies on the end of the task.
271
- collectAndSortArrows('endsuccs', task, scenarioIdx, lineIndex,
285
+ generateTaskDepLines('endsuccs', task, scenarioIdx, lineIndex,
272
286
  *line.getTask.endDepLineStart)
273
287
  end
274
288
  end
@@ -278,11 +292,9 @@ class TaskJuggler
278
292
  # and _startY_ are the graphic coordinates for the begin of the arrow
279
293
  # line. _task_ references the Task in question and _scenarioIdx_ the
280
294
  # scenario. _lineIndex_ specifies the line number in the chart.
281
- def collectAndSortArrows(kind, task, scenarioIdx, lineIndex, startX, startY)
282
- # We need to sort the arrows. This is an Array that holds 6 values for
283
- # each entry: The x and y coordinates for start and end points, the
284
- # sinus value of the angle between a vertical and the line specified by
285
- # the points and the length of the line.
295
+ def generateTaskDepLines(kind, task, scenarioIdx, lineIndex, startX, startY)
296
+ # This is an Array that holds 4 values for
297
+ # each entry: The x and y coordinates for start and end points.
286
298
  touples = []
287
299
  task[kind, scenarioIdx].each do |t, onEnd|
288
300
  # Skip inherited dependencies and tasks that are not included in the
@@ -294,37 +306,9 @@ class TaskJuggler
294
306
  end
295
307
  endX, endY = @tasks[t][lineIndex].getTask.send(
296
308
  onEnd ? :endDepLineEnd : :startDepLineEnd)
297
- # To make sure that we minimize the crossings of arrows that
298
- # originate from the same position, we sort the arrows by the
299
- # smallest angle between the vertical line through the task end
300
- # and the line between the start and end of the arrow.
301
- oppLeg = endX - startX
302
- adjLeg = (startY - endY).abs
303
- hypothenuse = Math.sqrt(adjLeg ** 2 + oppLeg ** 2)
304
- # We can now calculate the sinus values of the angle between the
305
- # vertical and a line through the coordinates.
306
- touples << [ startX, startY, endX, endY,
307
- (oppLeg / hypothenuse), hypothenuse ]
308
- end
309
- # We sort the arrows from small to a large angle. In case the angle is
310
- # identical, we use the length of the line as second criteria.
311
- touples.sort! { |t1, t2| t1[4] == t2[4] ? t1[5] <=> t2[5] :
312
- t1[4] <=> t2[4] }
313
- touples.each do |t|
314
- routeArrow(*t[0, 4])
315
- end
316
- end
317
-
318
- # Route the dependency lines from the start to the end point.
319
- def routeArrow(startX, startY, endX, endY)
320
- @depArrows << @router.route([startX, startY], [endX, endY])
321
-
322
- # It's enough to have only a single arrow drawn at the end point even if
323
- # it's the destination of multiple lines.
324
- @arrowHeads.each do |x, y|
325
- return if x == endX && y == endY
309
+ touples << [ startX, startY, endX, endY ]
326
310
  end
327
- @arrowHeads << [ endX, endY ]
311
+ @depArrows += @router.routeLines(touples) unless touples.empty?()
328
312
  end
329
313
 
330
314
  end
@@ -10,6 +10,8 @@
10
10
  # published by the Free Software Foundation.
11
11
  #
12
12
 
13
+ require 'reports/CollisionDetector'
14
+
13
15
  class TaskJuggler
14
16
 
15
17
  # The GanttRouter is used by the GanttChart to route the dependency lines from
@@ -17,11 +19,15 @@ class TaskJuggler
17
19
  # width and height. The graphical elements of the Gantt chart can be
18
20
  # registered as don't-cross-zones. These zones block the either horizontal or
19
21
  # vertical lines (or both) from crossing the zone. Zones can be registered by
20
- # calling addZone(). The route() method returns routed path from start to end
21
- # point.
22
+ # calling addZone(). The route() method returns routed path from
23
+ # start to end point.
22
24
  class GanttRouter
23
25
 
24
- include HTMLGraphics
26
+ # Minimum distance between the starting point and the first turning point.
27
+ MinStartGap = 5
28
+ # Minimum distance between the last turning point and the tip of the
29
+ # arrow.
30
+ MinEndGap = 10
25
31
 
26
32
  # Create a GanttRouter object. _width_ and _height_ describe the size of the
27
33
  # rectangular area this router is operating on.
@@ -29,77 +35,86 @@ class TaskJuggler
29
35
  @width = width.to_i
30
36
  @height = height.to_i
31
37
 
32
- # The zones are stored as Arrays of line segments. Horizontal blocks are
33
- # stored separately from vertical blocks. Blocked segments for a
34
- # particular x coordinate are stored in @vLines, for y coordinates in
35
- # @hLines. Each entry is an Array of [ start, end ] values that describe
36
- # the blocked segments of that particular line. Start and end point are
37
- # part of the segment. A listed segment will not be overwritten during
38
- # routing.
39
- @hLines = Array.new(@height) { |i| i = [] }
40
- @vLines = Array.new(@width) { |i| i = [] }
38
+ @detector = CollisionDetector.new(@width, @height)
41
39
  end
42
40
 
43
- # This function registers an area as don't-cross-zone. The rectangular zone
44
- # is described by _x_, _y_, _w_ and _h_. If _horiz_ is true, the zone will
45
- # be blocked for horizontal lines, if _vert_ is true the zone will be
46
- # blocked for vertical lines.
47
41
  def addZone(x, y, w, h, horiz, vert)
48
- # Clip the input rectangle to fit within the handled area of this router.
49
- x = clip(x.to_i, @width - 1)
50
- y = clip(y.to_i, @height - 1)
51
- w = clip(w.to_i, @width - x)
52
- h = clip(h.to_i, @height - y)
42
+ @detector.addBlockedZone(x, y, w, h, horiz, vert)
43
+ end
53
44
 
54
- # We can ignore empty zones.
55
- return if w == 0 || h == 0
45
+ def routeLines(fromToPoints)
46
+ # We first convert the fromToPoints list into a more readable list of
47
+ # Hash objects.
48
+ routes = []
49
+ fromToPoints.each do |touple|
50
+ routes << {
51
+ :startX => touple[0],
52
+ :startY => touple[1],
53
+ :endX => touple[2],
54
+ :endY => touple[3],
55
+ :id => touple[4]
56
+ }
57
+ end
56
58
 
57
- # Break the rectangle into line segments and add them to the appropriate
58
- # line Arrays.
59
- if horiz
60
- y.upto(y + h - 1) do |i|
61
- addSegment(@hLines[i], [ x, x + w - 1 ])
62
- end
59
+ # To make sure that we minimize the crossings of arrows that
60
+ # originate from the same position, we sort the arrows by the
61
+ # smallest angle between the vertical line through the task end
62
+ # and the line between the start and end of the arrow.
63
+ routes.each do |r|
64
+ adjLeg = (r[:endX] - MinEndGap) - (r[:startX] + MinStartGap)
65
+ oppLeg = (r[:startY] - r[:endY]).abs
66
+ r[:distance] = Math.sqrt(adjLeg ** 2 + oppLeg ** 2)
67
+ # We can now calculate the sinus values of the angle between the
68
+ # vertical and a line through the coordinates.
69
+ sinus = oppLeg.abs / r[:distance]
70
+ r[:angle] = (adjLeg < 0 ? Math::PI / 2 + Math.asin(Math::PI/2 - sinus) :
71
+ Math.asin(sinus)) / (Math::PI / (2 * 90))
63
72
  end
64
- if vert
65
- x.upto(x + w - 1) do |i|
66
- addSegment(@vLines[i], [ y, y + h - 1 ])
67
- end
73
+ # We sort the arrows from small to a large angle. In case the angle is
74
+ # identical, we use the length of the line as second criteria.
75
+ routes.sort! { |r1, r2| (r1[:angle] / 5).to_i == (r2[:angle] / 5).to_i ?
76
+ -(r1[:distance] <=> r2[:distance]) :
77
+ -(r1[:angle] <=> r2[:angle]) }
78
+
79
+ # Now that the routes are in proper order, we can actually lay the
80
+ # routes.
81
+ routePoints = []
82
+ routes.each do |r|
83
+ routePoints << route(r[:startX], r[:startY], r[:endX], r[:endY])
68
84
  end
85
+ routePoints
69
86
  end
70
87
 
71
88
  # Find a non-blocked route from the _startPoint_ [ x, y ] to the
72
89
  # _endPoint_ [ x, y ]. The route always starts from the start point towards
73
90
  # the right side of the chart and reaches the end point from the left side
74
91
  # of the chart. All lines are always strictly horizontal or vertical. There
75
- # are no diagonal lines.
76
- def route(startPoint, endPoint)
77
- points = [ startPoint ]
78
- # Minimum distance between the starting point and the first turning point.
79
- startGap = 5
80
- # Minimum distance between the last turning point and the tip of the
81
- # arrow.
82
- endGap = 10
83
-
84
- if endPoint[0] - startPoint[0] > startGap + endGap + 2
92
+ # are no diagonal lines. The result is an Array of [ x, y ] points that
93
+ # include the _startPoint_ as first and _endPoint_ as last element.
94
+ def route(startX, startY, endX, endY)
95
+ points = [ [ startX, startY ] ]
96
+ startGap = MinStartGap
97
+ endGap = MinEndGap
98
+
99
+ if endX - startX > startGap + endGap + 2
85
100
  # If the horizontal distance between start and end point is large enough
86
101
  # we can try a direct route.
87
102
  #
88
- # xSeg
89
- # |startGap|
90
- # startPoint X--------1
91
- # |
92
- # |
93
- # 2------X end Point
94
- # |endGap|
103
+ # xSeg
104
+ # |startGap|
105
+ # startX/endX X--------1
106
+ # |
107
+ # |
108
+ # 2------X endX/endY
109
+ # |endGap|
95
110
  #
96
- xSeg = placeLine([ startPoint[1] + (startPoint[1] < endPoint[1] ?
97
- 1 : -1), endPoint[1] ],
98
- false, startPoint[0] + startGap, 1)
99
- if xSeg && xSeg < endPoint[0] - endGap
100
- addLineTo(points, xSeg, startPoint[1]) # Point 1
101
- addLineTo(points, xSeg, endPoint[1]) # Point 2
102
- addLineTo(points, *endPoint)
111
+ xSeg = placeLine([ startY + (startY < endY ? 1 : -1), endY ],
112
+ false, startX + startGap, 1)
113
+ if xSeg && xSeg < endX - endGap
114
+ # The simple version works. Add the lines.
115
+ addLineTo(points, xSeg, startY) # Point 1
116
+ addLineTo(points, xSeg, endY) # Point 2
117
+ addLineTo(points, endX, endY)
103
118
  return points
104
119
  end
105
120
  end
@@ -107,40 +122,39 @@ class TaskJuggler
107
122
  # If the simple approach above fails, the try a more complex routing
108
123
  # strategy.
109
124
  #
110
- # x1
111
- # |startGap|
112
- # startPoint X--------1 yLS
113
- # |
114
- # 3---------------2 ySeg
115
- # |
116
- # 4------X endPoint
117
- # |endGap|
118
- # x2
125
+ # x1
126
+ # |startGap|
127
+ # startX/startY X--------1 yLS
128
+ # |
129
+ # 3---------------2 ySeg
130
+ # |
131
+ # 4------X endX/endY
132
+ # |endGap|
133
+ # x2
119
134
 
120
135
  # Place horizontal segue. We don't know the width yet, so we have to
121
136
  # assume full width. That's acceptable for horizontal lines.
122
- ySeg = placeLine([ 0, @width - 1 ], true, startPoint[1],
123
- startPoint[1] < endPoint[1] ? 1 : -1)
137
+ deltaY = startY < endY ? 1 : -1
138
+ ySeg = placeLine([ 0, @width - 1 ], true, startY + 2 * deltaY, deltaY)
124
139
  raise "Routing failed" unless ySeg
125
140
 
126
141
  # Place 1st vertical
127
- x1 = placeLine([ startPoint[1] + (startPoint[1] < endPoint[1] ? 1 : -1),
128
- ySeg ], false, startPoint[0] + startGap, 1)
142
+ x1 = placeLine([ startY + deltaY, ySeg ], false, startX + startGap, 1)
129
143
  raise "Routing failed" unless x1
130
144
 
131
145
  # Place 2nd vertical
132
- x2 = placeLine([ ySeg, endPoint[1] ], false, endPoint[0] - endGap, -1)
146
+ x2 = placeLine([ ySeg + deltaY, endY ], false, endX - endGap, -1)
133
147
  raise "Routing failed" unless x2
134
148
 
135
149
  # Now add the points 1 - 4 to the list and mark the zones around them. For
136
150
  # vertical lines, we only mark vertical zones and vice versa.
137
- addLineTo(points, x1, startPoint[1]) # Point 1
151
+ addLineTo(points, x1, startY) # Point 1
138
152
  if x1 != x2
139
153
  addLineTo(points, x1, ySeg) # Point 2
140
154
  addLineTo(points, x2, ySeg) # Point 3
141
155
  end
142
- addLineTo(points, x2, endPoint[1]) # Point 4
143
- addLineTo(points, *endPoint)
156
+ addLineTo(points, x2, endY) # Point 4
157
+ addLineTo(points, endX, endY)
144
158
 
145
159
  points
146
160
  end
@@ -148,138 +162,11 @@ class TaskJuggler
148
162
  # This function is only intended for debugging purposes. It marks either the
149
163
  # vertical or horizontal zones in the chart.
150
164
  def to_html
151
- html = []
152
- # Change this to determine what zones you want to see.
153
- if true
154
- # Show vertical blocks
155
- x = 0
156
- @vLines.each do |line|
157
- line.each do |segment|
158
- html << lineToHTML(x, segment[0], x, segment[1], 'white')
159
- end
160
- x += 1
161
- end
162
- else
163
- # Show horizontal blocks
164
- y = 0
165
- @hLines.each do |line|
166
- line.each do |segment|
167
- html << lineToHTML(segment[0], y, segment[1], y, 'white')
168
- end
169
- y += 1
170
- end
171
- end
172
- html
165
+ @detector.to_html
173
166
  end
174
167
 
175
168
  private
176
169
 
177
- # Simple utility function to limit _v_ between 0 and _max_.
178
- def clip(v, max)
179
- v = 0 if v < 0
180
- v = max if v > max
181
- v
182
- end
183
-
184
- # This function makes sure that the rectangle described by _x_, _y_, _w_ and
185
- # _h_ is properly justfified. If the width or height are negative, _x_ and
186
- # _y_ are adjusted to describe the same rectangle with all positive
187
- # coordinates.
188
- def justify(x, y, w, h)
189
- if w < 0
190
- w = -w
191
- x = x - w + 1
192
- end
193
- if h < 0
194
- h = -h
195
- y = y - h + 1
196
- end
197
- # Return the potentially adjusted rectangle coordinates.
198
- return x, y, w, h
199
- end
200
-
201
- # This function adds a new segment to the line. In case the new segment
202
- # overlaps with or directly attaches to existing segments, these segments
203
- # are merged into a single segment.
204
- def addSegment(line, newSegment)
205
- # Search for overlaping or directly attaching segments in the list.
206
- i = 0
207
- while (i < line.length)
208
- segment = line[i]
209
- if mergeable?(newSegment, segment)
210
- # Merge exiting segment into new one
211
- merge(newSegment, segment)
212
- # Remove the old one from the list and restart with the newly created
213
- # one at the same position.
214
- line.delete_at(i)
215
- next
216
- elsif segment[0] > newSegment[1]
217
- # Segments are stored in ascending order. If the next segment starts
218
- # with a larger value, we insert the new segment before the larger
219
- # one.
220
- line.insert(i, newSegment)
221
- return
222
- end
223
- i += 1
224
- end
225
- # Append new segment
226
- line << newSegment
227
- end
228
-
229
- # Return true if the two segments described by _s1_ and _s2_ overlap each
230
- # other. A segment is a [ start, end ] Array. The two points are part of the
231
- # segment.
232
- def overlaps?(s1, s2)
233
- (s1[0] <= s2[0] && s2[0] <= s1[1]) ||
234
- (s2[0] <= s1[0] && s1[0] <= s2[1])
235
- end
236
-
237
- # Return true if the two segments described by _s1_ and _s2_ overlap each
238
- # other or are directly attached to each other.
239
- def mergeable?(s1, s2)
240
- overlaps?(s1, s2) ||
241
- (s1[1] + 1 == s2[0]) ||
242
- (s2[1] + 1 == s1[0])
243
- end
244
-
245
- # Merge the two segments described by _dst_ and _src_ into _dst_.
246
- def merge(dst, seg)
247
- dst[0] = seg[0] if seg[0] < dst[0]
248
- dst[1] = seg[1] if seg[1] > dst[1]
249
- end
250
-
251
- # Find out if any of the segments in _line_ overlap with the _probeSegment_.
252
- # If so, return true, false otherwise.
253
- def collision?(line, probeSegment)
254
- # For complex charts, the segment lists can be rather long. We use a
255
- # binary search to be fairly efficient.
256
- l = 0
257
- u = line.length - 1
258
- while l <= u
259
- # Look at the element in the middle between l and u.
260
- p = l + ((u - l) / 2).to_i
261
- return true if overlaps?(line[p], probeSegment)
262
-
263
- if probeSegment[0] > line[p][1]
264
- # The potential target is above p. Adjust lower bound.
265
- l = p + 1
266
- else
267
- # The potential target is below p. Adjust upper bound.
268
- u = p - 1
269
- end
270
- end
271
- # TODO: This code uses a simple linear search to double check the above
272
- # binary search. It can be removed once we know the above code always
273
- # works properly.
274
- line.each do |segment|
275
- if overlaps?(probeSegment, segment)
276
- raise "Binary search failed to find collision"
277
- end
278
- end
279
-
280
- false
281
- end
282
-
283
170
  # This function is at the heart of the routing algorithm. It tries to find a
284
171
  # place for the line described by _segment_ without overlapping with the
285
172
  # defined zones. _horizontal_ determines whether the line is running
@@ -297,10 +184,9 @@ class TaskJuggler
297
184
 
298
185
  # Make sure that the segment coordinates are in ascending order.
299
186
  segment.sort!
300
- lines = horizontal ? @hLines : @vLines
301
187
  # TODO: Remove this check once the code becomes stable.
302
188
  #checkLines(lines)
303
- while collision?(lines[pos], segment)
189
+ while @detector.collision?(pos, segment, horizontal)
304
190
  pos += delta
305
191
  # Check if we have exceded the chart area towards top/left.
306
192
  if delta < 0
@@ -312,7 +198,6 @@ class TaskJuggler
312
198
  break if pos >= (horizontal ? @height : @width)
313
199
  end
314
200
  end
315
- doubleCheckLine(horizontal ? @hLines : @vLines, pos, segment)
316
201
  pos
317
202
  end
318
203
 
@@ -339,38 +224,24 @@ class TaskJuggler
339
224
  end
340
225
  end
341
226
 
342
- # This is just an internal sanity check that is not needed for normal
343
- # operation. It checks that all the line segments are valid and stored in
344
- # ascending order.
345
- def checkLines(lines)
346
- lines.each do |line|
347
- v = nil
348
- line.each do |segment|
349
- if segment[0] > segment[1]
350
- raise "Invalid segment [#{segment[0]}, #{segment[1]}]"
351
- end
352
- if v
353
- raise "Segment sequence error" if v >= segment[0]
354
- end
355
- v = segment[1]
356
- end
227
+ # This function makes sure that the rectangle described by _x_, _y_, _w_
228
+ # and _h_ is properly justfified. If the width or height are negative, _x_
229
+ # and _y_ are adjusted to describe the same rectangle with all positive
230
+ # coordinates.
231
+ def justify(x, y, w, h)
232
+ if w < 0
233
+ w = -w
234
+ x = x - w + 1
357
235
  end
358
- end
359
-
360
- # Internal function that is only used for testing. It raises an exception if
361
- # the placed line at _pos_ and [ _lineSegment_[0], _lineSegment_[1] ]
362
- # overlaps with a segment of _lines_.
363
- def doubleCheckLine(lines, pos, lineSegment)
364
- return if pos < 0 || lines[pos].nil?
365
- lines[pos].each do |segment|
366
- if overlaps?(lineSegment, segment)
367
- raise "Internal router failure for #{lines == @vLines ? 'v' : 'h'}" +
368
- "Line #{pos}: [#{lineSegment.join(', ')}] overlaps with " +
369
- "[#{segment.join(', ')}]."
370
- end
236
+ if h < 0
237
+ h = -h
238
+ y = y - h + 1
371
239
  end
240
+ # Return the potentially adjusted rectangle coordinates.
241
+ return x, y, w, h
372
242
  end
373
243
 
244
+
374
245
  end
375
246
 
376
247
  end