taskjuggler 3.3.0 → 3.4.0

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 (338) hide show
  1. data/CHANGELOG +35 -0
  2. data/data/tjp.vim +21 -7
  3. data/lib/taskjuggler/Allocation.rb +27 -3
  4. data/lib/taskjuggler/Attributes.rb +3 -2
  5. data/lib/taskjuggler/HTMLDocument.rb +3 -1
  6. data/lib/taskjuggler/KateSyntax.rb +213 -0
  7. data/lib/taskjuggler/Limits.rb +22 -0
  8. data/lib/taskjuggler/Log.rb +1 -1
  9. data/lib/taskjuggler/MessageHandler.rb +20 -10
  10. data/lib/taskjuggler/PTNProxy.rb +6 -1
  11. data/lib/taskjuggler/Project.rb +10 -4
  12. data/lib/taskjuggler/ProjectFileParser.rb +1 -2
  13. data/lib/taskjuggler/ProjectFileScanner.rb +41 -42
  14. data/lib/taskjuggler/ResourceScenario.rb +41 -1
  15. data/lib/taskjuggler/RichText/Element.rb +8 -0
  16. data/lib/taskjuggler/RichText/Parser.rb +1 -1
  17. data/lib/taskjuggler/RichText/RTFReportLink.rb +20 -10
  18. data/lib/taskjuggler/RichText/Scanner.rb +54 -38
  19. data/lib/taskjuggler/RichText/SyntaxRules.rb +12 -0
  20. data/lib/taskjuggler/SheetReceiver.rb +1 -1
  21. data/lib/taskjuggler/TableColumnDefinition.rb +5 -1
  22. data/lib/taskjuggler/TaskJuggler.rb +2 -2
  23. data/lib/taskjuggler/TaskScenario.rb +117 -33
  24. data/lib/taskjuggler/TextParser.rb +2 -4
  25. data/lib/taskjuggler/TextParser/MacroTable.rb +7 -0
  26. data/lib/taskjuggler/TextParser/Scanner.rb +10 -9
  27. data/lib/taskjuggler/Tj3Config.rb +1 -1
  28. data/lib/taskjuggler/TjTime.rb +5 -28
  29. data/lib/taskjuggler/TjpSyntaxRules.rb +85 -13
  30. data/lib/taskjuggler/UTF8String.rb +5 -0
  31. data/lib/taskjuggler/XMLElement.rb +2 -1
  32. data/lib/taskjuggler/apps/Tj3.rb +29 -5
  33. data/lib/taskjuggler/daemon/ProcessIntercom.rb +1 -1
  34. data/lib/taskjuggler/daemon/ProjectServer.rb +5 -2
  35. data/lib/taskjuggler/daemon/ReportServer.rb +7 -4
  36. data/lib/taskjuggler/reports/AccountListRE.rb +2 -0
  37. data/lib/taskjuggler/reports/CSVFile.rb +24 -2
  38. data/lib/taskjuggler/reports/GanttChart.rb +3 -2
  39. data/lib/taskjuggler/reports/GanttHeader.rb +18 -18
  40. data/lib/taskjuggler/reports/GanttLoadStack.rb +1 -1
  41. data/lib/taskjuggler/reports/MspXmlRE.rb +5 -1
  42. data/lib/taskjuggler/reports/Report.rb +29 -18
  43. data/lib/taskjuggler/reports/ReportTable.rb +5 -1
  44. data/lib/taskjuggler/reports/ReportTableCell.rb +16 -10
  45. data/lib/taskjuggler/reports/ResourceListRE.rb +2 -0
  46. data/lib/taskjuggler/reports/TableReport.rb +23 -16
  47. data/lib/taskjuggler/reports/TaskListRE.rb +2 -0
  48. data/lib/taskjuggler/reports/TraceReport.rb +1 -1
  49. data/manual/Installation +5 -1
  50. data/manual/Intro +1 -0
  51. data/manual/Rich_Text_Attributes +5 -0
  52. data/manual/TaskJuggler_Internals +82 -34
  53. data/manual/Tutorial +1 -1
  54. data/manual/html/Day_To_Day_Juggling.html +1 -1
  55. data/manual/html/Getting_Started.html +1 -1
  56. data/manual/html/How_To_Contribute.html +1 -1
  57. data/manual/html/Installation.html +3 -2
  58. data/manual/html/Intro.html +2 -1
  59. data/manual/html/Reporting_Bugs.html +1 -1
  60. data/manual/html/Rich_Text_Attributes.html +2 -1
  61. data/manual/html/Software.html +1 -1
  62. data/manual/html/TaskJuggler_2x_Migration.html +1 -1
  63. data/manual/html/TaskJuggler_Internals.html +15 -13
  64. data/manual/html/The_TaskJuggler_Syntax.html +1 -1
  65. data/manual/html/Tutorial.html +2 -2
  66. data/manual/html/account.html +1 -1
  67. data/manual/html/account.task.html +1 -1
  68. data/manual/html/accountprefix.html +1 -1
  69. data/manual/html/accountreport.html +14 -2
  70. data/manual/html/accountroot.html +1 -1
  71. data/manual/html/active.html +1 -1
  72. data/manual/html/adopt.task.html +1 -1
  73. data/manual/html/aggregate.html +1 -1
  74. data/manual/html/alert.html +1 -1
  75. data/manual/html/alertlevels.html +1 -1
  76. data/manual/html/allocate.html +1 -1
  77. data/manual/html/alphabet.html +1 -1
  78. data/manual/html/alternative.html +1 -1
  79. data/manual/html/author.html +3 -3
  80. data/manual/html/auxdir.html +69 -0
  81. data/manual/html/balance.html +3 -3
  82. data/manual/html/booking.resource.html +1 -1
  83. data/manual/html/booking.task.html +1 -1
  84. data/manual/html/caption.html +1 -1
  85. data/manual/html/cellcolor.column.html +1 -1
  86. data/manual/html/celltext.column.html +1 -1
  87. data/manual/html/center.html +1 -1
  88. data/manual/html/charge.html +1 -1
  89. data/manual/html/chargeset.html +1 -1
  90. data/manual/html/columnid.html +21 -9
  91. data/manual/html/columns.html +2 -2
  92. data/manual/html/complete.html +1 -1
  93. data/manual/html/copyright.html +1 -1
  94. data/manual/html/credits.html +1 -1
  95. data/manual/html/currency.html +1 -1
  96. data/manual/html/currencyformat.html +1 -1
  97. data/manual/html/dailymax.html +1 -1
  98. data/manual/html/dailymin.html +1 -1
  99. data/manual/html/dailyworkinghours.html +1 -1
  100. data/manual/html/date.extend.html +1 -1
  101. data/manual/html/date.html +1 -1
  102. data/manual/html/definitions.html +1 -1
  103. data/manual/html/depends.html +1 -1
  104. data/manual/html/details.html +1 -1
  105. data/manual/html/disabled.html +1 -1
  106. data/manual/html/duration.html +1 -1
  107. data/manual/html/efficiency.html +1 -1
  108. data/manual/html/effort.html +1 -1
  109. data/manual/html/email.html +1 -1
  110. data/manual/html/enabled.html +1 -1
  111. data/manual/html/end.column.html +1 -1
  112. data/manual/html/end.html +1 -1
  113. data/manual/html/end.limit.html +1 -1
  114. data/manual/html/end.report.html +1 -1
  115. data/manual/html/end.timesheet.html +1 -1
  116. data/manual/html/endcredit.html +1 -1
  117. data/manual/html/epilog.html +1 -1
  118. data/manual/html/export.html +1 -1
  119. data/manual/html/extend.html +1 -1
  120. data/manual/html/fail.html +1 -1
  121. data/manual/html/fdl.html +1 -1
  122. data/manual/html/flags.account.html +1 -1
  123. data/manual/html/flags.html +1 -1
  124. data/manual/html/flags.journalentry.html +1 -1
  125. data/manual/html/flags.report.html +1 -1
  126. data/manual/html/flags.resource.html +1 -1
  127. data/manual/html/flags.statussheet.html +1 -1
  128. data/manual/html/flags.task.html +1 -1
  129. data/manual/html/flags.timesheet.html +1 -1
  130. data/manual/html/fontcolor.column.html +1 -1
  131. data/manual/html/footer.html +1 -1
  132. data/manual/html/formats.export.html +1 -1
  133. data/manual/html/formats.html +1 -1
  134. data/manual/html/functions.html +1 -1
  135. data/manual/html/gapduration.html +1 -1
  136. data/manual/html/gaplength.html +1 -1
  137. data/manual/html/halign.center.html +1 -1
  138. data/manual/html/halign.column.html +1 -1
  139. data/manual/html/halign.left.html +1 -1
  140. data/manual/html/halign.right.html +1 -1
  141. data/manual/html/hasalert.html +1 -1
  142. data/manual/html/header.html +1 -1
  143. data/manual/html/headline.html +1 -1
  144. data/manual/html/height.html +1 -1
  145. data/manual/html/hideaccount.html +1 -1
  146. data/manual/html/hidejournalentry.html +1 -1
  147. data/manual/html/hidereport.html +1 -1
  148. data/manual/html/hideresource.html +1 -1
  149. data/manual/html/hidetask.html +1 -1
  150. data/manual/html/icalreport.html +1 -1
  151. data/manual/html/include.macro.html +1 -1
  152. data/manual/html/include.project.html +1 -1
  153. data/manual/html/include.properties.html +1 -1
  154. data/manual/html/index.html +1 -1
  155. data/manual/html/inherit.extend.html +1 -1
  156. data/manual/html/interval1.html +1 -1
  157. data/manual/html/interval2.html +1 -1
  158. data/manual/html/interval3.html +1 -1
  159. data/manual/html/interval4.html +1 -1
  160. data/manual/html/isactive.html +1 -1
  161. data/manual/html/ischildof.html +1 -1
  162. data/manual/html/isdependencyof.html +1 -1
  163. data/manual/html/isdutyof.html +1 -1
  164. data/manual/html/isfeatureof.html +1 -1
  165. data/manual/html/isleaf.html +1 -1
  166. data/manual/html/ismilestone.html +1 -1
  167. data/manual/html/isongoing.html +1 -1
  168. data/manual/html/isresource.html +1 -1
  169. data/manual/html/isresponsibilityof.html +1 -1
  170. data/manual/html/istask.html +1 -1
  171. data/manual/html/journalattributes.html +1 -1
  172. data/manual/html/journalentry.html +1 -1
  173. data/manual/html/journalmode.html +1 -1
  174. data/manual/html/leaveallowance.html +1 -1
  175. data/manual/html/leaves.html +1 -1
  176. data/manual/html/left.html +1 -1
  177. data/manual/html/length.html +1 -1
  178. data/manual/html/limits.allocate.html +1 -1
  179. data/manual/html/limits.html +1 -1
  180. data/manual/html/limits.resource.html +1 -1
  181. data/manual/html/limits.task.html +1 -1
  182. data/manual/html/listitem.column.html +1 -1
  183. data/manual/html/listtype.column.html +1 -1
  184. data/manual/html/loadunit.html +1 -1
  185. data/manual/html/logicalexpression.html +1 -1
  186. data/manual/html/logicalflagexpression.html +1 -1
  187. data/manual/html/macro.html +1 -1
  188. data/manual/html/managers.html +1 -1
  189. data/manual/html/mandatory.html +1 -1
  190. data/manual/html/maxend.html +1 -1
  191. data/manual/html/maximum.html +1 -1
  192. data/manual/html/maxstart.html +1 -1
  193. data/manual/html/milestone.html +1 -1
  194. data/manual/html/minend.html +1 -1
  195. data/manual/html/minimum.html +1 -1
  196. data/manual/html/minstart.html +1 -1
  197. data/manual/html/monthlymax.html +1 -1
  198. data/manual/html/monthlymin.html +1 -1
  199. data/manual/html/navbar.html +9 -1
  200. data/manual/html/navigator.html +1 -1
  201. data/manual/html/newtask.html +1 -1
  202. data/manual/html/nikureport.html +1 -1
  203. data/manual/html/note.task.html +1 -1
  204. data/manual/html/now.html +1 -1
  205. data/manual/html/numberformat.html +1 -1
  206. data/manual/html/onend.html +1 -1
  207. data/manual/html/onstart.html +1 -1
  208. data/manual/html/opennodes.html +1 -1
  209. data/manual/html/overtime.booking.html +1 -1
  210. data/manual/html/period.column.html +1 -1
  211. data/manual/html/period.limit.html +1 -1
  212. data/manual/html/period.report.html +1 -1
  213. data/manual/html/period.task.html +1 -1
  214. data/manual/html/persistent.html +1 -1
  215. data/manual/html/precedes.html +1 -1
  216. data/manual/html/priority.html +1 -1
  217. data/manual/html/priority.timesheet.html +1 -1
  218. data/manual/html/project.html +1 -1
  219. data/manual/html/projectid.html +1 -1
  220. data/manual/html/projectid.task.html +1 -1
  221. data/manual/html/projectids.html +1 -1
  222. data/manual/html/projection.html +1 -1
  223. data/manual/html/prolog.html +1 -1
  224. data/manual/html/properties.html +1 -1
  225. data/manual/html/purge.html +1 -1
  226. data/manual/html/rate.html +1 -1
  227. data/manual/html/rate.resource.html +3 -3
  228. data/manual/html/rawhtmlhead.html +68 -0
  229. data/manual/html/reference.extend.html +3 -3
  230. data/manual/html/remaining.html +1 -1
  231. data/manual/html/replace.html +1 -1
  232. data/manual/html/reportprefix.html +1 -1
  233. data/manual/html/resource.html +1 -1
  234. data/manual/html/resourceattributes.html +1 -1
  235. data/manual/html/resourceprefix.html +1 -1
  236. data/manual/html/resourcereport.html +14 -2
  237. data/manual/html/resourceroot.html +1 -1
  238. data/manual/html/resources.limit.html +1 -1
  239. data/manual/html/responsible.html +1 -1
  240. data/manual/html/richtext.extend.html +1 -1
  241. data/manual/html/right.html +1 -1
  242. data/manual/html/rollupaccount.html +1 -1
  243. data/manual/html/rollupresource.html +1 -1
  244. data/manual/html/rolluptask.html +1 -1
  245. data/manual/html/scale.column.html +1 -1
  246. data/manual/html/scenario.html +1 -1
  247. data/manual/html/scenario.ical.html +1 -1
  248. data/manual/html/scenarios.export.html +1 -1
  249. data/manual/html/scenarios.html +1 -1
  250. data/manual/html/scenariospecific.extend.html +1 -1
  251. data/manual/html/scheduled.html +1 -1
  252. data/manual/html/scheduling.html +2 -1
  253. data/manual/html/select.html +1 -1
  254. data/manual/html/selfcontained.html +1 -1
  255. data/manual/html/shift.allocate.html +1 -1
  256. data/manual/html/shift.html +1 -1
  257. data/manual/html/shift.resource.html +1 -1
  258. data/manual/html/shift.task.html +1 -1
  259. data/manual/html/shift.timesheet.html +1 -1
  260. data/manual/html/shifts.allocate.html +1 -1
  261. data/manual/html/shifts.resource.html +1 -1
  262. data/manual/html/shifts.task.html +1 -1
  263. data/manual/html/shorttimeformat.html +1 -1
  264. data/manual/html/sloppy.booking.html +1 -1
  265. data/manual/html/sloppy.projection.html +1 -1
  266. data/manual/html/sortaccounts.html +1 -1
  267. data/manual/html/sortjournalentries.html +1 -1
  268. data/manual/html/sortresources.html +1 -1
  269. data/manual/html/sorttasks.html +1 -1
  270. data/manual/html/start.column.html +1 -1
  271. data/manual/html/start.html +1 -1
  272. data/manual/html/start.limit.html +1 -1
  273. data/manual/html/start.report.html +1 -1
  274. data/manual/html/startcredit.html +1 -1
  275. data/manual/html/status.statussheet.html +1 -1
  276. data/manual/html/status.timesheet.html +1 -1
  277. data/manual/html/statussheet.html +1 -1
  278. data/manual/html/statussheetreport.html +1 -1
  279. data/manual/html/strict.projection.html +1 -1
  280. data/manual/html/summary.html +1 -1
  281. data/manual/html/supplement.html +1 -1
  282. data/manual/html/supplement.resource.html +1 -1
  283. data/manual/html/supplement.task.html +1 -1
  284. data/manual/html/tagfile.html +2 -2
  285. data/manual/html/task.html +1 -1
  286. data/manual/html/task.statussheet.html +1 -1
  287. data/manual/html/task.timesheet.html +1 -1
  288. data/manual/html/taskattributes.html +1 -1
  289. data/manual/html/taskprefix.html +1 -1
  290. data/manual/html/taskreport.html +14 -2
  291. data/manual/html/taskroot.export.html +1 -1
  292. data/manual/html/taskroot.html +1 -1
  293. data/manual/html/text.extend.html +1 -1
  294. data/manual/html/textreport.html +14 -2
  295. data/manual/html/timeformat.html +3 -3
  296. data/manual/html/timeformat1.html +67 -0
  297. data/manual/html/timeformat2.html +67 -0
  298. data/manual/html/timeoff.nikureport.html +3 -3
  299. data/manual/html/timesheet.html +1 -1
  300. data/manual/html/timesheetreport.html +1 -1
  301. data/manual/html/timezone.export.html +1 -1
  302. data/manual/html/timezone.html +1 -1
  303. data/manual/html/timezone.report.html +1 -1
  304. data/manual/html/timezone.shift.html +1 -1
  305. data/manual/html/timingresolution.html +1 -1
  306. data/manual/html/title.column.html +1 -1
  307. data/manual/html/title.html +1 -1
  308. data/manual/html/toc.html +270 -242
  309. data/manual/html/tooltip.column.html +1 -1
  310. data/manual/html/tracereport.html +14 -2
  311. data/manual/html/trackingscenario.html +1 -1
  312. data/manual/html/treelevel.html +1 -1
  313. data/manual/html/vacation.html +1 -1
  314. data/manual/html/vacation.resource.html +1 -1
  315. data/manual/html/vacation.shift.html +1 -1
  316. data/manual/html/warn.html +1 -1
  317. data/manual/html/weeklymax.html +1 -1
  318. data/manual/html/weeklymin.html +1 -1
  319. data/manual/html/weekstartsmonday.html +1 -1
  320. data/manual/html/weekstartssunday.html +1 -1
  321. data/manual/html/width.column.html +1 -1
  322. data/manual/html/width.html +1 -1
  323. data/manual/html/work.html +1 -1
  324. data/manual/html/workinghours.project.html +1 -1
  325. data/manual/html/workinghours.resource.html +1 -1
  326. data/manual/html/workinghours.shift.html +1 -1
  327. data/manual/html/yearlyworkingdays.html +1 -1
  328. data/tasks/kate.rake +8 -0
  329. data/test/TestSuite/HTML-Reports/Calendars.tjp +10 -0
  330. data/test/TestSuite/Scheduler/Correct/PersistentResources-2.tjp +33 -0
  331. data/test/TestSuite/Scheduler/Correct/PersistentResources.tjp +30 -0
  332. data/test/TestSuite/Scheduler/Correct/PriorityInversion.tjp +2 -0
  333. data/test/TestSuite/Syntax/Correct/Macro-4.tjp +4 -0
  334. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
  335. data/test/test_BatchProcessor.rb +1 -1
  336. data/test/test_CSVFile.rb +10 -0
  337. data/test/test_RichText.rb +20 -0
  338. metadata +38 -9
