##// END OF EJS Templates
code clean up lib/redmine/export/pdf.rb....
Toshi MARUYAMA -
r5188:3b20bd76a8e5
parent child
Show More
@@ -1,394 +1,400
1 1 # encoding: utf-8
2 2 #
3 3 # Redmine - project management software
4 4 # Copyright (C) 2006-2009 Jean-Philippe Lang
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; either version 2
9 9 # of the License, or (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 20 require 'iconv'
21 21 require 'rfpdf/fpdf'
22 22 require 'fpdf/chinese'
23 23 require 'fpdf/japanese'
24 24 require 'fpdf/korean'
25 25
26 26 module Redmine
27 27 module Export
28 28 module PDF
29 29 include ActionView::Helpers::TextHelper
30 30 include ActionView::Helpers::NumberHelper
31 31
32 32 class ITCPDF < TCPDF
33 33 include Redmine::I18n
34 34 attr_accessor :footer_date
35 35
36 36 def initialize(lang)
37 37 super()
38 38 set_language_if_valid lang
39 39 @font_for_content = 'FreeSans'
40 40 @font_for_footer = 'FreeSans'
41 41 SetCreator(Redmine::Info.app_name)
42 42 SetFont(@font_for_content)
43 43 end
44 44
45 45 def SetFontStyle(style, size)
46 46 SetFont(@font_for_content, style, size)
47 47 end
48 48
49 49 def SetTitle(txt)
50 50 txt = begin
51 51 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
52 52 hextxt = "<FEFF" # FEFF is BOM
53 53 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
54 54 hextxt << ">"
55 55 rescue
56 56 txt
57 57 end || ''
58 58 super(txt)
59 59 end
60 60
61 61 def textstring(s)
62 62 # Format a text string
63 63 if s =~ /^</ # This means the string is hex-dumped.
64 64 return s
65 65 else
66 66 return '('+escape(s)+')'
67 67 end
68 68 end
69 69
70 70 alias RDMCell Cell
71 71 alias RDMMultiCell MultiCell
72 72
73 73 def Footer
74 74 SetFont(@font_for_footer, 'I', 8)
75 75 SetY(-15)
76 76 SetX(15)
77 77 RDMCell(0, 5, @footer_date, 0, 0, 'L')
78 78 SetY(-15)
79 79 SetX(-30)
80 80 RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
81 81 end
82 82 end
83 83
84 84 class IFPDF < FPDF
85 85 include Redmine::I18n
86 86 attr_accessor :footer_date
87 87
88 88 def initialize(lang)
89 89 super()
90 90 set_language_if_valid lang
91 91 case current_language.to_s.downcase
92 92 when 'ko'
93 93 extend(PDF_Korean)
94 94 AddUHCFont()
95 95 @font_for_content = 'UHC'
96 96 @font_for_footer = 'UHC'
97 97 when 'ja'
98 98 extend(PDF_Japanese)
99 99 AddSJISFont()
100 100 @font_for_content = 'SJIS'
101 101 @font_for_footer = 'SJIS'
102 102 when 'zh'
103 103 extend(PDF_Chinese)
104 104 AddGBFont()
105 105 @font_for_content = 'GB'
106 106 @font_for_footer = 'GB'
107 107 when 'zh-tw'
108 108 extend(PDF_Chinese)
109 109 AddBig5Font()
110 110 @font_for_content = 'Big5'
111 111 @font_for_footer = 'Big5'
112 112 else
113 113 @font_for_content = 'Arial'
114 114 @font_for_footer = 'Helvetica'
115 115 end
116 116 SetCreator(Redmine::Info.app_name)
117 117 SetFont(@font_for_content)
118 118 end
119 119
120 120 def SetFontStyle(style, size)
121 121 SetFont(@font_for_content, style, size)
122 122 end
123 123
124 124 def SetTitle(txt)
125 125 txt = begin
126 126 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
127 127 hextxt = "<FEFF" # FEFF is BOM
128 128 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
129 129 hextxt << ">"
130 130 rescue
131 131 txt
132 132 end || ''
133 133 super(txt)
134 134 end
135 135
136 136 def textstring(s)
137 137 # Format a text string
138 138 if s =~ /^</ # This means the string is hex-dumped.
139 139 return s
140 140 else
141 141 return '('+escape(s)+')'
142 142 end
143 143 end
144 144
145 145 def fix_text_encoding(txt)
146 146 @ic ||= Iconv.new(l(:general_pdf_encoding), 'UTF-8')
147 147 txt = begin
148 148 # 0x5c char handling
149 149 txtar = txt.split('\\')
150 150 txtar << '' if txt[-1] == ?\\
151 151 txtar.collect {|x| @ic.iconv(x)}.join('\\').gsub(/\\/, "\\\\\\\\")
152 152 rescue
153 153 txt
154 154 end || ''
155 155 return txt
156 156 end
157 157
158 158 def RDMCell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
159 159 Cell(w,h,fix_text_encoding(txt),border,ln,align,fill,link)
160 160 end
161 161
162 162 def RDMMultiCell(w,h=0,txt='',border=0,align='',fill=0)
163 163 MultiCell(w,h,fix_text_encoding(txt),border,align,fill)
164 164 end
165 165
166 166 def Footer
167 167 SetFont(@font_for_footer, 'I', 8)
168 168 SetY(-15)
169 169 SetX(15)
170 170 RDMCell(0, 5, @footer_date, 0, 0, 'L')
171 171 SetY(-15)
172 172 SetX(-30)
173 173 RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
174 174 end
175 175 alias alias_nb_pages AliasNbPages
176 176 end
177 177
178 178 # Returns a PDF string of a list of issues
179 179 def issues_to_pdf(issues, project, query)
180 180 if ( current_language.to_s.downcase == 'ko' ||
181 181 current_language.to_s.downcase == 'ja' ||
182 182 current_language.to_s.downcase == 'zh' ||
183 183 current_language.to_s.downcase == 'zh-tw' ||
184 184 current_language.to_s.downcase == 'th' )
185 185 pdf = IFPDF.new(current_language)
186 186 else
187 187 pdf = ITCPDF.new(current_language)
188 188 end
189 189 title = query.new_record? ? l(:label_issue_plural) : query.name
190 190 title = "#{project} - #{title}" if project
191 191 pdf.SetTitle(title)
192 192 pdf.alias_nb_pages
193 193 pdf.footer_date = format_date(Date.today)
194 194 pdf.AddPage("L")
195 195
196 196 row_height = 6
197 197 col_width = []
198 198 unless query.columns.empty?
199 199 col_width = query.columns.collect {|column| column.name == :subject ? 4.0 : 1.0 }
200 200 ratio = 262.0 / col_width.inject(0) {|s,w| s += w}
201 201 col_width = col_width.collect {|w| w * ratio}
202 202 end
203 203
204 204 # title
205 205 pdf.SetFontStyle('B',11)
206 206 pdf.RDMCell(190,10, title)
207 207 pdf.Ln
208 208
209 209 # headers
210 210 pdf.SetFontStyle('B',8)
211 211 pdf.SetFillColor(230, 230, 230)
212 212 pdf.RDMCell(15, row_height, "#", 1, 0, 'L', 1)
213 213 query.columns.each_with_index do |column, i|
214 214 pdf.RDMCell(col_width[i], row_height, column.caption, 1, 0, 'L', 1)
215 215 end
216 216 pdf.Ln
217 217
218 218 # rows
219 219 pdf.SetFontStyle('',8)
220 220 pdf.SetFillColor(255, 255, 255)
221 221 previous_group = false
222 222 issues.each do |issue|
223 if query.grouped? && (group = query.group_by_column.value(issue)) != previous_group
223 if query.grouped? &&
224 (group = query.group_by_column.value(issue)) != previous_group
224 225 pdf.SetFontStyle('B',9)
225 226 pdf.RDMCell(277, row_height,
226 227 (group.blank? ? 'None' : group.to_s) + " (#{query.issue_count_by_group[group]})",
227 228 1, 1, 'L')
228 229 pdf.SetFontStyle('',8)
229 230 previous_group = group
230 231 end
231 232 pdf.RDMCell(15, row_height, issue.id.to_s, 1, 0, 'L', 1)
232 233 query.columns.each_with_index do |column, i|
233 234 s = if column.is_a?(QueryCustomFieldColumn)
234 235 cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
235 236 show_value(cv)
236 237 else
237 238 value = issue.send(column.name)
238 239 if value.is_a?(Date)
239 240 format_date(value)
240 241 elsif value.is_a?(Time)
241 242 format_time(value)
242 243 else
243 244 value
244 245 end
245 246 end
246 247 pdf.RDMCell(col_width[i], row_height, s.to_s, 1, 0, 'L', 1)
247 248 end
248 249 pdf.Ln
249 250 end
250 251 if issues.size == Setting.issues_export_limit.to_i
251 252 pdf.SetFontStyle('B',10)
252 253 pdf.RDMCell(0, row_height, '...')
253 254 end
254 255 pdf.Output
255 256 end
256 257
257 258 # Returns a PDF string of a single issue
258 259 def issue_to_pdf(issue)
259 260 if ( current_language.to_s.downcase == 'ko' ||
260 261 current_language.to_s.downcase == 'ja' ||
261 262 current_language.to_s.downcase == 'zh' ||
262 263 current_language.to_s.downcase == 'zh-tw' ||
263 264 current_language.to_s.downcase == 'th' )
264 265 pdf = IFPDF.new(current_language)
265 266 else
266 267 pdf = ITCPDF.new(current_language)
267 268 end
268 269 pdf.SetTitle("#{issue.project} - ##{issue.tracker} #{issue.id}")
269 270 pdf.alias_nb_pages
270 271 pdf.footer_date = format_date(Date.today)
271 272 pdf.AddPage
272 273
273 274 pdf.SetFontStyle('B',11)
274 pdf.RDMCell(190,10, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
275 pdf.RDMCell(190,10,
276 "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
275 277 pdf.Ln
276 278
277 279 y0 = pdf.GetY
278 280
279 281 pdf.SetFontStyle('B',9)
280 282 pdf.RDMCell(35,5, l(:field_status) + ":","LT")
281 283 pdf.SetFontStyle('',9)
282 284 pdf.RDMCell(60,5, issue.status.to_s,"RT")
283 285 pdf.SetFontStyle('B',9)
284 286 pdf.RDMCell(35,5, l(:field_priority) + ":","LT")
285 287 pdf.SetFontStyle('',9)
286 288 pdf.RDMCell(60,5, issue.priority.to_s,"RT")
287 289 pdf.Ln
288 290
289 291 pdf.SetFontStyle('B',9)
290 292 pdf.RDMCell(35,5, l(:field_author) + ":","L")
291 293 pdf.SetFontStyle('',9)
292 294 pdf.RDMCell(60,5, issue.author.to_s,"R")
293 295 pdf.SetFontStyle('B',9)
294 296 pdf.RDMCell(35,5, l(:field_category) + ":","L")
295 297 pdf.SetFontStyle('',9)
296 298 pdf.RDMCell(60,5, issue.category.to_s,"R")
297 299 pdf.Ln
298 300
299 301 pdf.SetFontStyle('B',9)
300 302 pdf.RDMCell(35,5, l(:field_created_on) + ":","L")
301 303 pdf.SetFontStyle('',9)
302 304 pdf.RDMCell(60,5, format_date(issue.created_on),"R")
303 305 pdf.SetFontStyle('B',9)
304 306 pdf.RDMCell(35,5, l(:field_assigned_to) + ":","L")
305 307 pdf.SetFontStyle('',9)
306 308 pdf.RDMCell(60,5, issue.assigned_to.to_s,"R")
307 309 pdf.Ln
308 310
309 311 pdf.SetFontStyle('B',9)
310 312 pdf.RDMCell(35,5, l(:field_updated_on) + ":","LB")
311 313 pdf.SetFontStyle('',9)
312 314 pdf.RDMCell(60,5, format_date(issue.updated_on),"RB")
313 315 pdf.SetFontStyle('B',9)
314 316 pdf.RDMCell(35,5, l(:field_due_date) + ":","LB")
315 317 pdf.SetFontStyle('',9)
316 318 pdf.RDMCell(60,5, format_date(issue.due_date),"RB")
317 319 pdf.Ln
318 320
319 321 for custom_value in issue.custom_field_values
320 322 pdf.SetFontStyle('B',9)
321 323 pdf.RDMCell(35,5, custom_value.custom_field.name + ":","L")
322 324 pdf.SetFontStyle('',9)
323 325 pdf.RDMMultiCell(155,5, (show_value custom_value),"R")
324 326 end
325 327
326 328 pdf.SetFontStyle('B',9)
327 329 pdf.RDMCell(35,5, l(:field_subject) + ":","LTB")
328 330 pdf.SetFontStyle('',9)
329 331 pdf.RDMCell(155,5, issue.subject,"RTB")
330 332 pdf.Ln
331 333
332 334 pdf.SetFontStyle('B',9)
333 335 pdf.RDMCell(35,5, l(:field_description) + ":")
334 336 pdf.SetFontStyle('',9)
335 337 pdf.RDMMultiCell(155,5, issue.description.to_s,"BR")
336 338
337 339 pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
338 340 pdf.Line(pdf.GetX, pdf.GetY, 170, pdf.GetY)
339 341 pdf.Ln
340 342
341 if issue.changesets.any? && User.current.allowed_to?(:view_changesets, issue.project)
343 if issue.changesets.any? &&
344 User.current.allowed_to?(:view_changesets, issue.project)
342 345 pdf.SetFontStyle('B',9)
343 346 pdf.RDMCell(190,5, l(:label_associated_revisions), "B")
344 347 pdf.Ln
345 348 for changeset in issue.changesets
346 349 pdf.SetFontStyle('B',8)
347 pdf.RDMCell(190,5, format_time(changeset.committed_on) + " - " + changeset.author.to_s)
350 pdf.RDMCell(190,5,
351 format_time(changeset.committed_on) + " - " + changeset.author.to_s)
348 352 pdf.Ln
349 353 unless changeset.comments.blank?
350 354 pdf.SetFontStyle('',8)
351 355 pdf.RDMMultiCell(190,5, changeset.comments.to_s)
352 356 end
353 357 pdf.Ln
354 358 end
355 359 end
356 360
357 361 pdf.SetFontStyle('B',9)
358 362 pdf.RDMCell(190,5, l(:label_history), "B")
359 363 pdf.Ln
360 for journal in issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
364 for journal in issue.journals.find(
365 :all, :include => [:user, :details],
366 :order => "#{Journal.table_name}.created_on ASC")
361 367 pdf.SetFontStyle('B',8)
362 pdf.RDMCell(190,5, format_time(journal.created_on) + " - " + journal.user.name)
368 pdf.RDMCell(190,5,
369 format_time(journal.created_on) + " - " + journal.user.name)
363 370 pdf.Ln
364 371 pdf.SetFontStyle('I',8)
365 372 for detail in journal.details
366 373 pdf.RDMCell(190,5, "- " + show_detail(detail, true))
367 374 pdf.Ln
368 375 end
369 376 if journal.notes?
370 377 pdf.SetFontStyle('',8)
371 378 pdf.RDMMultiCell(190,5, journal.notes.to_s)
372 379 end
373 380 pdf.Ln
374 381 end
375
382
376 383 if issue.attachments.any?
377 384 pdf.SetFontStyle('B',9)
378 385 pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
379 386 pdf.Ln
380 387 for attachment in issue.attachments
381 388 pdf.SetFontStyle('',8)
382 389 pdf.RDMCell(80,5, attachment.filename)
383 390 pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
384 391 pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
385 392 pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
386 393 pdf.Ln
387 394 end
388 395 end
389 396 pdf.Output
390 397 end
391
392 398 end
393 399 end
394 400 end
General Comments 0
You need to be logged in to leave comments. Login now