taskjuggler 3.3.0 → 3.4.0

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