@@ -83,6 +83,20 @@ class TaskJuggler
83
83
  end
84
84
  end
85
85
 
86
+ # Decrease the counter if the _index_ matches the @interval. The
87
+ # relationship between @resource and _resource_ is described below.
88
+ # @r \ _r_ nil y
89
+ # nil inc inc
90
+ # x - if x==y inc else -
91
+ def dec(index, resource)
92
+ if @interval.contains?(index) &&
93
+ (@resource.nil? || @resource == resource)
94
+ # The condition is met, decrement the counter for the interval.
95
+ @dirty = true
96
+ @scoreboard[idxToSbIdx(index)] -= 1
97
+ end
98
+ end
99
+
86
100
  # Returns true if the counter for the time slot specified by +index+ or
87
101
  # all counters are within the limit. If +upper+ is true, only upper
88
102
  # limits are checked. If not, only lower limits are checked. The
@@ -237,6 +251,14 @@ class TaskJuggler
237
251
  end
238
252
  end
239
253
 
254
+ # This function decreases the counters for all limits for a specific
255
+ # interval identified by _index_.
256
+ def dec(index, resource = nil)
257
+ @limits.each do |limit|
258
+ limit.dec(index, resource)
259
+ end
260
+ end
261
+
240
262
  # Check all upper limits and return true if none is exceeded. If an
