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