@@ -19,6 +19,9 module Redmine | |||||
19 | module Helpers |
|
19 | module Helpers | |
20 | # Simple class to handle gantt chart data |
|
20 | # Simple class to handle gantt chart data | |
21 | class Gantt |
|
21 | class Gantt | |
|
22 | class MaxLinesLimitReached < Exception | |||
|
23 | end | |||
|
24 | ||||
22 | include ERB::Util |
|
25 | include ERB::Util | |
23 | include Redmine::I18n |
|
26 | include Redmine::I18n | |
24 | include Redmine::Utils::DateCalculation |
|
27 | include Redmine::Utils::DateCalculation | |
@@ -74,7 +77,6 module Redmine | |||||
74 | @subjects = '' |
|
77 | @subjects = '' | |
75 | @lines = '' |
|
78 | @lines = '' | |
76 | @number_of_rows = nil |
|
79 | @number_of_rows = nil | |
77 | @issue_ancestors = [] |
|
|||
78 | @truncated = false |
|
80 | @truncated = false | |
79 | if options.has_key?(:max_rows) |
|
81 | if options.has_key?(:max_rows) | |
80 | @max_rows = options[:max_rows] |
|
82 | @max_rows = options[:max_rows] | |
@@ -197,10 +199,13 module Redmine | |||||
197 | @subjects = '' unless options[:only] == :lines |
|
199 | @subjects = '' unless options[:only] == :lines | |
198 | @lines = '' unless options[:only] == :subjects |
|
200 | @lines = '' unless options[:only] == :subjects | |
199 | @number_of_rows = 0 |
|
201 | @number_of_rows = 0 | |
200 | Project.project_tree(projects) do |project, level| |
|
202 | begin | |
201 | options[:indent] = indent + level * options[:indent_increment] |
|
203 | Project.project_tree(projects) do |project, level| | |
202 | render_project(project, options) |
|
204 | options[:indent] = indent + level * options[:indent_increment] | |
203 | break if abort? |
|
205 | render_project(project, options) | |
|
206 | end | |||
|
207 | rescue MaxLinesLimitReached | |||
|
208 | @truncated = true | |||
204 | end |
|
209 | end | |
205 | @subjects_rendered = true unless options[:only] == :lines |
|
210 | @subjects_rendered = true unless options[:only] == :lines | |
206 | @lines_rendered = true unless options[:only] == :subjects |
|
211 | @lines_rendered = true unless options[:only] == :subjects | |
@@ -208,53 +213,53 module Redmine | |||||
208 | end |
|
213 | end | |
209 |
|
214 | |||
210 | def render_project(project, options={}) |
|
215 | def render_project(project, options={}) | |
211 | subject_for_project(project, options) unless options[:only] == :lines |
|
216 | render_object_row(project, options) | |
212 | line_for_project(project, options) unless options[:only] == :subjects |
|
217 | increment_indent(options) do | |
213 | options[:top] += options[:top_increment] |
|
218 | # render issue that are not assigned to a version | |
214 | options[:indent] += options[:indent_increment] |
|
219 | issues = project_issues(project).select {|i| i.fixed_version.nil?} | |
215 | @number_of_rows += 1 |
|
|||
216 | return if abort? |
|
|||
217 | issues = project_issues(project).select {|i| i.fixed_version.nil?} |
|
|||
218 | self.class.sort_issues!(issues) |
|
|||
219 | if issues |
|
|||
220 | render_issues(issues, options) |
|
220 | render_issues(issues, options) | |
221 | return if abort? |
|
221 | # then render project versions and their issues | |
|
222 | versions = project_versions(project) | |||
|
223 | self.class.sort_versions!(versions) | |||
|
224 | versions.each do |version| | |||
|
225 | render_version(project, version, options) | |||
|
226 | end | |||
222 | end |
|
227 | end | |
223 | versions = project_versions(project) |
|
228 | end | |
224 | self.class.sort_versions!(versions) |
|
229 | ||
225 | versions.each do |version| |
|
230 | def render_version(project, version, options={}) | |
226 |
|
|
231 | render_object_row(version, options) | |
|
232 | increment_indent(options) do | |||
|
233 | issues = version_issues(project, version) | |||
|
234 | render_issues(issues, options) | |||
227 | end |
|
235 | end | |
228 | # Remove indent to hit the next sibling |
|
|||
229 | options[:indent] -= options[:indent_increment] |
|
|||
230 | end |
|
236 | end | |
231 |
|
237 | |||
232 | def render_issues(issues, options={}) |
|
238 | def render_issues(issues, options={}) | |
233 | @issue_ancestors = [] |
|
239 | self.class.sort_issues!(issues) | |
234 | issues.each do |i| |
|
240 | ancestors = [] | |
235 | subject_for_issue(i, options) unless options[:only] == :lines |
|
241 | issues.each do |issue| | |
236 | line_for_issue(i, options) unless options[:only] == :subjects |
|
242 | while ancestors.any? && !issue.is_descendant_of?(ancestors.last) | |
237 | options[:top] += options[:top_increment] |
|
243 | ancestors.pop | |
238 | @number_of_rows += 1 |
|
244 | decrement_indent(options) | |
239 | break if abort? |
|
245 | end | |
|
246 | render_object_row(issue, options) | |||
|
247 | unless issue.leaf? | |||
|
248 | ancestors << issue | |||
|
249 | increment_indent(options) | |||
|
250 | end | |||
240 | end |
|
251 | end | |
241 |
|
|
252 | decrement_indent(options, ancestors.size) | |
242 | end |
|
253 | end | |
243 |
|
254 | |||
244 |
def render_ |
|
255 | def render_object_row(object, options) | |
245 | # Version header |
|
256 | class_name = object.class.name.downcase | |
246 |
s |
|
257 | send("subject_for_#{class_name}", object, options) unless options[:only] == :lines | |
247 |
|
|
258 | send("line_for_#{class_name}", object, options) unless options[:only] == :subjects | |
248 | options[:top] += options[:top_increment] |
|
259 | options[:top] += options[:top_increment] | |
249 | @number_of_rows += 1 |
|
260 | @number_of_rows += 1 | |
250 | return if abort? |
|
261 | if @max_rows && @number_of_rows >= @max_rows | |
251 | issues = version_issues(project, version) |
|
262 | raise MaxLinesLimitReached | |
252 | if issues |
|
|||
253 | self.class.sort_issues!(issues) |
|
|||
254 | # Indent issues |
|
|||
255 | options[:indent] += options[:indent_increment] |
|
|||
256 | render_issues(issues, options) |
|
|||
257 | options[:indent] -= options[:indent_increment] |
|
|||
258 | end |
|
263 | end | |
259 | end |
|
264 | end | |
260 |
|
265 | |||
@@ -265,6 +270,18 module Redmine | |||||
265 | end |
|
270 | end | |
266 | end |
|
271 | end | |
267 |
|
272 | |||
|
273 | def increment_indent(options, factor=1) | |||
|
274 | options[:indent] += options[:indent_increment] * factor | |||
|
275 | if block_given? | |||
|
276 | yield | |||
|
277 | decrement_indent(options, factor) | |||
|
278 | end | |||
|
279 | end | |||
|
280 | ||||
|
281 | def decrement_indent(options, factor=1) | |||
|
282 | increment_indent(options, -factor) | |||
|
283 | end | |||
|
284 | ||||
268 | def subject_for_project(project, options) |
|
285 | def subject_for_project(project, options) | |
269 | case options[:format] |
|
286 | case options[:format] | |
270 | when :html |
|
287 | when :html | |
@@ -355,10 +372,6 module Redmine | |||||
355 | end |
|
372 | end | |
356 |
|
373 | |||
357 | def subject_for_issue(issue, options) |
|
374 | def subject_for_issue(issue, options) | |
358 | while @issue_ancestors.any? && !issue.is_descendant_of?(@issue_ancestors.last) |
|
|||
359 | @issue_ancestors.pop |
|
|||
360 | options[:indent] -= options[:indent_increment] |
|
|||
361 | end |
|
|||
362 | output = case options[:format] |
|
375 | output = case options[:format] | |
363 | when :html |
|
376 | when :html | |
364 | css_classes = '' |
|
377 | css_classes = '' | |
@@ -390,10 +403,6 module Redmine | |||||
390 | pdf_new_page?(options) |
|
403 | pdf_new_page?(options) | |
391 | pdf_subject(options, issue.subject) |
|
404 | pdf_subject(options, issue.subject) | |
392 | end |
|
405 | end | |
393 | unless issue.leaf? |
|
|||
394 | @issue_ancestors << issue |
|
|||
395 | options[:indent] += options[:indent_increment] |
|
|||
396 | end |
|
|||
397 | output |
|
406 | output | |
398 | end |
|
407 | end | |
399 |
|
408 | |||
@@ -696,20 +705,6 module Redmine | |||||
696 | versions.sort! |
|
705 | versions.sort! | |
697 | end |
|
706 | end | |
698 |
|
707 | |||
699 | def current_limit |
|
|||
700 | if @max_rows |
|
|||
701 | @max_rows - @number_of_rows |
|
|||
702 | else |
|
|||
703 | nil |
|
|||
704 | end |
|
|||
705 | end |
|
|||
706 |
|
||||
707 | def abort? |
|
|||
708 | if @max_rows && @number_of_rows >= @max_rows |
|
|||
709 | @truncated = true |
|
|||
710 | end |
|
|||
711 | end |
|
|||
712 |
|
||||
713 | def pdf_new_page?(options) |
|
708 | def pdf_new_page?(options) | |
714 | if options[:top] > 180 |
|
709 | if options[:top] > 180 | |
715 | options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top]) |
|
710 | options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top]) |
General Comments 0
You need to be logged in to leave comments.
Login now