241
263
  # _index_ is specified only the counters for that specific period are
242
264
  # tested. Otherwise all periods are tested. If _resource_ is nil, only
@@ -124,7 +124,7 @@ class TaskJuggler
124
124
 
125
125
  maxlen = 60
126
126
  text = text.ljust(maxlen)
127
- text = text[0..maxlen - 1] if text.length > maxlen
127
+ text = text[0..maxlen - 1] if text.length_utf8 > maxlen
128
128
  @@progressMeter = text
129
129
  $stdout.print("#{@@progressMeter} ...\r")
130
130
  end
@@ -115,7 +115,7 @@ class TaskJuggler
115
115
  include Singleton
116
116
 
117
117
  attr_reader :messages, :errors
118
- attr_accessor :logFile, :appName, :abortOnWarning, :trapSetup, :baselineSFI
118
+ attr_accessor :logFile, :appName, :abortOnWarning
119
119
 
120
120
  LogLevels = { :none => 0, :fatal => 1, :error => 2, :critical => 2,
121
121
  :warning => 3, :info => 4, :debug => 5 }
@@ -141,15 +141,25 @@ class TaskJuggler
141
141
  # Set to true if program should be exited on warnings.
142
142
  @abortOnWarning = false
143
143
  # A SourceFileInfo object that will be used to baseline the provided
