##// END OF EJS Templates
Display project names for versions too on PDF (#5904)....
Jean-Philippe Lang -
r3770:bdad35a73614
parent child
Show More
@@ -1,496 +1,497
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2009 Jean-Philippe Lang
4 # Copyright (C) 2006-2009 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require 'iconv'
20 require 'iconv'
21 require 'rfpdf/fpdf'
21 require 'rfpdf/fpdf'
22 require 'rfpdf/chinese'
22 require 'rfpdf/chinese'
23
23
24 module Redmine
24 module Redmine
25 module Export
25 module Export
26 module PDF
26 module PDF
27 include ActionView::Helpers::TextHelper
27 include ActionView::Helpers::TextHelper
28 include ActionView::Helpers::NumberHelper
28 include ActionView::Helpers::NumberHelper
29
29
30 class IFPDF < FPDF
30 class IFPDF < FPDF
31 include Redmine::I18n
31 include Redmine::I18n
32 attr_accessor :footer_date
32 attr_accessor :footer_date
33
33
34 def initialize(lang)
34 def initialize(lang)
35 super()
35 super()
36 set_language_if_valid lang
36 set_language_if_valid lang
37 case current_language.to_s.downcase
37 case current_language.to_s.downcase
38 when 'ko'
38 when 'ko'
39 extend(PDF_Korean)
39 extend(PDF_Korean)
40 AddUHCFont()
40 AddUHCFont()
41 @font_for_content = 'UHC'
41 @font_for_content = 'UHC'
42 @font_for_footer = 'UHC'
42 @font_for_footer = 'UHC'
43 when 'ja'
43 when 'ja'
44 extend(PDF_Japanese)
44 extend(PDF_Japanese)
45 AddSJISFont()
45 AddSJISFont()
46 @font_for_content = 'SJIS'
46 @font_for_content = 'SJIS'
47 @font_for_footer = 'SJIS'
47 @font_for_footer = 'SJIS'
48 when 'zh'
48 when 'zh'
49 extend(PDF_Chinese)
49 extend(PDF_Chinese)
50 AddGBFont()
50 AddGBFont()
51 @font_for_content = 'GB'
51 @font_for_content = 'GB'
52 @font_for_footer = 'GB'
52 @font_for_footer = 'GB'
53 when 'zh-tw'
53 when 'zh-tw'
54 extend(PDF_Chinese)
54 extend(PDF_Chinese)
55 AddBig5Font()
55 AddBig5Font()
56 @font_for_content = 'Big5'
56 @font_for_content = 'Big5'
57 @font_for_footer = 'Big5'
57 @font_for_footer = 'Big5'
58 else
58 else
59 @font_for_content = 'Arial'
59 @font_for_content = 'Arial'
60 @font_for_footer = 'Helvetica'
60 @font_for_footer = 'Helvetica'
61 end
61 end
62 SetCreator(Redmine::Info.app_name)
62 SetCreator(Redmine::Info.app_name)
63 SetFont(@font_for_content)
63 SetFont(@font_for_content)
64 end
64 end
65
65
66 def SetFontStyle(style, size)
66 def SetFontStyle(style, size)
67 SetFont(@font_for_content, style, size)
67 SetFont(@font_for_content, style, size)
68 end
68 end
69
69
70 def SetTitle(txt)
70 def SetTitle(txt)
71 txt = begin
71 txt = begin
72 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
72 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
73 hextxt = "<FEFF" # FEFF is BOM
73 hextxt = "<FEFF" # FEFF is BOM
74 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
74 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
75 hextxt << ">"
75 hextxt << ">"
76 rescue
76 rescue
77 txt
77 txt
78 end || ''
78 end || ''
79 super(txt)
79 super(txt)
80 end
80 end
81
81
82 def textstring(s)
82 def textstring(s)
83 # Format a text string
83 # Format a text string
84 if s =~ /^</ # This means the string is hex-dumped.
84 if s =~ /^</ # This means the string is hex-dumped.
85 return s
85 return s
86 else
86 else
87 return '('+escape(s)+')'
87 return '('+escape(s)+')'
88 end
88 end
89 end
89 end
90
90
91 def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
91 def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
92 @ic ||= Iconv.new(l(:general_pdf_encoding), 'UTF-8')
92 @ic ||= Iconv.new(l(:general_pdf_encoding), 'UTF-8')
93 # these quotation marks are not correctly rendered in the pdf
93 # these quotation marks are not correctly rendered in the pdf
94 txt = txt.gsub(/[Ò€œÒ€�]/, '"') if txt
94 txt = txt.gsub(/[Ò€œÒ€�]/, '"') if txt
95 txt = begin
95 txt = begin
96 # 0x5c char handling
96 # 0x5c char handling
97 txtar = txt.split('\\')
97 txtar = txt.split('\\')
98 txtar << '' if txt[-1] == ?\\
98 txtar << '' if txt[-1] == ?\\
99 txtar.collect {|x| @ic.iconv(x)}.join('\\').gsub(/\\/, "\\\\\\\\")
99 txtar.collect {|x| @ic.iconv(x)}.join('\\').gsub(/\\/, "\\\\\\\\")
100 rescue
100 rescue
101 txt
101 txt
102 end || ''
102 end || ''
103 super w,h,txt,border,ln,align,fill,link
103 super w,h,txt,border,ln,align,fill,link
104 end
104 end
105
105
106 def Footer
106 def Footer
107 SetFont(@font_for_footer, 'I', 8)
107 SetFont(@font_for_footer, 'I', 8)
108 SetY(-15)
108 SetY(-15)
109 SetX(15)
109 SetX(15)
110 Cell(0, 5, @footer_date, 0, 0, 'L')
110 Cell(0, 5, @footer_date, 0, 0, 'L')
111 SetY(-15)
111 SetY(-15)
112 SetX(-30)
112 SetX(-30)
113 Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
113 Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
114 end
114 end
115 end
115 end
116
116
117 # Returns a PDF string of a list of issues
117 # Returns a PDF string of a list of issues
118 def issues_to_pdf(issues, project, query)
118 def issues_to_pdf(issues, project, query)
119 pdf = IFPDF.new(current_language)
119 pdf = IFPDF.new(current_language)
120 title = query.new_record? ? l(:label_issue_plural) : query.name
120 title = query.new_record? ? l(:label_issue_plural) : query.name
121 title = "#{project} - #{title}" if project
121 title = "#{project} - #{title}" if project
122 pdf.SetTitle(title)
122 pdf.SetTitle(title)
123 pdf.AliasNbPages
123 pdf.AliasNbPages
124 pdf.footer_date = format_date(Date.today)
124 pdf.footer_date = format_date(Date.today)
125 pdf.AddPage("L")
125 pdf.AddPage("L")
126
126
127 row_height = 6
127 row_height = 6
128 col_width = []
128 col_width = []
129 unless query.columns.empty?
129 unless query.columns.empty?
130 col_width = query.columns.collect {|column| column.name == :subject ? 4.0 : 1.0 }
130 col_width = query.columns.collect {|column| column.name == :subject ? 4.0 : 1.0 }
131 ratio = 262.0 / col_width.inject(0) {|s,w| s += w}
131 ratio = 262.0 / col_width.inject(0) {|s,w| s += w}
132 col_width = col_width.collect {|w| w * ratio}
132 col_width = col_width.collect {|w| w * ratio}
133 end
133 end
134
134
135 # title
135 # title
136 pdf.SetFontStyle('B',11)
136 pdf.SetFontStyle('B',11)
137 pdf.Cell(190,10, title)
137 pdf.Cell(190,10, title)
138 pdf.Ln
138 pdf.Ln
139
139
140 # headers
140 # headers
141 pdf.SetFontStyle('B',8)
141 pdf.SetFontStyle('B',8)
142 pdf.SetFillColor(230, 230, 230)
142 pdf.SetFillColor(230, 230, 230)
143 pdf.Cell(15, row_height, "#", 1, 0, 'L', 1)
143 pdf.Cell(15, row_height, "#", 1, 0, 'L', 1)
144 query.columns.each_with_index do |column, i|
144 query.columns.each_with_index do |column, i|
145 pdf.Cell(col_width[i], row_height, column.caption, 1, 0, 'L', 1)
145 pdf.Cell(col_width[i], row_height, column.caption, 1, 0, 'L', 1)
146 end
146 end
147 pdf.Ln
147 pdf.Ln
148
148
149 # rows
149 # rows
150 pdf.SetFontStyle('',8)
150 pdf.SetFontStyle('',8)
151 pdf.SetFillColor(255, 255, 255)
151 pdf.SetFillColor(255, 255, 255)
152 previous_group = false
152 previous_group = false
153 issues.each do |issue|
153 issues.each do |issue|
154 if query.grouped? && (group = query.group_by_column.value(issue)) != previous_group
154 if query.grouped? && (group = query.group_by_column.value(issue)) != previous_group
155 pdf.SetFontStyle('B',9)
155 pdf.SetFontStyle('B',9)
156 pdf.Cell(277, row_height,
156 pdf.Cell(277, row_height,
157 (group.blank? ? 'None' : group.to_s) + " (#{@issue_count_by_group[group]})",
157 (group.blank? ? 'None' : group.to_s) + " (#{@issue_count_by_group[group]})",
158 1, 1, 'L')
158 1, 1, 'L')
159 pdf.SetFontStyle('',8)
159 pdf.SetFontStyle('',8)
160 previous_group = group
160 previous_group = group
161 end
161 end
162 pdf.Cell(15, row_height, issue.id.to_s, 1, 0, 'L', 1)
162 pdf.Cell(15, row_height, issue.id.to_s, 1, 0, 'L', 1)
163 query.columns.each_with_index do |column, i|
163 query.columns.each_with_index do |column, i|
164 s = if column.is_a?(QueryCustomFieldColumn)
164 s = if column.is_a?(QueryCustomFieldColumn)
165 cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
165 cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
166 show_value(cv)
166 show_value(cv)
167 else
167 else
168 value = issue.send(column.name)
168 value = issue.send(column.name)
169 if value.is_a?(Date)
169 if value.is_a?(Date)
170 format_date(value)
170 format_date(value)
171 elsif value.is_a?(Time)
171 elsif value.is_a?(Time)
172 format_time(value)
172 format_time(value)
173 else
173 else
174 value
174 value
175 end
175 end
176 end
176 end
177 pdf.Cell(col_width[i], row_height, s.to_s, 1, 0, 'L', 1)
177 pdf.Cell(col_width[i], row_height, s.to_s, 1, 0, 'L', 1)
178 end
178 end
179 pdf.Ln
179 pdf.Ln
180 end
180 end
181 if issues.size == Setting.issues_export_limit.to_i
181 if issues.size == Setting.issues_export_limit.to_i
182 pdf.SetFontStyle('B',10)
182 pdf.SetFontStyle('B',10)
183 pdf.Cell(0, row_height, '...')
183 pdf.Cell(0, row_height, '...')
184 end
184 end
185 pdf.Output
185 pdf.Output
186 end
186 end
187
187
188 # Returns a PDF string of a single issue
188 # Returns a PDF string of a single issue
189 def issue_to_pdf(issue)
189 def issue_to_pdf(issue)
190 pdf = IFPDF.new(current_language)
190 pdf = IFPDF.new(current_language)
191 pdf.SetTitle("#{issue.project} - ##{issue.tracker} #{issue.id}")
191 pdf.SetTitle("#{issue.project} - ##{issue.tracker} #{issue.id}")
192 pdf.AliasNbPages
192 pdf.AliasNbPages
193 pdf.footer_date = format_date(Date.today)
193 pdf.footer_date = format_date(Date.today)
194 pdf.AddPage
194 pdf.AddPage
195
195
196 pdf.SetFontStyle('B',11)
196 pdf.SetFontStyle('B',11)
197 pdf.Cell(190,10, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
197 pdf.Cell(190,10, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
198 pdf.Ln
198 pdf.Ln
199
199
200 y0 = pdf.GetY
200 y0 = pdf.GetY
201
201
202 pdf.SetFontStyle('B',9)
202 pdf.SetFontStyle('B',9)
203 pdf.Cell(35,5, l(:field_status) + ":","LT")
203 pdf.Cell(35,5, l(:field_status) + ":","LT")
204 pdf.SetFontStyle('',9)
204 pdf.SetFontStyle('',9)
205 pdf.Cell(60,5, issue.status.to_s,"RT")
205 pdf.Cell(60,5, issue.status.to_s,"RT")
206 pdf.SetFontStyle('B',9)
206 pdf.SetFontStyle('B',9)
207 pdf.Cell(35,5, l(:field_priority) + ":","LT")
207 pdf.Cell(35,5, l(:field_priority) + ":","LT")
208 pdf.SetFontStyle('',9)
208 pdf.SetFontStyle('',9)
209 pdf.Cell(60,5, issue.priority.to_s,"RT")
209 pdf.Cell(60,5, issue.priority.to_s,"RT")
210 pdf.Ln
210 pdf.Ln
211
211
212 pdf.SetFontStyle('B',9)
212 pdf.SetFontStyle('B',9)
213 pdf.Cell(35,5, l(:field_author) + ":","L")
213 pdf.Cell(35,5, l(:field_author) + ":","L")
214 pdf.SetFontStyle('',9)
214 pdf.SetFontStyle('',9)
215 pdf.Cell(60,5, issue.author.to_s,"R")
215 pdf.Cell(60,5, issue.author.to_s,"R")
216 pdf.SetFontStyle('B',9)
216 pdf.SetFontStyle('B',9)
217 pdf.Cell(35,5, l(:field_category) + ":","L")
217 pdf.Cell(35,5, l(:field_category) + ":","L")
218 pdf.SetFontStyle('',9)
218 pdf.SetFontStyle('',9)
219 pdf.Cell(60,5, issue.category.to_s,"R")
219 pdf.Cell(60,5, issue.category.to_s,"R")
220 pdf.Ln
220 pdf.Ln
221
221
222 pdf.SetFontStyle('B',9)
222 pdf.SetFontStyle('B',9)
223 pdf.Cell(35,5, l(:field_created_on) + ":","L")
223 pdf.Cell(35,5, l(:field_created_on) + ":","L")
224 pdf.SetFontStyle('',9)
224 pdf.SetFontStyle('',9)
225 pdf.Cell(60,5, format_date(issue.created_on),"R")
225 pdf.Cell(60,5, format_date(issue.created_on),"R")
226 pdf.SetFontStyle('B',9)
226 pdf.SetFontStyle('B',9)
227 pdf.Cell(35,5, l(:field_assigned_to) + ":","L")
227 pdf.Cell(35,5, l(:field_assigned_to) + ":","L")
228 pdf.SetFontStyle('',9)
228 pdf.SetFontStyle('',9)
229 pdf.Cell(60,5, issue.assigned_to.to_s,"R")
229 pdf.Cell(60,5, issue.assigned_to.to_s,"R")
230 pdf.Ln
230 pdf.Ln
231
231
232 pdf.SetFontStyle('B',9)
232 pdf.SetFontStyle('B',9)
233 pdf.Cell(35,5, l(:field_updated_on) + ":","LB")
233 pdf.Cell(35,5, l(:field_updated_on) + ":","LB")
234 pdf.SetFontStyle('',9)
234 pdf.SetFontStyle('',9)
235 pdf.Cell(60,5, format_date(issue.updated_on),"RB")
235 pdf.Cell(60,5, format_date(issue.updated_on),"RB")
236 pdf.SetFontStyle('B',9)
236 pdf.SetFontStyle('B',9)
237 pdf.Cell(35,5, l(:field_due_date) + ":","LB")
237 pdf.Cell(35,5, l(:field_due_date) + ":","LB")
238 pdf.SetFontStyle('',9)
238 pdf.SetFontStyle('',9)
239 pdf.Cell(60,5, format_date(issue.due_date),"RB")
239 pdf.Cell(60,5, format_date(issue.due_date),"RB")
240 pdf.Ln
240 pdf.Ln
241
241
242 for custom_value in issue.custom_field_values
242 for custom_value in issue.custom_field_values
243 pdf.SetFontStyle('B',9)
243 pdf.SetFontStyle('B',9)
244 pdf.Cell(35,5, custom_value.custom_field.name + ":","L")
244 pdf.Cell(35,5, custom_value.custom_field.name + ":","L")
245 pdf.SetFontStyle('',9)
245 pdf.SetFontStyle('',9)
246 pdf.MultiCell(155,5, (show_value custom_value),"R")
246 pdf.MultiCell(155,5, (show_value custom_value),"R")
247 end
247 end
248
248
249 pdf.SetFontStyle('B',9)
249 pdf.SetFontStyle('B',9)
250 pdf.Cell(35,5, l(:field_subject) + ":","LTB")
250 pdf.Cell(35,5, l(:field_subject) + ":","LTB")
251 pdf.SetFontStyle('',9)
251 pdf.SetFontStyle('',9)
252 pdf.Cell(155,5, issue.subject,"RTB")
252 pdf.Cell(155,5, issue.subject,"RTB")
253 pdf.Ln
253 pdf.Ln
254
254
255 pdf.SetFontStyle('B',9)
255 pdf.SetFontStyle('B',9)
256 pdf.Cell(35,5, l(:field_description) + ":")
256 pdf.Cell(35,5, l(:field_description) + ":")
257 pdf.SetFontStyle('',9)
257 pdf.SetFontStyle('',9)
258 pdf.MultiCell(155,5, @issue.description,"BR")
258 pdf.MultiCell(155,5, @issue.description,"BR")
259
259
260 pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
260 pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
261 pdf.Line(pdf.GetX, pdf.GetY, 170, pdf.GetY)
261 pdf.Line(pdf.GetX, pdf.GetY, 170, pdf.GetY)
262 pdf.Ln
262 pdf.Ln
263
263
264 if issue.changesets.any? && User.current.allowed_to?(:view_changesets, issue.project)
264 if issue.changesets.any? && User.current.allowed_to?(:view_changesets, issue.project)
265 pdf.SetFontStyle('B',9)
265 pdf.SetFontStyle('B',9)
266 pdf.Cell(190,5, l(:label_associated_revisions), "B")
266 pdf.Cell(190,5, l(:label_associated_revisions), "B")
267 pdf.Ln
267 pdf.Ln
268 for changeset in issue.changesets
268 for changeset in issue.changesets
269 pdf.SetFontStyle('B',8)
269 pdf.SetFontStyle('B',8)
270 pdf.Cell(190,5, format_time(changeset.committed_on) + " - " + changeset.author.to_s)
270 pdf.Cell(190,5, format_time(changeset.committed_on) + " - " + changeset.author.to_s)
271 pdf.Ln
271 pdf.Ln
272 unless changeset.comments.blank?
272 unless changeset.comments.blank?
273 pdf.SetFontStyle('',8)
273 pdf.SetFontStyle('',8)
274 pdf.MultiCell(190,5, changeset.comments)
274 pdf.MultiCell(190,5, changeset.comments)
275 end
275 end
276 pdf.Ln
276 pdf.Ln
277 end
277 end
278 end
278 end
279
279
280 pdf.SetFontStyle('B',9)
280 pdf.SetFontStyle('B',9)
281 pdf.Cell(190,5, l(:label_history), "B")
281 pdf.Cell(190,5, l(:label_history), "B")
282 pdf.Ln
282 pdf.Ln
283 for journal in issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
283 for journal in issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
284 pdf.SetFontStyle('B',8)
284 pdf.SetFontStyle('B',8)
285 pdf.Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name)
285 pdf.Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name)
286 pdf.Ln
286 pdf.Ln
287 pdf.SetFontStyle('I',8)
287 pdf.SetFontStyle('I',8)
288 for detail in journal.details
288 for detail in journal.details
289 pdf.Cell(190,5, "- " + show_detail(detail, true))
289 pdf.Cell(190,5, "- " + show_detail(detail, true))
290 pdf.Ln
290 pdf.Ln
291 end
291 end
292 if journal.notes?
292 if journal.notes?
293 pdf.SetFontStyle('',8)
293 pdf.SetFontStyle('',8)
294 pdf.MultiCell(190,5, journal.notes)
294 pdf.MultiCell(190,5, journal.notes)
295 end
295 end
296 pdf.Ln
296 pdf.Ln
297 end
297 end
298
298
299 if issue.attachments.any?
299 if issue.attachments.any?
300 pdf.SetFontStyle('B',9)
300 pdf.SetFontStyle('B',9)
301 pdf.Cell(190,5, l(:label_attachment_plural), "B")
301 pdf.Cell(190,5, l(:label_attachment_plural), "B")
302 pdf.Ln
302 pdf.Ln
303 for attachment in issue.attachments
303 for attachment in issue.attachments
304 pdf.SetFontStyle('',8)
304 pdf.SetFontStyle('',8)
305 pdf.Cell(80,5, attachment.filename)
305 pdf.Cell(80,5, attachment.filename)
306 pdf.Cell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
306 pdf.Cell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
307 pdf.Cell(25,5, format_date(attachment.created_on),0,0,"R")
307 pdf.Cell(25,5, format_date(attachment.created_on),0,0,"R")
308 pdf.Cell(65,5, attachment.author.name,0,0,"R")
308 pdf.Cell(65,5, attachment.author.name,0,0,"R")
309 pdf.Ln
309 pdf.Ln
310 end
310 end
311 end
311 end
312 pdf.Output
312 pdf.Output
313 end
313 end
314
314
315 # Returns a PDF string of a gantt chart
315 # Returns a PDF string of a gantt chart
316 def gantt_to_pdf(gantt, project)
316 def gantt_to_pdf(gantt, project)
317 pdf = IFPDF.new(current_language)
317 pdf = IFPDF.new(current_language)
318 pdf.SetTitle("#{l(:label_gantt)} #{project}")
318 pdf.SetTitle("#{l(:label_gantt)} #{project}")
319 pdf.AliasNbPages
319 pdf.AliasNbPages
320 pdf.footer_date = format_date(Date.today)
320 pdf.footer_date = format_date(Date.today)
321 pdf.AddPage("L")
321 pdf.AddPage("L")
322 pdf.SetFontStyle('B',12)
322 pdf.SetFontStyle('B',12)
323 pdf.SetX(15)
323 pdf.SetX(15)
324 pdf.Cell(70, 20, project.to_s)
324 pdf.Cell(70, 20, project.to_s)
325 pdf.Ln
325 pdf.Ln
326 pdf.SetFontStyle('B',9)
326 pdf.SetFontStyle('B',9)
327
327
328 subject_width = 100
328 subject_width = 100
329 header_heigth = 5
329 header_heigth = 5
330
330
331 headers_heigth = header_heigth
331 headers_heigth = header_heigth
332 show_weeks = false
332 show_weeks = false
333 show_days = false
333 show_days = false
334
334
335 if gantt.months < 7
335 if gantt.months < 7
336 show_weeks = true
336 show_weeks = true
337 headers_heigth = 2*header_heigth
337 headers_heigth = 2*header_heigth
338 if gantt.months < 3
338 if gantt.months < 3
339 show_days = true
339 show_days = true
340 headers_heigth = 3*header_heigth
340 headers_heigth = 3*header_heigth
341 end
341 end
342 end
342 end
343
343
344 g_width = 280 - subject_width
344 g_width = 280 - subject_width
345 zoom = (g_width) / (gantt.date_to - gantt.date_from + 1)
345 zoom = (g_width) / (gantt.date_to - gantt.date_from + 1)
346 g_height = 120
346 g_height = 120
347 t_height = g_height + headers_heigth
347 t_height = g_height + headers_heigth
348
348
349 y_start = pdf.GetY
349 y_start = pdf.GetY
350
350
351 # Months headers
351 # Months headers
352 month_f = gantt.date_from
352 month_f = gantt.date_from
353 left = subject_width
353 left = subject_width
354 height = header_heigth
354 height = header_heigth
355 gantt.months.times do
355 gantt.months.times do
356 width = ((month_f >> 1) - month_f) * zoom
356 width = ((month_f >> 1) - month_f) * zoom
357 pdf.SetY(y_start)
357 pdf.SetY(y_start)
358 pdf.SetX(left)
358 pdf.SetX(left)
359 pdf.Cell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C")
359 pdf.Cell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C")
360 left = left + width
360 left = left + width
361 month_f = month_f >> 1
361 month_f = month_f >> 1
362 end
362 end
363
363
364 # Weeks headers
364 # Weeks headers
365 if show_weeks
365 if show_weeks
366 left = subject_width
366 left = subject_width
367 height = header_heigth
367 height = header_heigth
368 if gantt.date_from.cwday == 1
368 if gantt.date_from.cwday == 1
369 # gantt.date_from is monday
369 # gantt.date_from is monday
370 week_f = gantt.date_from
370 week_f = gantt.date_from
371 else
371 else
372 # find next monday after gantt.date_from
372 # find next monday after gantt.date_from
373 week_f = gantt.date_from + (7 - gantt.date_from.cwday + 1)
373 week_f = gantt.date_from + (7 - gantt.date_from.cwday + 1)
374 width = (7 - gantt.date_from.cwday + 1) * zoom-1
374 width = (7 - gantt.date_from.cwday + 1) * zoom-1
375 pdf.SetY(y_start + header_heigth)
375 pdf.SetY(y_start + header_heigth)
376 pdf.SetX(left)
376 pdf.SetX(left)
377 pdf.Cell(width + 1, height, "", "LTR")
377 pdf.Cell(width + 1, height, "", "LTR")
378 left = left + width+1
378 left = left + width+1
379 end
379 end
380 while week_f <= gantt.date_to
380 while week_f <= gantt.date_to
381 width = (week_f + 6 <= gantt.date_to) ? 7 * zoom : (gantt.date_to - week_f + 1) * zoom
381 width = (week_f + 6 <= gantt.date_to) ? 7 * zoom : (gantt.date_to - week_f + 1) * zoom
382 pdf.SetY(y_start + header_heigth)
382 pdf.SetY(y_start + header_heigth)
383 pdf.SetX(left)
383 pdf.SetX(left)
384 pdf.Cell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
384 pdf.Cell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
385 left = left + width
385 left = left + width
386 week_f = week_f+7
386 week_f = week_f+7
387 end
387 end
388 end
388 end
389
389
390 # Days headers
390 # Days headers
391 if show_days
391 if show_days
392 left = subject_width
392 left = subject_width
393 height = header_heigth
393 height = header_heigth
394 wday = gantt.date_from.cwday
394 wday = gantt.date_from.cwday
395 pdf.SetFontStyle('B',7)
395 pdf.SetFontStyle('B',7)
396 (gantt.date_to - gantt.date_from + 1).to_i.times do
396 (gantt.date_to - gantt.date_from + 1).to_i.times do
397 width = zoom
397 width = zoom
398 pdf.SetY(y_start + 2 * header_heigth)
398 pdf.SetY(y_start + 2 * header_heigth)
399 pdf.SetX(left)
399 pdf.SetX(left)
400 pdf.Cell(width, height, day_name(wday).first, "LTR", 0, "C")
400 pdf.Cell(width, height, day_name(wday).first, "LTR", 0, "C")
401 left = left + width
401 left = left + width
402 wday = wday + 1
402 wday = wday + 1
403 wday = 1 if wday > 7
403 wday = 1 if wday > 7
404 end
404 end
405 end
405 end
406
406
407 pdf.SetY(y_start)
407 pdf.SetY(y_start)
408 pdf.SetX(15)
408 pdf.SetX(15)
409 pdf.Cell(subject_width+g_width-15, headers_heigth, "", 1)
409 pdf.Cell(subject_width+g_width-15, headers_heigth, "", 1)
410
410
411 # Tasks
411 # Tasks
412 top = headers_heigth + y_start
412 top = headers_heigth + y_start
413 pdf.SetFontStyle('B',7)
413 pdf.SetFontStyle('B',7)
414 gantt.events.each do |i|
414 gantt.events.each do |i|
415 pdf.SetY(top)
415 pdf.SetY(top)
416 pdf.SetX(15)
416 pdf.SetX(15)
417
417
418 text = ""
418 if i.is_a? Issue
419 if i.is_a? Issue
419 text = "#{i.tracker} #{i.id}: #{i.subject}"
420 text = "#{i.tracker} #{i.id}: #{i.subject}"
420 text = "#{i.project} - #{text}" unless project && project == i.project
421 pdf.Cell(subject_width-15, 5, text, "LR")
422 else
421 else
423 pdf.Cell(subject_width-15, 5, "#{l(:label_version)}: #{i.name}", "LR")
422 text = i.name
424 end
423 end
424 text = "#{i.project} - #{text}" unless project && project == i.project
425 pdf.Cell(subject_width-15, 5, text, "LR")
425
426
426 pdf.SetY(top + 0.2)
427 pdf.SetY(top + 0.2)
427 pdf.SetX(subject_width)
428 pdf.SetX(subject_width)
428 pdf.SetFillColor(255, 255, 255)
429 pdf.SetFillColor(255, 255, 255)
429 pdf.Cell(g_width, 4.6, "", "LR", 0, "", 1)
430 pdf.Cell(g_width, 4.6, "", "LR", 0, "", 1)
430 pdf.SetY(top+1.5)
431 pdf.SetY(top+1.5)
431
432
432 if i.is_a? Issue
433 if i.is_a? Issue
433 i_start_date = (i.start_date >= gantt.date_from ? i.start_date : gantt.date_from )
434 i_start_date = (i.start_date >= gantt.date_from ? i.start_date : gantt.date_from )
434 i_end_date = (i.due_before <= gantt.date_to ? i.due_before : gantt.date_to )
435 i_end_date = (i.due_before <= gantt.date_to ? i.due_before : gantt.date_to )
435
436
436 i_done_date = i.start_date + ((i.due_before - i.start_date+1)*i.done_ratio/100).floor
437 i_done_date = i.start_date + ((i.due_before - i.start_date+1)*i.done_ratio/100).floor
437 i_done_date = (i_done_date <= gantt.date_from ? gantt.date_from : i_done_date )
438 i_done_date = (i_done_date <= gantt.date_from ? gantt.date_from : i_done_date )
438 i_done_date = (i_done_date >= gantt.date_to ? gantt.date_to : i_done_date )
439 i_done_date = (i_done_date >= gantt.date_to ? gantt.date_to : i_done_date )
439
440
440 i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
441 i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
441
442
442 i_left = ((i_start_date - gantt.date_from)*zoom)
443 i_left = ((i_start_date - gantt.date_from)*zoom)
443 i_width = ((i_end_date - i_start_date + 1)*zoom)
444 i_width = ((i_end_date - i_start_date + 1)*zoom)
444 d_width = ((i_done_date - i_start_date)*zoom)
445 d_width = ((i_done_date - i_start_date)*zoom)
445 l_width = ((i_late_date - i_start_date+1)*zoom) if i_late_date
446 l_width = ((i_late_date - i_start_date+1)*zoom) if i_late_date
446 l_width ||= 0
447 l_width ||= 0
447
448
448 pdf.SetX(subject_width + i_left)
449 pdf.SetX(subject_width + i_left)
449 pdf.SetFillColor(200,200,200)
450 pdf.SetFillColor(200,200,200)
450 pdf.Cell(i_width, 2, "", 0, 0, "", 1)
451 pdf.Cell(i_width, 2, "", 0, 0, "", 1)
451
452
452 if l_width > 0
453 if l_width > 0
453 pdf.SetY(top+1.5)
454 pdf.SetY(top+1.5)
454 pdf.SetX(subject_width + i_left)
455 pdf.SetX(subject_width + i_left)
455 pdf.SetFillColor(255,100,100)
456 pdf.SetFillColor(255,100,100)
456 pdf.Cell(l_width, 2, "", 0, 0, "", 1)
457 pdf.Cell(l_width, 2, "", 0, 0, "", 1)
457 end
458 end
458 if d_width > 0
459 if d_width > 0
459 pdf.SetY(top+1.5)
460 pdf.SetY(top+1.5)
460 pdf.SetX(subject_width + i_left)
461 pdf.SetX(subject_width + i_left)
461 pdf.SetFillColor(100,100,255)
462 pdf.SetFillColor(100,100,255)
462 pdf.Cell(d_width, 2, "", 0, 0, "", 1)
463 pdf.Cell(d_width, 2, "", 0, 0, "", 1)
463 end
464 end
464
465
465 pdf.SetY(top+1.5)
466 pdf.SetY(top+1.5)
466 pdf.SetX(subject_width + i_left + i_width)
467 pdf.SetX(subject_width + i_left + i_width)
467 pdf.Cell(30, 2, "#{i.status} #{i.done_ratio}%")
468 pdf.Cell(30, 2, "#{i.status} #{i.done_ratio}%")
468 else
469 else
469 i_left = ((i.start_date - gantt.date_from)*zoom)
470 i_left = ((i.start_date - gantt.date_from)*zoom)
470
471
471 pdf.SetX(subject_width + i_left)
472 pdf.SetX(subject_width + i_left)
472 pdf.SetFillColor(50,200,50)
473 pdf.SetFillColor(50,200,50)
473 pdf.Cell(2, 2, "", 0, 0, "", 1)
474 pdf.Cell(2, 2, "", 0, 0, "", 1)
474
475
475 pdf.SetY(top+1.5)
476 pdf.SetY(top+1.5)
476 pdf.SetX(subject_width + i_left + 3)
477 pdf.SetX(subject_width + i_left + 3)
477 pdf.Cell(30, 2, "#{i.name}")
478 pdf.Cell(30, 2, "#{i.name}")
478 end
479 end
479
480
480 top = top + 5
481 top = top + 5
481 pdf.SetDrawColor(200, 200, 200)
482 pdf.SetDrawColor(200, 200, 200)
482 pdf.Line(15, top, subject_width+g_width, top)
483 pdf.Line(15, top, subject_width+g_width, top)
483 if pdf.GetY() > 180
484 if pdf.GetY() > 180
484 pdf.AddPage("L")
485 pdf.AddPage("L")
485 top = 20
486 top = 20
486 pdf.Line(15, top, subject_width+g_width, top)
487 pdf.Line(15, top, subject_width+g_width, top)
487 end
488 end
488 pdf.SetDrawColor(0, 0, 0)
489 pdf.SetDrawColor(0, 0, 0)
489 end
490 end
490
491
491 pdf.Line(15, top, subject_width+g_width, top)
492 pdf.Line(15, top, subject_width+g_width, top)
492 pdf.Output
493 pdf.Output
493 end
494 end
494 end
495 end
495 end
496 end
496 end
497 end
General Comments 0
You need to be logged in to leave comments. Login now