##// END OF EJS Templates
remove trailing white-spaces lib/redmine/export/pdf.rb....
Toshi MARUYAMA -
r5543:479d9380a7ec
parent child
Show More
@@ -1,470 +1,470
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-2011 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 'fpdf/chinese'
22 require 'fpdf/chinese'
23 require 'fpdf/japanese'
23 require 'fpdf/japanese'
24 require 'fpdf/korean'
24 require 'fpdf/korean'
25
25
26 module Redmine
26 module Redmine
27 module Export
27 module Export
28 module PDF
28 module PDF
29 include ActionView::Helpers::TextHelper
29 include ActionView::Helpers::TextHelper
30 include ActionView::Helpers::NumberHelper
30 include ActionView::Helpers::NumberHelper
31
31
32 class ITCPDF < TCPDF
32 class ITCPDF < TCPDF
33 include Redmine::I18n
33 include Redmine::I18n
34 attr_accessor :footer_date
34 attr_accessor :footer_date
35
35
36 def initialize(lang)
36 def initialize(lang)
37 super()
37 super()
38 set_language_if_valid lang
38 set_language_if_valid lang
39 @font_for_content = 'FreeSans'
39 @font_for_content = 'FreeSans'
40 @font_for_footer = 'FreeSans'
40 @font_for_footer = 'FreeSans'
41 SetCreator(Redmine::Info.app_name)
41 SetCreator(Redmine::Info.app_name)
42 SetFont(@font_for_content)
42 SetFont(@font_for_content)
43 end
43 end
44
44
45 def SetFontStyle(style, size)
45 def SetFontStyle(style, size)
46 SetFont(@font_for_content, style, size)
46 SetFont(@font_for_content, style, size)
47 end
47 end
48
48
49 def SetTitle(txt)
49 def SetTitle(txt)
50 txt = begin
50 txt = begin
51 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
51 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
52 hextxt = "<FEFF" # FEFF is BOM
52 hextxt = "<FEFF" # FEFF is BOM
53 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
53 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
54 hextxt << ">"
54 hextxt << ">"
55 rescue
55 rescue
56 txt
56 txt
57 end || ''
57 end || ''
58 super(txt)
58 super(txt)
59 end
59 end
60
60
61 def textstring(s)
61 def textstring(s)
62 # Format a text string
62 # Format a text string
63 if s =~ /^</ # This means the string is hex-dumped.
63 if s =~ /^</ # This means the string is hex-dumped.
64 return s
64 return s
65 else
65 else
66 return '('+escape(s)+')'
66 return '('+escape(s)+')'
67 end
67 end
68 end
68 end
69
69
70 alias RDMCell Cell
70 alias RDMCell Cell
71 alias RDMMultiCell MultiCell
71 alias RDMMultiCell MultiCell
72
72
73 def Footer
73 def Footer
74 SetFont(@font_for_footer, 'I', 8)
74 SetFont(@font_for_footer, 'I', 8)
75 SetY(-15)
75 SetY(-15)
76 SetX(15)
76 SetX(15)
77 RDMCell(0, 5, @footer_date, 0, 0, 'L')
77 RDMCell(0, 5, @footer_date, 0, 0, 'L')
78 SetY(-15)
78 SetY(-15)
79 SetX(-30)
79 SetX(-30)
80 RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
80 RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
81 end
81 end
82 end
82 end
83
83
84 class IFPDF < FPDF
84 class IFPDF < FPDF
85 include Redmine::I18n
85 include Redmine::I18n
86 attr_accessor :footer_date
86 attr_accessor :footer_date
87
87
88 def initialize(lang)
88 def initialize(lang)
89 super()
89 super()
90 set_language_if_valid lang
90 set_language_if_valid lang
91 case l(:general_pdf_encoding).upcase
91 case l(:general_pdf_encoding).upcase
92 when 'CP949'
92 when 'CP949'
93 extend(PDF_Korean)
93 extend(PDF_Korean)
94 AddUHCFont()
94 AddUHCFont()
95 @font_for_content = 'UHC'
95 @font_for_content = 'UHC'
96 @font_for_footer = 'UHC'
96 @font_for_footer = 'UHC'
97 when 'CP932'
97 when 'CP932'
98 extend(PDF_Japanese)
98 extend(PDF_Japanese)
99 AddSJISFont()
99 AddSJISFont()
100 @font_for_content = 'SJIS'
100 @font_for_content = 'SJIS'
101 @font_for_footer = 'SJIS'
101 @font_for_footer = 'SJIS'
102 when 'GB18030'
102 when 'GB18030'
103 extend(PDF_Chinese)
103 extend(PDF_Chinese)
104 AddGBFont()
104 AddGBFont()
105 @font_for_content = 'GB'
105 @font_for_content = 'GB'
106 @font_for_footer = 'GB'
106 @font_for_footer = 'GB'
107 when 'BIG5'
107 when 'BIG5'
108 extend(PDF_Chinese)
108 extend(PDF_Chinese)
109 AddBig5Font()
109 AddBig5Font()
110 @font_for_content = 'Big5'
110 @font_for_content = 'Big5'
111 @font_for_footer = 'Big5'
111 @font_for_footer = 'Big5'
112 else
112 else
113 @font_for_content = 'Arial'
113 @font_for_content = 'Arial'
114 @font_for_footer = 'Helvetica'
114 @font_for_footer = 'Helvetica'
115 end
115 end
116 SetCreator(Redmine::Info.app_name)
116 SetCreator(Redmine::Info.app_name)
117 SetFont(@font_for_content)
117 SetFont(@font_for_content)
118 end
118 end
119
119
120 def SetFontStyle(style, size)
120 def SetFontStyle(style, size)
121 SetFont(@font_for_content, style, size)
121 SetFont(@font_for_content, style, size)
122 end
122 end
123
123
124 def SetTitle(txt)
124 def SetTitle(txt)
125 txt = begin
125 txt = begin
126 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
126 utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
127 hextxt = "<FEFF" # FEFF is BOM
127 hextxt = "<FEFF" # FEFF is BOM
128 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
128 hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
129 hextxt << ">"
129 hextxt << ">"
130 rescue
130 rescue
131 txt
131 txt
132 end || ''
132 end || ''
133 super(txt)
133 super(txt)
134 end
134 end
135
135
136 def textstring(s)
136 def textstring(s)
137 # Format a text string
137 # Format a text string
138 if s =~ /^</ # This means the string is hex-dumped.
138 if s =~ /^</ # This means the string is hex-dumped.
139 return s
139 return s
140 else
140 else
141 return '('+escape(s)+')'
141 return '('+escape(s)+')'
142 end
142 end
143 end
143 end
144
144
145 def fix_text_encoding(txt)
145 def fix_text_encoding(txt)
146 txt ||= ''
146 txt ||= ''
147 if txt.respond_to?(:force_encoding)
147 if txt.respond_to?(:force_encoding)
148 txt.force_encoding('UTF-8')
148 txt.force_encoding('UTF-8')
149 txt = txt.encode(l(:general_pdf_encoding), :invalid => :replace,
149 txt = txt.encode(l(:general_pdf_encoding), :invalid => :replace,
150 :undef => :replace, :replace => '?')
150 :undef => :replace, :replace => '?')
151 txt.force_encoding('ASCII-8BIT')
151 txt.force_encoding('ASCII-8BIT')
152 else
152 else
153 @ic ||= Iconv.new(l(:general_pdf_encoding), 'UTF-8')
153 @ic ||= Iconv.new(l(:general_pdf_encoding), 'UTF-8')
154 txtar = ""
154 txtar = ""
155 begin
155 begin
156 txtar += @ic.iconv(txt)
156 txtar += @ic.iconv(txt)
157 rescue Iconv::IllegalSequence
157 rescue Iconv::IllegalSequence
158 txtar += $!.success
158 txtar += $!.success
159 txt = '?' + $!.failed[1,$!.failed.length]
159 txt = '?' + $!.failed[1,$!.failed.length]
160 retry
160 retry
161 rescue
161 rescue
162 txtar += $!.success
162 txtar += $!.success
163 end
163 end
164 txt = txtar
164 txt = txtar
165 end
165 end
166 txt
166 txt
167 end
167 end
168
168
169 def RDMCell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
169 def RDMCell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
170 Cell(w,h,fix_text_encoding(txt),border,ln,align,fill,link)
170 Cell(w,h,fix_text_encoding(txt),border,ln,align,fill,link)
171 end
171 end
172
172
173 def RDMMultiCell(w,h=0,txt='',border=0,align='',fill=0)
173 def RDMMultiCell(w,h=0,txt='',border=0,align='',fill=0)
174 MultiCell(w,h,fix_text_encoding(txt),border,align,fill)
174 MultiCell(w,h,fix_text_encoding(txt),border,align,fill)
175 end
175 end
176
176
177 def Footer
177 def Footer
178 SetFont(@font_for_footer, 'I', 8)
178 SetFont(@font_for_footer, 'I', 8)
179 SetY(-15)
179 SetY(-15)
180 SetX(15)
180 SetX(15)
181 RDMCell(0, 5, @footer_date, 0, 0, 'L')
181 RDMCell(0, 5, @footer_date, 0, 0, 'L')
182 SetY(-15)
182 SetY(-15)
183 SetX(-30)
183 SetX(-30)
184 RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
184 RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
185 end
185 end
186 alias alias_nb_pages AliasNbPages
186 alias alias_nb_pages AliasNbPages
187 end
187 end
188
188
189 # Returns a PDF string of a list of issues
189 # Returns a PDF string of a list of issues
190 def issues_to_pdf(issues, project, query)
190 def issues_to_pdf(issues, project, query)
191 if l(:general_pdf_encoding).upcase != 'UTF-8'
191 if l(:general_pdf_encoding).upcase != 'UTF-8'
192 pdf = IFPDF.new(current_language)
192 pdf = IFPDF.new(current_language)
193 else
193 else
194 pdf = ITCPDF.new(current_language)
194 pdf = ITCPDF.new(current_language)
195 end
195 end
196 title = query.new_record? ? l(:label_issue_plural) : query.name
196 title = query.new_record? ? l(:label_issue_plural) : query.name
197 title = "#{project} - #{title}" if project
197 title = "#{project} - #{title}" if project
198 pdf.SetTitle(title)
198 pdf.SetTitle(title)
199 pdf.alias_nb_pages
199 pdf.alias_nb_pages
200 pdf.footer_date = format_date(Date.today)
200 pdf.footer_date = format_date(Date.today)
201 pdf.SetAutoPageBreak(false)
201 pdf.SetAutoPageBreak(false)
202 pdf.AddPage("L")
202 pdf.AddPage("L")
203
203
204 # Landscape A4 = 210 x 297 mm
204 # Landscape A4 = 210 x 297 mm
205 page_height = 210
205 page_height = 210
206 page_width = 297
206 page_width = 297
207 right_margin = 10
207 right_margin = 10
208 bottom_margin = 20
208 bottom_margin = 20
209 col_id_width = 10
209 col_id_width = 10
210 row_height = 5
210 row_height = 5
211
211
212 # column widths
212 # column widths
213 table_width = page_width - right_margin - 10 # fixed left margin
213 table_width = page_width - right_margin - 10 # fixed left margin
214 col_width = []
214 col_width = []
215 unless query.columns.empty?
215 unless query.columns.empty?
216 col_width = query.columns.collect do |c|
216 col_width = query.columns.collect do |c|
217 (c.name == :subject || (c.is_a?(QueryCustomFieldColumn) && ['string', 'text'].include?(c.custom_field.field_format)))? 4.0 : 1.0
217 (c.name == :subject || (c.is_a?(QueryCustomFieldColumn) && ['string', 'text'].include?(c.custom_field.field_format)))? 4.0 : 1.0
218 end
218 end
219 ratio = (table_width - col_id_width) / col_width.inject(0) {|s,w| s += w}
219 ratio = (table_width - col_id_width) / col_width.inject(0) {|s,w| s += w}
220 col_width = col_width.collect {|w| w * ratio}
220 col_width = col_width.collect {|w| w * ratio}
221 end
221 end
222
222
223 # title
223 # title
224 pdf.SetFontStyle('B',11)
224 pdf.SetFontStyle('B',11)
225 pdf.RDMCell(190,10, title)
225 pdf.RDMCell(190,10, title)
226 pdf.Ln
226 pdf.Ln
227
227
228 # headers
228 # headers
229 pdf.SetFontStyle('B',8)
229 pdf.SetFontStyle('B',8)
230 pdf.SetFillColor(230, 230, 230)
230 pdf.SetFillColor(230, 230, 230)
231
231
232 # render it background to find the max height used
232 # render it background to find the max height used
233 base_x = pdf.GetX
233 base_x = pdf.GetX
234 base_y = pdf.GetY
234 base_y = pdf.GetY
235 max_height = issues_to_pdf_write_cells(pdf, query.columns, col_width, row_height, true)
235 max_height = issues_to_pdf_write_cells(pdf, query.columns, col_width, row_height, true)
236 pdf.Rect(base_x, base_y, table_width, max_height, 'FD');
236 pdf.Rect(base_x, base_y, table_width, max_height, 'FD');
237 pdf.SetXY(base_x, base_y);
237 pdf.SetXY(base_x, base_y);
238
238
239 # write the cells on page
239 # write the cells on page
240 pdf.RDMCell(col_id_width, row_height, "#", "T", 0, 'C', 1)
240 pdf.RDMCell(col_id_width, row_height, "#", "T", 0, 'C', 1)
241 issues_to_pdf_write_cells(pdf, query.columns, col_width, row_height, true)
241 issues_to_pdf_write_cells(pdf, query.columns, col_width, row_height, true)
242 issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
242 issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
243 pdf.SetY(base_y + max_height);
243 pdf.SetY(base_y + max_height);
244
244
245 # rows
245 # rows
246 pdf.SetFontStyle('',8)
246 pdf.SetFontStyle('',8)
247 pdf.SetFillColor(255, 255, 255)
247 pdf.SetFillColor(255, 255, 255)
248 previous_group = false
248 previous_group = false
249 issues.each do |issue|
249 issues.each do |issue|
250 if query.grouped? &&
250 if query.grouped? &&
251 (group = query.group_by_column.value(issue)) != previous_group
251 (group = query.group_by_column.value(issue)) != previous_group
252 pdf.SetFontStyle('B',9)
252 pdf.SetFontStyle('B',9)
253 pdf.RDMCell(277, row_height,
253 pdf.RDMCell(277, row_height,
254 (group.blank? ? 'None' : group.to_s) + " (#{query.issue_count_by_group[group]})",
254 (group.blank? ? 'None' : group.to_s) + " (#{query.issue_count_by_group[group]})",
255 1, 1, 'L')
255 1, 1, 'L')
256 pdf.SetFontStyle('',8)
256 pdf.SetFontStyle('',8)
257 previous_group = group
257 previous_group = group
258 end
258 end
259 # fetch all the row values
259 # fetch all the row values
260 col_values = query.columns.collect do |column|
260 col_values = query.columns.collect do |column|
261 s = if column.is_a?(QueryCustomFieldColumn)
261 s = if column.is_a?(QueryCustomFieldColumn)
262 cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
262 cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
263 show_value(cv)
263 show_value(cv)
264 else
264 else
265 value = issue.send(column.name)
265 value = issue.send(column.name)
266 if value.is_a?(Date)
266 if value.is_a?(Date)
267 format_date(value)
267 format_date(value)
268 elsif value.is_a?(Time)
268 elsif value.is_a?(Time)
269 format_time(value)
269 format_time(value)
270 else
270 else
271 value
271 value
272 end
272 end
273 end
273 end
274 s.to_s
274 s.to_s
275 end
275 end
276
276
277 # render it off-page to find the max height used
277 # render it off-page to find the max height used
278 base_x = pdf.GetX
278 base_x = pdf.GetX
279 base_y = pdf.GetY
279 base_y = pdf.GetY
280 pdf.SetY(2 * page_height)
280 pdf.SetY(2 * page_height)
281 max_height = issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
281 max_height = issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
282 pdf.SetXY(base_x, base_y)
282 pdf.SetXY(base_x, base_y)
283
283
284 # make new page if it doesn't fit on the current one
284 # make new page if it doesn't fit on the current one
285 space_left = page_height - base_y - bottom_margin
285 space_left = page_height - base_y - bottom_margin
286 if max_height > space_left
286 if max_height > space_left
287 pdf.AddPage("L")
287 pdf.AddPage("L")
288 base_x = pdf.GetX
288 base_x = pdf.GetX
289 base_y = pdf.GetY
289 base_y = pdf.GetY
290 end
290 end
291
291
292 # write the cells on page
292 # write the cells on page
293 pdf.RDMCell(col_id_width, row_height, issue.id.to_s, "T", 0, 'C', 1)
293 pdf.RDMCell(col_id_width, row_height, issue.id.to_s, "T", 0, 'C', 1)
294 issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
294 issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
295 issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
295 issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
296 pdf.SetY(base_y + max_height);
296 pdf.SetY(base_y + max_height);
297 end
297 end
298
298
299 if issues.size == Setting.issues_export_limit.to_i
299 if issues.size == Setting.issues_export_limit.to_i
300 pdf.SetFontStyle('B',10)
300 pdf.SetFontStyle('B',10)
301 pdf.RDMCell(0, row_height, '...')
301 pdf.RDMCell(0, row_height, '...')
302 end
302 end
303 pdf.Output
303 pdf.Output
304 end
304 end
305
305
306 # Renders MultiCells and returns the maximum height used
306 # Renders MultiCells and returns the maximum height used
307 def issues_to_pdf_write_cells(pdf, col_values, col_widths, row_height, head=false)
307 def issues_to_pdf_write_cells(pdf, col_values, col_widths, row_height, head=false)
308 base_y = pdf.GetY
308 base_y = pdf.GetY
309 max_height = row_height
309 max_height = row_height
310 col_values.each_with_index do |column, i|
310 col_values.each_with_index do |column, i|
311 col_x = pdf.GetX
311 col_x = pdf.GetX
312 if head == true
312 if head == true
313 pdf.RDMMultiCell(col_widths[i], row_height, column.caption, "T", 'L', 1)
313 pdf.RDMMultiCell(col_widths[i], row_height, column.caption, "T", 'L', 1)
314 else
314 else
315 pdf.RDMMultiCell(col_widths[i], row_height, column, "T", 'L', 1)
315 pdf.RDMMultiCell(col_widths[i], row_height, column, "T", 'L', 1)
316 end
316 end
317 max_height = (pdf.GetY - base_y) if (pdf.GetY - base_y) > max_height
317 max_height = (pdf.GetY - base_y) if (pdf.GetY - base_y) > max_height
318 pdf.SetXY(col_x + col_widths[i], base_y);
318 pdf.SetXY(col_x + col_widths[i], base_y);
319 end
319 end
320 return max_height
320 return max_height
321 end
321 end
322
322
323 # Draw lines to close the row (MultiCell border drawing in not uniform)
323 # Draw lines to close the row (MultiCell border drawing in not uniform)
324 def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y, id_width, col_widths)
324 def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y, id_width, col_widths)
325 col_x = top_x + id_width
325 col_x = top_x + id_width
326 pdf.Line(col_x, top_y, col_x, lower_y) # id right border
326 pdf.Line(col_x, top_y, col_x, lower_y) # id right border
327 col_widths.each do |width|
327 col_widths.each do |width|
328 col_x += width
328 col_x += width
329 pdf.Line(col_x, top_y, col_x, lower_y) # columns right border
329 pdf.Line(col_x, top_y, col_x, lower_y) # columns right border
330 end
330 end
331 pdf.Line(top_x, top_y, top_x, lower_y) # left border
331 pdf.Line(top_x, top_y, top_x, lower_y) # left border
332 pdf.Line(top_x, lower_y, col_x, lower_y) # bottom border
332 pdf.Line(top_x, lower_y, col_x, lower_y) # bottom border
333 end
333 end
334
334
335 # Returns a PDF string of a single issue
335 # Returns a PDF string of a single issue
336 def issue_to_pdf(issue)
336 def issue_to_pdf(issue)
337 if l(:general_pdf_encoding).upcase != 'UTF-8'
337 if l(:general_pdf_encoding).upcase != 'UTF-8'
338 pdf = IFPDF.new(current_language)
338 pdf = IFPDF.new(current_language)
339 else
339 else
340 pdf = ITCPDF.new(current_language)
340 pdf = ITCPDF.new(current_language)
341 end
341 end
342 pdf.SetTitle("#{issue.project} - ##{issue.tracker} #{issue.id}")
342 pdf.SetTitle("#{issue.project} - ##{issue.tracker} #{issue.id}")
343 pdf.alias_nb_pages
343 pdf.alias_nb_pages
344 pdf.footer_date = format_date(Date.today)
344 pdf.footer_date = format_date(Date.today)
345 pdf.AddPage
345 pdf.AddPage
346 pdf.SetFontStyle('B',11)
346 pdf.SetFontStyle('B',11)
347 pdf.RDMMultiCell(190,5, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
347 pdf.RDMMultiCell(190,5, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
348 pdf.Ln
348 pdf.Ln
349
349
350 y0 = pdf.GetY
350 y0 = pdf.GetY
351
351
352 pdf.SetFontStyle('B',9)
352 pdf.SetFontStyle('B',9)
353 pdf.RDMCell(35,5, l(:field_status) + ":","LT")
353 pdf.RDMCell(35,5, l(:field_status) + ":","LT")
354 pdf.SetFontStyle('',9)
354 pdf.SetFontStyle('',9)
355 pdf.RDMCell(60,5, issue.status.to_s,"RT")
355 pdf.RDMCell(60,5, issue.status.to_s,"RT")
356 pdf.SetFontStyle('B',9)
356 pdf.SetFontStyle('B',9)
357 pdf.RDMCell(35,5, l(:field_priority) + ":","LT")
357 pdf.RDMCell(35,5, l(:field_priority) + ":","LT")
358 pdf.SetFontStyle('',9)
358 pdf.SetFontStyle('',9)
359 pdf.RDMCell(60,5, issue.priority.to_s,"RT")
359 pdf.RDMCell(60,5, issue.priority.to_s,"RT")
360 pdf.Ln
360 pdf.Ln
361
361
362 pdf.SetFontStyle('B',9)
362 pdf.SetFontStyle('B',9)
363 pdf.RDMCell(35,5, l(:field_author) + ":","L")
363 pdf.RDMCell(35,5, l(:field_author) + ":","L")
364 pdf.SetFontStyle('',9)
364 pdf.SetFontStyle('',9)
365 pdf.RDMCell(60,5, issue.author.to_s,"R")
365 pdf.RDMCell(60,5, issue.author.to_s,"R")
366 pdf.SetFontStyle('B',9)
366 pdf.SetFontStyle('B',9)
367 pdf.RDMCell(35,5, l(:field_category) + ":","L")
367 pdf.RDMCell(35,5, l(:field_category) + ":","L")
368 pdf.SetFontStyle('',9)
368 pdf.SetFontStyle('',9)
369 pdf.RDMCell(60,5, issue.category.to_s,"R")
369 pdf.RDMCell(60,5, issue.category.to_s,"R")
370 pdf.Ln
370 pdf.Ln
371
371
372 pdf.SetFontStyle('B',9)
372 pdf.SetFontStyle('B',9)
373 pdf.RDMCell(35,5, l(:field_created_on) + ":","L")
373 pdf.RDMCell(35,5, l(:field_created_on) + ":","L")
374 pdf.SetFontStyle('',9)
374 pdf.SetFontStyle('',9)
375 pdf.RDMCell(60,5, format_date(issue.created_on),"R")
375 pdf.RDMCell(60,5, format_date(issue.created_on),"R")
376 pdf.SetFontStyle('B',9)
376 pdf.SetFontStyle('B',9)
377 pdf.RDMCell(35,5, l(:field_assigned_to) + ":","L")
377 pdf.RDMCell(35,5, l(:field_assigned_to) + ":","L")
378 pdf.SetFontStyle('',9)
378 pdf.SetFontStyle('',9)
379 pdf.RDMCell(60,5, issue.assigned_to.to_s,"R")
379 pdf.RDMCell(60,5, issue.assigned_to.to_s,"R")
380 pdf.Ln
380 pdf.Ln
381
381
382 pdf.SetFontStyle('B',9)
382 pdf.SetFontStyle('B',9)
383 pdf.RDMCell(35,5, l(:field_updated_on) + ":","LB")
383 pdf.RDMCell(35,5, l(:field_updated_on) + ":","LB")
384 pdf.SetFontStyle('',9)
384 pdf.SetFontStyle('',9)
385 pdf.RDMCell(60,5, format_date(issue.updated_on),"RB")
385 pdf.RDMCell(60,5, format_date(issue.updated_on),"RB")
386 pdf.SetFontStyle('B',9)
386 pdf.SetFontStyle('B',9)
387 pdf.RDMCell(35,5, l(:field_due_date) + ":","LB")
387 pdf.RDMCell(35,5, l(:field_due_date) + ":","LB")
388 pdf.SetFontStyle('',9)
388 pdf.SetFontStyle('',9)
389 pdf.RDMCell(60,5, format_date(issue.due_date),"RB")
389 pdf.RDMCell(60,5, format_date(issue.due_date),"RB")
390 pdf.Ln
390 pdf.Ln
391
391
392 for custom_value in issue.custom_field_values
392 for custom_value in issue.custom_field_values
393 pdf.SetFontStyle('B',9)
393 pdf.SetFontStyle('B',9)
394 pdf.RDMCell(35,5, custom_value.custom_field.name + ":","L")
394 pdf.RDMCell(35,5, custom_value.custom_field.name + ":","L")
395 pdf.SetFontStyle('',9)
395 pdf.SetFontStyle('',9)
396 pdf.RDMMultiCell(155,5, (show_value custom_value),"R")
396 pdf.RDMMultiCell(155,5, (show_value custom_value),"R")
397 end
397 end
398
398
399 pdf.SetFontStyle('B',9)
399 pdf.SetFontStyle('B',9)
400 pdf.RDMCell(35,5, l(:field_subject) + ":","LT")
400 pdf.RDMCell(35,5, l(:field_subject) + ":","LT")
401 pdf.SetFontStyle('',9)
401 pdf.SetFontStyle('',9)
402 pdf.RDMMultiCell(155,5, issue.subject,"RT")
402 pdf.RDMMultiCell(155,5, issue.subject,"RT")
403
403
404 pdf.SetFontStyle('B',9)
404 pdf.SetFontStyle('B',9)
405 pdf.RDMCell(35,5, l(:field_description) + ":","LT")
405 pdf.RDMCell(35,5, l(:field_description) + ":","LT")
406 pdf.SetFontStyle('',9)
406 pdf.SetFontStyle('',9)
407 pdf.RDMMultiCell(155,5, issue.description.to_s,"RT")
407 pdf.RDMMultiCell(155,5, issue.description.to_s,"RT")
408
408
409 pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
409 pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
410 pdf.Line(pdf.GetX, pdf.GetY, pdf.GetX + 190, pdf.GetY)
410 pdf.Line(pdf.GetX, pdf.GetY, pdf.GetX + 190, pdf.GetY)
411 pdf.Ln
411 pdf.Ln
412
412
413 if issue.changesets.any? &&
413 if issue.changesets.any? &&
414 User.current.allowed_to?(:view_changesets, issue.project)
414 User.current.allowed_to?(:view_changesets, issue.project)
415 pdf.SetFontStyle('B',9)
415 pdf.SetFontStyle('B',9)
416 pdf.RDMCell(190,5, l(:label_associated_revisions), "B")
416 pdf.RDMCell(190,5, l(:label_associated_revisions), "B")
417 pdf.Ln
417 pdf.Ln
418 for changeset in issue.changesets
418 for changeset in issue.changesets
419 pdf.SetFontStyle('B',8)
419 pdf.SetFontStyle('B',8)
420 pdf.RDMCell(190,5,
420 pdf.RDMCell(190,5,
421 format_time(changeset.committed_on) + " - " + changeset.author.to_s)
421 format_time(changeset.committed_on) + " - " + changeset.author.to_s)
422 pdf.Ln
422 pdf.Ln
423 unless changeset.comments.blank?
423 unless changeset.comments.blank?
424 pdf.SetFontStyle('',8)
424 pdf.SetFontStyle('',8)
425 pdf.RDMMultiCell(190,5, changeset.comments.to_s)
425 pdf.RDMMultiCell(190,5, changeset.comments.to_s)
426 end
426 end
427 pdf.Ln
427 pdf.Ln
428 end
428 end
429 end
429 end
430
430
431 pdf.SetFontStyle('B',9)
431 pdf.SetFontStyle('B',9)
432 pdf.RDMCell(190,5, l(:label_history), "B")
432 pdf.RDMCell(190,5, l(:label_history), "B")
433 pdf.Ln
433 pdf.Ln
434 for journal in issue.journals.find(
434 for journal in issue.journals.find(
435 :all, :include => [:user, :details],
435 :all, :include => [:user, :details],
436 :order => "#{Journal.table_name}.created_on ASC")
436 :order => "#{Journal.table_name}.created_on ASC")
437 pdf.SetFontStyle('B',8)
437 pdf.SetFontStyle('B',8)
438 pdf.RDMCell(190,5,
438 pdf.RDMCell(190,5,
439 format_time(journal.created_on) + " - " + journal.user.name)
439 format_time(journal.created_on) + " - " + journal.user.name)
440 pdf.Ln
440 pdf.Ln
441 pdf.SetFontStyle('I',8)
441 pdf.SetFontStyle('I',8)
442 for detail in journal.details
442 for detail in journal.details
443 pdf.RDMMultiCell(190,5, "- " + show_detail(detail, true))
443 pdf.RDMMultiCell(190,5, "- " + show_detail(detail, true))
444 end
444 end
445 if journal.notes?
445 if journal.notes?
446 pdf.Ln unless journal.details.empty?
446 pdf.Ln unless journal.details.empty?
447 pdf.SetFontStyle('',8)
447 pdf.SetFontStyle('',8)
448 pdf.RDMMultiCell(190,5, journal.notes.to_s)
448 pdf.RDMMultiCell(190,5, journal.notes.to_s)
449 end
449 end
450 pdf.Ln
450 pdf.Ln
451 end
451 end
452
452
453 if issue.attachments.any?
453 if issue.attachments.any?
454 pdf.SetFontStyle('B',9)
454 pdf.SetFontStyle('B',9)
455 pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
455 pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
456 pdf.Ln
456 pdf.Ln
457 for attachment in issue.attachments
457 for attachment in issue.attachments
458 pdf.SetFontStyle('',8)
458 pdf.SetFontStyle('',8)
459 pdf.RDMCell(80,5, attachment.filename)
459 pdf.RDMCell(80,5, attachment.filename)
460 pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
460 pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
461 pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
461 pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
462 pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
462 pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
463 pdf.Ln
463 pdf.Ln
464 end
464 end
465 end
465 end
466 pdf.Output
466 pdf.Output
467 end
467 end
468 end
468 end
469 end
469 end
470 end
470 end
General Comments 0
You need to be logged in to leave comments. Login now