144
- # source file infos of the messages.
145
- @baselineSFI = nil
146
- # If this is set the true, we only throw a TjRuntimeError instead of
147
- # using exit().
148
- @trapSetup = false
144
+ # source file infos of the messages. We use a Hash to keep per Thread
145
+ # values.
146
+ @baselineSFI = {}
147
+ # Each tread can request to only throw a TjRuntimeError instead of
148
+ # using exit(). This hash keeps a flag for each thread using the
149
+ # object_id of the Thread object as key.
150
+ @trapSetup = {}
149
151
 
150
152
  clear
151
153
  end
152
154
 
155
+ def baselineSFI=(line)
156
+ @baselineSFI[Thread.current.object_id] = line
157
+ end
158
+
159
+ def trapSetup=(enable)
160
+ @trapSetup[Thread.current.object_id] = enable
161
+ end
162
+
153
163
  # Clear the error log.
154
164
  def clear
155
165
  # A counter for messages of type error.
@@ -248,10 +258,10 @@ class TaskJuggler
248
258
  data = nil, scenario = nil)
249
259
  # If we have a SourceFileInfo and a baseline SFI, we correct the
250
260
  # sourceFileInfo accordingly.
251
- if sourceFileInfo && @baselineSFI
261
+ baselineSFI = @baselineSFI[Thread.current.object_id]
262
+ if sourceFileInfo && baselineSFI
252
263
  sourceFileInfo = TextParser::SourceFileInfo.new(
253
- @baselineSFI.fileName,
254
- sourceFileInfo.lineNo + @baselineSFI.lineNo - 1,
264
+ baselineSFI.fileName, sourceFileInfo.lineNo + baselineSFI.lineNo - 1,
255
265
  sourceFileInfo.columnNo)
