taskjuggler 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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