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