256
266
  end
257
267
 
@@ -276,7 +286,7 @@ class TaskJuggler
276
286
  when :error
277
287
  # Increase the error counter.
278
288
  @errors += 1
279
- if @trapSetup
289
+ if @trapSetup[Thread.current.object_id]
280
290
  raise TjRuntimeError
281
291
  else
282
292
  exit 1
@@ -41,7 +41,12 @@ class TaskJuggler
41
41
  if @ptn.propertySet.flatNamespace
42
42
  @ptn.id
43
43
  else
44
- @parent.logicalId + '.' + @ptn.id[(@ptn.id.rindex('.') + 1).. -1]
44
+ if (dotPos = @ptn.id.rindex('.'))
45
+ id = @ptn.id[(dotPos + 1)..-1]
46
+ else
47
+ id = @ptn.id
48
+ end
49
+ @parent.logicalId + '.' + id
45
50
  end
46
51
  end
47
52
 
@@ -253,6 +253,8 @@ class TaskJuggler
253
253
  true, false, true, [] ],
254
254
  [ 'complete', 'Completion', FloatAttribute,
255
255
  false, false, true, nil ],
256
+ [ 'competitors', 'Competitors', TaskListAttribute,
257
+ false, false, true, [] ],
256
258
  [ 'criticalness', 'Criticalness', FloatAttribute,
257
259
  false, false, true, 0.0 ],
258
260
  [ 'depends', 'Preceding tasks', DependencyListAttribute,
@@ -334,8 +336,10 @@ class TaskJuggler
334
336
  # Inh. Inh.Prj Scen. Default
335
337
  [ 'accountroot', 'Account Root', PropertyAttribute,
336
338
  true, false, false, nil ],
339
+ [ 'auxdir', 'Auxiliary files directory', StringAttribute,
340
+ true, false, false, '' ],
337
341
  [ 'bsi', 'BSI', StringAttribute,
338
- false, false, false, "" ],
342
+ false, false, false, '' ],
339
343
  [ 'caption', 'Caption', RichTextAttribute,
340
344
  true, false, false, nil ],
341
345
  [ 'center', 'Center', RichTextAttribute,
@@ -397,7 +401,9 @@ class TaskJuggler
397
401
  [ 'openNodes', 'Open Nodes', NodeListAttribute,
398
402
  false, false, false, nil ],
399
403
  [ 'prolog', 'Prolog', RichTextAttribute,
400
- true, false, false, nil],
404
+ true, false, false, nil ],
405
+ [ 'rawHtmlHead', 'Raw HTML Header', StringAttribute,
406
+ true, false, false, nil ],
401
407
  [ 'resourceAttributes', 'Resource Attributes', FormatListAttribute,
402
408
  true, false, false, KeywordArray.new([ '*' ]) ],
