##// END OF EJS Templates
Fixed: private method 'gsub' called for nil:NilClass on activity (#1519)....
Jean-Philippe Lang -
r1568:c97a5efde911
parent child
Show More
@@ -1,198 +1,198
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module ProjectsHelper
18 module ProjectsHelper
19 def link_to_version(version, options = {})
19 def link_to_version(version, options = {})
20 return '' unless version && version.is_a?(Version)
20 return '' unless version && version.is_a?(Version)
21 link_to h(version.name), { :controller => 'versions', :action => 'show', :id => version }, options
21 link_to h(version.name), { :controller => 'versions', :action => 'show', :id => version }, options
22 end
22 end
23
23
24 def format_activity_title(text)
24 def format_activity_title(text)
25 h(truncate_single_line(text, 100))
25 h(truncate_single_line(text, 100))
26 end
26 end
27
27
28 def format_activity_day(date)
28 def format_activity_day(date)
29 date == Date.today ? l(:label_today).titleize : format_date(date)
29 date == Date.today ? l(:label_today).titleize : format_date(date)
30 end
30 end
31
31
32 def format_activity_description(text)
32 def format_activity_description(text)
33 h(truncate(text, 250).gsub(%r{<(pre|code)>.*$}m, '...'))
33 h(truncate(text.to_s, 250).gsub(%r{<(pre|code)>.*$}m, '...'))
34 end
34 end
35
35
36 def project_settings_tabs
36 def project_settings_tabs
37 tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
37 tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
38 {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
38 {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
39 {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
39 {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
40 {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
40 {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
41 {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
41 {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
42 {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
42 {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
43 {:name => 'repository', :action => :manage_repository, :partial => 'projects/settings/repository', :label => :label_repository},
43 {:name => 'repository', :action => :manage_repository, :partial => 'projects/settings/repository', :label => :label_repository},
44 {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}
44 {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}
45 ]
45 ]
46 tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
46 tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
47 end
47 end
48
48
49 # Generates a gantt image
49 # Generates a gantt image
50 # Only defined if RMagick is avalaible
50 # Only defined if RMagick is avalaible
51 def gantt_image(events, date_from, months, zoom)
51 def gantt_image(events, date_from, months, zoom)
52 date_to = (date_from >> months)-1
52 date_to = (date_from >> months)-1
53 show_weeks = zoom > 1
53 show_weeks = zoom > 1
54 show_days = zoom > 2
54 show_days = zoom > 2
55
55
56 subject_width = 320
56 subject_width = 320
57 header_heigth = 18
57 header_heigth = 18
58 # width of one day in pixels
58 # width of one day in pixels
59 zoom = zoom*2
59 zoom = zoom*2
60 g_width = (date_to - date_from + 1)*zoom
60 g_width = (date_to - date_from + 1)*zoom
61 g_height = 20 * events.length + 20
61 g_height = 20 * events.length + 20
62 headers_heigth = (show_weeks ? 2*header_heigth : header_heigth)
62 headers_heigth = (show_weeks ? 2*header_heigth : header_heigth)
63 height = g_height + headers_heigth
63 height = g_height + headers_heigth
64
64
65 imgl = Magick::ImageList.new
65 imgl = Magick::ImageList.new
66 imgl.new_image(subject_width+g_width+1, height)
66 imgl.new_image(subject_width+g_width+1, height)
67 gc = Magick::Draw.new
67 gc = Magick::Draw.new
68
68
69 # Subjects
69 # Subjects
70 top = headers_heigth + 20
70 top = headers_heigth + 20
71 gc.fill('black')
71 gc.fill('black')
72 gc.stroke('transparent')
72 gc.stroke('transparent')
73 gc.stroke_width(1)
73 gc.stroke_width(1)
74 events.each do |i|
74 events.each do |i|
75 gc.text(4, top + 2, (i.is_a?(Issue) ? i.subject : i.name))
75 gc.text(4, top + 2, (i.is_a?(Issue) ? i.subject : i.name))
76 top = top + 20
76 top = top + 20
77 end
77 end
78
78
79 # Months headers
79 # Months headers
80 month_f = date_from
80 month_f = date_from
81 left = subject_width
81 left = subject_width
82 months.times do
82 months.times do
83 width = ((month_f >> 1) - month_f) * zoom
83 width = ((month_f >> 1) - month_f) * zoom
84 gc.fill('white')
84 gc.fill('white')
85 gc.stroke('grey')
85 gc.stroke('grey')
86 gc.stroke_width(1)
86 gc.stroke_width(1)
87 gc.rectangle(left, 0, left + width, height)
87 gc.rectangle(left, 0, left + width, height)
88 gc.fill('black')
88 gc.fill('black')
89 gc.stroke('transparent')
89 gc.stroke('transparent')
90 gc.stroke_width(1)
90 gc.stroke_width(1)
91 gc.text(left.round + 8, 14, "#{month_f.year}-#{month_f.month}")
91 gc.text(left.round + 8, 14, "#{month_f.year}-#{month_f.month}")
92 left = left + width
92 left = left + width
93 month_f = month_f >> 1
93 month_f = month_f >> 1
94 end
94 end
95
95
96 # Weeks headers
96 # Weeks headers
97 if show_weeks
97 if show_weeks
98 left = subject_width
98 left = subject_width
99 height = header_heigth
99 height = header_heigth
100 if date_from.cwday == 1
100 if date_from.cwday == 1
101 # date_from is monday
101 # date_from is monday
102 week_f = date_from
102 week_f = date_from
103 else
103 else
104 # find next monday after date_from
104 # find next monday after date_from
105 week_f = date_from + (7 - date_from.cwday + 1)
105 week_f = date_from + (7 - date_from.cwday + 1)
106 width = (7 - date_from.cwday + 1) * zoom
106 width = (7 - date_from.cwday + 1) * zoom
107 gc.fill('white')
107 gc.fill('white')
108 gc.stroke('grey')
108 gc.stroke('grey')
109 gc.stroke_width(1)
109 gc.stroke_width(1)
110 gc.rectangle(left, header_heigth, left + width, 2*header_heigth + g_height-1)
110 gc.rectangle(left, header_heigth, left + width, 2*header_heigth + g_height-1)
111 left = left + width
111 left = left + width
112 end
112 end
113 while week_f <= date_to
113 while week_f <= date_to
114 width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom
114 width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom
115 gc.fill('white')
115 gc.fill('white')
116 gc.stroke('grey')
116 gc.stroke('grey')
117 gc.stroke_width(1)
117 gc.stroke_width(1)
118 gc.rectangle(left.round, header_heigth, left.round + width, 2*header_heigth + g_height-1)
118 gc.rectangle(left.round, header_heigth, left.round + width, 2*header_heigth + g_height-1)
119 gc.fill('black')
119 gc.fill('black')
120 gc.stroke('transparent')
120 gc.stroke('transparent')
121 gc.stroke_width(1)
121 gc.stroke_width(1)
122 gc.text(left.round + 2, header_heigth + 14, week_f.cweek.to_s)
122 gc.text(left.round + 2, header_heigth + 14, week_f.cweek.to_s)
123 left = left + width
123 left = left + width
124 week_f = week_f+7
124 week_f = week_f+7
125 end
125 end
126 end
126 end
127
127
128 # Days details (week-end in grey)
128 # Days details (week-end in grey)
129 if show_days
129 if show_days
130 left = subject_width
130 left = subject_width
131 height = g_height + header_heigth - 1
131 height = g_height + header_heigth - 1
132 wday = date_from.cwday
132 wday = date_from.cwday
133 (date_to - date_from + 1).to_i.times do
133 (date_to - date_from + 1).to_i.times do
134 width = zoom
134 width = zoom
135 gc.fill(wday == 6 || wday == 7 ? '#eee' : 'white')
135 gc.fill(wday == 6 || wday == 7 ? '#eee' : 'white')
136 gc.stroke('grey')
136 gc.stroke('grey')
137 gc.stroke_width(1)
137 gc.stroke_width(1)
138 gc.rectangle(left, 2*header_heigth, left + width, 2*header_heigth + g_height-1)
138 gc.rectangle(left, 2*header_heigth, left + width, 2*header_heigth + g_height-1)
139 left = left + width
139 left = left + width
140 wday = wday + 1
140 wday = wday + 1
141 wday = 1 if wday > 7
141 wday = 1 if wday > 7
142 end
142 end
143 end
143 end
144
144
145 # border
145 # border
146 gc.fill('transparent')
146 gc.fill('transparent')
147 gc.stroke('grey')
147 gc.stroke('grey')
148 gc.stroke_width(1)
148 gc.stroke_width(1)
149 gc.rectangle(0, 0, subject_width+g_width, headers_heigth)
149 gc.rectangle(0, 0, subject_width+g_width, headers_heigth)
150 gc.stroke('black')
150 gc.stroke('black')
151 gc.rectangle(0, 0, subject_width+g_width, g_height+ headers_heigth-1)
151 gc.rectangle(0, 0, subject_width+g_width, g_height+ headers_heigth-1)
152
152
153 # content
153 # content
154 top = headers_heigth + 20
154 top = headers_heigth + 20
155 gc.stroke('transparent')
155 gc.stroke('transparent')
156 events.each do |i|
156 events.each do |i|
157 if i.is_a?(Issue)
157 if i.is_a?(Issue)
158 i_start_date = (i.start_date >= date_from ? i.start_date : date_from )
158 i_start_date = (i.start_date >= date_from ? i.start_date : date_from )
159 i_end_date = (i.due_date <= date_to ? i.due_date : date_to )
159 i_end_date = (i.due_date <= date_to ? i.due_date : date_to )
160 i_done_date = i.start_date + ((i.due_date - i.start_date+1)*i.done_ratio/100).floor
160 i_done_date = i.start_date + ((i.due_date - i.start_date+1)*i.done_ratio/100).floor
161 i_done_date = (i_done_date <= date_from ? date_from : i_done_date )
161 i_done_date = (i_done_date <= date_from ? date_from : i_done_date )
162 i_done_date = (i_done_date >= date_to ? date_to : i_done_date )
162 i_done_date = (i_done_date >= date_to ? date_to : i_done_date )
163 i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
163 i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
164
164
165 i_left = subject_width + ((i_start_date - date_from)*zoom).floor
165 i_left = subject_width + ((i_start_date - date_from)*zoom).floor
166 i_width = ((i_end_date - i_start_date + 1)*zoom).floor # total width of the issue
166 i_width = ((i_end_date - i_start_date + 1)*zoom).floor # total width of the issue
167 d_width = ((i_done_date - i_start_date)*zoom).floor # done width
167 d_width = ((i_done_date - i_start_date)*zoom).floor # done width
168 l_width = i_late_date ? ((i_late_date - i_start_date+1)*zoom).floor : 0 # delay width
168 l_width = i_late_date ? ((i_late_date - i_start_date+1)*zoom).floor : 0 # delay width
169
169
170 gc.fill('grey')
170 gc.fill('grey')
171 gc.rectangle(i_left, top, i_left + i_width, top - 6)
171 gc.rectangle(i_left, top, i_left + i_width, top - 6)
172 gc.fill('red')
172 gc.fill('red')
173 gc.rectangle(i_left, top, i_left + l_width, top - 6) if l_width > 0
173 gc.rectangle(i_left, top, i_left + l_width, top - 6) if l_width > 0
174 gc.fill('blue')
174 gc.fill('blue')
175 gc.rectangle(i_left, top, i_left + d_width, top - 6) if d_width > 0
175 gc.rectangle(i_left, top, i_left + d_width, top - 6) if d_width > 0
176 gc.fill('black')
176 gc.fill('black')
177 gc.text(i_left + i_width + 5,top + 1, "#{i.status.name} #{i.done_ratio}%")
177 gc.text(i_left + i_width + 5,top + 1, "#{i.status.name} #{i.done_ratio}%")
178 else
178 else
179 i_left = subject_width + ((i.start_date - date_from)*zoom).floor
179 i_left = subject_width + ((i.start_date - date_from)*zoom).floor
180 gc.fill('green')
180 gc.fill('green')
181 gc.rectangle(i_left, top, i_left + 6, top - 6)
181 gc.rectangle(i_left, top, i_left + 6, top - 6)
182 gc.fill('black')
182 gc.fill('black')
183 gc.text(i_left + 11, top + 1, i.name)
183 gc.text(i_left + 11, top + 1, i.name)
184 end
184 end
185 top = top + 20
185 top = top + 20
186 end
186 end
187
187
188 # today red line
188 # today red line
189 if Date.today >= date_from and Date.today <= date_to
189 if Date.today >= date_from and Date.today <= date_to
190 gc.stroke('red')
190 gc.stroke('red')
191 x = (Date.today-date_from+1)*zoom + subject_width
191 x = (Date.today-date_from+1)*zoom + subject_width
192 gc.line(x, headers_heigth, x, headers_heigth + g_height-1)
192 gc.line(x, headers_heigth, x, headers_heigth + g_height-1)
193 end
193 end
194
194
195 gc.draw(imgl)
195 gc.draw(imgl)
196 imgl
196 imgl
197 end if Object.const_defined?(:Magick)
197 end if Object.const_defined?(:Magick)
198 end
198 end
General Comments 0
You need to be logged in to leave comments. Login now