403
409
  [ 'resourceroot', 'resource Root', PropertyAttribute,
@@ -1150,8 +1156,8 @@ class TaskJuggler
1150
1156
  # Schedule all tasks for the given Scenario with index +scIdx+.
1151
1157
  def scheduleScenario(scIdx)
1152
1158
  tasks = PropertyList.new(@tasks)
1153
- # Only care about leaf tasks that are not milestones are aren't
1154
- # scheduled already (due to bookings).
1159
+ # Only care about leaf tasks that are not milestones and aren't
1160
+ # scheduled already (marked with the 'scheduled' attribute).
1155
1161
  tasks.delete_if { |task| !task.leaf? ||
1156
1162
  task['milestone', scIdx] ||
1157
1163
  task['scheduled', scIdx] }
@@ -466,8 +466,7 @@ class TaskJuggler
466
466
  # Pop the last stack entry from the @fileStack and restore the class
467
467
  # variables according to the now top-entry.
468
468
  def popFileStack
469
- @fileStack.pop
470
- stackEntry = @fileStack.last
469
+ stackEntry = @fileStack.pop
471
470
  @fileStackVariables.each do |var|
472
471
  instance_variable_set('@' + var, stackEntry[var])
473
472
  end
@@ -22,26 +22,26 @@ class TaskJuggler
22
22
  def initialize(masterFile)
23
23
  tokenPatterns = [
24
24
  # Any white spaces
25
- [ nil, '\s+', /\s+/, :tjp, method('newPos') ],
25
+ [ nil, /\s+/, :tjp, method('newPos') ],
26
26
 
27
27
  # Single line comments starting with #
28
- [ nil, '#.*\n?', /#.*\n?/, :tjp, method('newPos') ],
28
+ [ nil, /#.*\n?/, :tjp, method('newPos') ],
29
29
 
30
30
  # C++ style single line comments starting with //
31
- [ nil, '//.*\n?', /\/\/.*\n?/, :tjp, method('newPos') ],
31
+ [ nil, /\/\/.*\n?/, :tjp, method('newPos') ],
32
32
 
33
33
  # C style single line comment /* .. */.
34
- [ nil, '/\*.*\*/', /\/\*.*\*\//, :tjp, method('newPos') ],
34
+ [ nil, /\/\*.*\*\//, :tjp, method('newPos') ],
35
35
 
36
36
  # C style multi line comment: We need three patterns here. The first
37
37
  # one is for the start of the string. It switches the scanner mode to
38
38
  # the :cppComment mode.
39
- [ nil, '/\*([^*]*[^/]|.*)\n', /\/\*([^*]*[^\/]|.*)\n/, :tjp, method('startComment') ],
39
+ [ nil, /\/\*([^*]*[^\/]|.*)\n/, :tjp, method('startComment') ],
40
40
  # This is the string end pattern. It switches back to tjp mode.
41
- [ nil, '.*\*/', /.*\*\//, :cppComment, method('endComment') ],
41
+ [ nil, /.*\*\//, :cppComment, method('endComment') ],
42
42
  # This pattern matches string lines that contain neither the start,
43
43
  # nor the end of the string.
44
- [ nil, '^.*\n', /^.*\n/, :cppComment ],
44
+ [ nil, /^.*\n/, :cppComment ],
45
45
 
46
46
  # Macro Call: This case is more complicated because we want to replace
47
47
  # macro calls inside of numbers, strings and identifiers. For this to
@@ -54,102 +54,100 @@ class TaskJuggler
54
54
  # with neither start nor end. Macro calls inside of strings need a
55
55
  # special start pattern that is active in the string modes. Both
56
56
  # patterns switch the scanner to macroCall mode.
57
- [ nil, '([-a-zA-Z_0-9>:.+]*|"(\\\\"|[^"])*?|\'(\\\\\'|[^\'])*?)?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\\\"|[^"])*")*', /([-a-zA-Z_0-9>:.+]*|"(\\"|[^"])*?|'(\\'|[^'])*?)?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
57
+ [ nil, /([-a-zA-Z_0-9>:.+]*|"(\\"|[^"])*?|'(\\'|[^'])*?)?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
58
58
  :tjp, method('startMacroCall') ],
59
59
  # This pattern is similar to the previous one, but is active inside of
60
60
  # multi-line strings. The corresponding rule for sizzors strings
61
61
  # can be found below.
62
- [ nil, '(\\\\"|[^"])*?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\\\"|[^"])*")*',
63
- /(\\"|[^"])*?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
62
+ [ nil, /(\\"|[^"])*?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
64
63
  :dqString, method('startMacroCall') ],
65
- [ nil, '(\\\\\'|[^\'])*?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\\\"|[^"])*")*',
66
- /(\\'|[^'])*?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
64
+ [ nil, /(\\'|[^'])*?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
67
65
  :sqString, method('startMacroCall') ],
68
66
  # This pattern matches the end of a macro call. It injects the prefix
69
67
  # and the expanded macro into the scanner again. The mode is restored
70
68
  # to the previous mode.
71
- [ nil, '(\s*"(\\\\"|[^"])*")*\s*\}', /(\s*"(\\"|[^"])*")*\s*\}/, :macroCall, method('endMacroCall') ],
69
+ [ nil, /(\s*"(\\"|[^"])*")*\s*\}/, :macroCall, method('endMacroCall') ],
72
70
  # This pattern collects macro call arguments in lines that contain
73
71
  # neither the start nor the end of the macro.
74
- [ nil, '.*\n', /.*\n/, :macroCall, method('midMacroCall') ],
72
+ [ nil, /.*\n/, :macroCall, method('midMacroCall') ],
75
73
 
76
74
  # Environment variable reference. This is similar to the macro call,
77
75
  # but the it can only extend within the starting line.
78
- [ nil, '([-a-zA-Z_0-9>:.+]*|"(\\\\"|[^"])*?|\'(\\\\\'|[^\'])*?)?\$\([A-Z_][A-Z_0-9]*\)', /([-a-zA-Z_0-9>:.+]*|"(\\"|[^"])*?|'(\\'|[^'])*?)?\$\([A-Z_][A-Z_0-9]*\)/,
76
+ [ nil, /([-a-zA-Z_0-9>:.+]*|"(\\"|[^"])*?|'(\\'|[^'])*?)?\$\([A-Z_][A-Z_0-9]*\)/,
79
77
  :tjp, method('environmentVariable') ],
80
78
  # An ID with a colon suffix: foo:
81
- [ :ID_WITH_COLON, '[a-zA-Z_]\w*:', /[a-zA-Z_]\w*:/, :tjp, method('chop') ],
79
+ [ :ID_WITH_COLON, /[a-zA-Z_]\w*:/, :tjp, method('chop') ],
82
80
 
83
81
  # An absolute ID: a.b.c
84
- [ :ABSOLUTE_ID, '[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)+', /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)+/ ],
82
+ [ :ABSOLUTE_ID, /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)+/ ],
85
83
 
86
84
  # A normal ID: bar
87
- [ :ID, '[a-zA-Z_]\w*', /[a-zA-Z_]\w*/ ],
85
+ [ :ID, /[a-zA-Z_]\w*/ ],
88
86
 
89
87
  # A date
90
- [ :DATE, '\d{4}-\d{1,2}-\d{1,2}(-\d{1,2}:\d{1,2}(:\d{1,2})?(-[-+]?\d{4})?)?', /\d{4}-\d{1,2}-\d{1,2}(-\d{1,2}:\d{1,2}(:\d{1,2})?(-[-+]?\d{4})?)?/, :tjp, method('to_date') ],
88
+ [ :DATE, /\d{4}-\d{1,2}-\d{1,2}(-\d{1,2}:\d{1,2}(:\d{1,2})?(-[-+]?\d{4})?)?/, :tjp, method('to_date') ],
91
89
 
92
90
  # A time of day
93
- [ :TIME, '\d{1,2}:\d{2}', /\d{1,2}:\d{2}/, :tjp, method('to_time') ],
91
+ [ :TIME, /\d{1,2}:\d{2}/, :tjp, method('to_time') ],
94
92
 
95
93
  # A floating point number (e. g. 3.143)
96
- [ :FLOAT, '\d*\.\d+', /\d*\.\d+/, :tjp, method('to_f') ],
94
+ [ :FLOAT, /\d*\.\d+/, :tjp, method('to_f') ],
97
95
 
98
96
  # An integer number
99
- [ :INTEGER, '\d+', /\d+/, :tjp, method('to_i') ],
97
+ [ :INTEGER, /\d+/, :tjp, method('to_i') ],
100
98
 
101
99
  # Multi line string enclosed with double quotes. The string may
102
100
  # contain double quotes prefixed by a backslash. The first rule
103
101
  # switches the scanner to dqString mode.
104
- [ 'nil', '"(\\\\"|[^"])*', /"(\\"|[^"])*/, :tjp, method('startStringDQ') ],
102
+ [ 'nil', /"(\\"|[^"])*/, :tjp, method('startStringDQ') ],
105
103
  # Any line not containing the start or end.
106
- [ 'nil', '^(\\\\"|[^"])*\n', /^(\\"|[^"])*\n/, :dqString, method('midStringDQ') ],
104
+ [ 'nil', /^(\\"|[^"])*\n/, :dqString, method('midStringDQ') ],
107
105
  # The end of the string.
108
- [ :STRING, '(\\\\"|[^"])*"', /(\\"|[^"])*"/, :dqString, method('endStringDQ') ],
106
+ [ :STRING, /(\\"|[^"])*"/, :dqString, method('endStringDQ') ],
109
107
 
110
108
  # Multi line string enclosed with single quotes.
111
- [ 'nil', '\'(\\\\\'|[^\'])*', /'(\\'|[^'])*/, :tjp, method('startStringSQ') ],
109
+ [ 'nil', /'(\\'|[^'])*/, :tjp, method('startStringSQ') ],
112
110
  # Any line not containing the start or end.
113
- [ 'nil', '^(\\\\\'|[^\'])*\n', /^(\\'|[^'])*\n/, :sqString, method('midStringSQ') ],
111
+ [ 'nil', /^(\\'|[^'])*\n/, :sqString, method('midStringSQ') ],
114
112
  # The end of the string.
115
- [ :STRING, '(\\\\\'|[^\'])*\'', /(\\'|[^'])*'/, :sqString, method('endStringSQ') ],
113
+ [ :STRING, /(\\'|[^'])*'/, :sqString, method('endStringSQ') ],
116
114
 
117
115
  # Scizzors marked string -8<- ... ->8-: The opening mark must be the
118
116
  # last thing in the line. The indentation of the first line after the
119
117
  # opening mark determines the indentation for all following lines. So,
120
118
  # we first switch the scanner to szrString1 mode.
121
- [ 'nil', '-8<-.*\n', /-8<-.*\n/, :tjp, method('startStringSZR') ],
119
+ [ 'nil', /-8<-.*\n/, :tjp, method('startStringSZR') ],
122
120
  # Since the first line can be the last line (empty string case), we
123
121
  # need to detect the end in szrString1 and szrString mode. The
124
122
  # patterns switch the scanner back to tjp mode.
125
- [ :STRING, '\s*->8-', /\s*->8-/, :szrString1, method('endStringSZR') ],
126
- [ :STRING, '\s*->8-', /\s*->8-/, :szrString, method('endStringSZR') ],
123
+ [ :STRING, /\s*->8-/, :szrString1, method('endStringSZR') ],
124
+ [ :STRING, /\s*->8-/, :szrString, method('endStringSZR') ],
127
125
  # This rule handles macros inside of sizzors strings.
128
- [ nil, '.*?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\\\"|[^"])*")*', /.*?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
126
+ [ nil, /.*?\$\{\s*(\??[a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
129
127
  [ :szrString, :szrString1 ], method('startMacroCall') ],
130
128
  # Any line not containing the start or end.
131
- [ 'nil', '.*\n', /.*\n/, :szrString1, method('firstStringSZR') ],
132
- [ 'nil', '.*\n', /.*\n/, :szrString, method('midStringSZR') ],
129
+ [ 'nil', /.*\n/, :szrString1, method('firstStringSZR') ],
130
+ [ 'nil', /.*\n/, :szrString, method('midStringSZR') ],
133
131
 
134
132
  # Single line macro definition
135
- [ :MACRO, '\[.*\](\n|$)', /\[.*\]\n/, :tjp, method('chop2nl') ],
133
+ [ :MACRO, /\[.*\]\n/, :tjp, method('chop2nl') ],
136
134
 
137
135
  # Multi line macro definition: The pattern switches the scanner into
138
136
  # macroDef mode.
139
- [ nil, '\[.*\n', /\[.*\n/, :tjp, method('startMacroDef') ],
137
+ [ nil, /\[.*\n/, :tjp, method('startMacroDef') ],
140
138
  # The end of the macro is marked by a ']' that is immediately followed
141
139
  # by a line break. It switches the scanner back to tjp mode.
142
- [ :MACRO, '.*\](\n|$)', /.*\]\n/, :macroDef, method('endMacroDef') ],
140
+ [ :MACRO, /.*\]\n/, :macroDef, method('endMacroDef') ],
143
141
  # Any line not containing the start or end.
144
- [ nil, '.*\n', /.*\n/, :macroDef, method('midMacroDef') ],
142
+ [ nil, /.*\n/, :macroDef, method('midMacroDef') ],
145
143
 
146
144
  # Some multi-char literals.
147
- [ :LITERAL, '<=?', /<=?/ ],
148
- [ :LITERAL, '>=?', />=?/ ],
149
- [ :LITERAL, '!=?', /!=?/ ],
145
+ [ :LITERAL, /<=?/ ],
146
+ [ :LITERAL, />=?/ ],
147
+ [ :LITERAL, /!=?/ ],
150
148
 
151
149
  # Everything else is returned as a single-char literal.
152
- [ :LITERAL, '.', /./ ]
150
+ [ :LITERAL, /./ ]
153
151
  ]
154
152
 
155
153
  super(masterFile, Log, tokenPatterns, :tjp)
@@ -375,6 +373,7 @@ class TaskJuggler
375
373
  macroCallLength = @macroCall.length
376
374
  # Remove '${' and '}' and white spaces at begin and end
377
375
  argsStr = @macroCall[2..-2].sub(/^[ \t\n]*(.*?)[ \t\n]*$/, '\1')
376
+
378
377
  # Extract the macro name.
379
378
  if argsStr.index(' ').nil?
380
379
  expandMacro(prefix, [ argsStr ], macroCallLength)
@@ -51,6 +51,11 @@ class TaskJuggler
51
51
  # Same but for each assigned resource.
52
52
  @lastBookedSlots = {}
53
53
 
54
+ # First available slot of the resource.
55
+ @minslot = nil
56
+ # Last available slot of the resource.
57
+ @maxslot = nil
58
+
54
59
  # Attributed are only really created when they are accessed the first
55
60
  # time. So make sure some needed attributes really exist so we don't
56
61
  # have to check for existance each time we access them.
@@ -170,6 +175,13 @@ class TaskJuggler
170
175
  @scoreboard[sbIdx].is_a?(Task)
171
176
  end
172
177
 
178
+ # Return the Task that this resource is booked for at the time specified
179
+ # by _sbIdx_. If not booked to a task, nil is returned.
180
+ def bookedTask(sbIdx)
181
+ return nil unless (sb = @scoreboard[sbIdx]).is_a?(Task)
182
+ sb
183
+ end
184
+
173
185
  # Book the slot indicated by the scoreboard index +sbIdx+ for Task +task+.
174
186
  # If +force+ is true, overwrite the existing booking for this slot. The
175
187
  # method returns true if the slot was available.
@@ -677,7 +689,7 @@ class TaskJuggler
677
689
  # Count the booked slots between the start and end index. If _task_ is not
678
690
  # nil count only those slots that are assigned to this particular task or
679
691
  # any of its sub tasks.
680
- def getAllocatedSlots(startIdx, endIdx, task)
692
+ def getAllocatedSlots(startIdx, endIdx, task = nil)
681
693
  # If there is no scoreboard, we don't have any allocations.
682
694
  return 0 unless @scoreboard
683
695
 
@@ -728,6 +740,16 @@ class TaskJuggler
728
740
  end
729
741
  end
730
742
 
743
+ # Get the first available slot of the resource.
744
+ def getMinSlot
745
+ @minslot
746
+ end
747
+
748
+ # Get the last available slot of the resource.
749
+ def getMaxSlot
750
+ @maxslot
751
+ end
752
+
731
753
  private
732
754
 
733
755
  def initScoreboard
@@ -792,6 +814,24 @@ class TaskJuggler
792
814
  end
793
815
  end
794
816
  end
817
+
818
+ # Set minimum and maximum availability
819
+ idx = 0
820
+ while idx < @scoreboard.size
821
+ if available?(idx)
822
+ @minslot = idx
823
+ break
824
+ end
825
+ idx += 1
826
+ end
827
+ idx = @scoreboard.size - 1
828
+ while idx >= 0
829
+ if available?(idx)
830
+ @maxslot = idx
831
+ break
832
+ end
833
+ idx -= 1
834
+ end
795
835
  end
796
836
 
797
837
  def countSlots(startIdx, endIdx)
@@ -224,6 +224,8 @@ class TaskJuggler
224
224
  when :fontCol
225
225
  when :code
226
226
  when :text
227
+ when :htmlblob
228
+ return ''
227
229
  else
228
230
  raise "Unknown RichTextElement category #{@category}"
229
231
  end
@@ -348,6 +350,9 @@ class TaskJuggler
348
350
  when :code
349
351
  pre = '<code>'
350
352
  post = '</code>'
353
+ when :htmlblob
354
+ pre = '<html>'
355
+ post = '</html>'
351
356
  when :text
352
357
  pre = '['
353
358
  post = ']'
@@ -460,6 +465,9 @@ class TaskJuggler
460
465
  XMLElement.new('span', 'style' => "color:#{@data}")
461
466
  when :code
462
467
  XMLElement.new('code', attrs)
468
+ when :htmlblob
469
+ noChilds = true
470
+ XMLBlob.new(@children[0])
463
471
  when :text
464
472
  noChilds = true
465
473
  XMLText.new(@children[0])