Project

General

Profile

Defect #61 » pdf.rb_rfpdf115_2.patch

Jun NAITOH, 2011-03-29 16:08

View differences:

lib/redmine/export/pdf.rb 2011-03-08 04:44:40.000000000 +0900 → lib/redmine/export/pdf.rb 2011-03-29 22:16:24.000000000 +0900
19 19

  
20 20
require 'iconv'
21 21
require 'rfpdf/fpdf'
22
require 'rfpdf/chinese'
22
require 'fpdf/chinese'
23
require 'fpdf/japanese'
24
require 'fpdf/korean'
23 25

  
24 26
module Redmine
25 27
  module Export
......
27 29
      include ActionView::Helpers::TextHelper
28 30
      include ActionView::Helpers::NumberHelper
29 31
      
32
      class ITCPDF < TCPDF
33
        include Redmine::I18n
34
        attr_accessor :footer_date
35
        
36
        def initialize(lang)
37
          super()
38
          set_language_if_valid lang
39
          @font_for_content = 'FreeSans'
40
          @font_for_footer = 'FreeSans'              
41
          SetCreator(Redmine::Info.app_name)
42
          SetFont(@font_for_content)
43
        end
44
        
45
        def SetFontStyle(style, size)
46
          SetFont(@font_for_content, style, size)
47
        end
48
        
49
        def SetTitle(txt)
50
          txt = begin
51
            utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
52
            hextxt = "<FEFF"  # FEFF is BOM
53
            hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
54
            hextxt << ">"
55
          rescue
56
            txt
57
          end || ''
58
          super(txt)
59
        end
60
    
61
        def textstring(s)
62
          # Format a text string
63
          if s =~ /^</  # This means the string is hex-dumped.
64
            return s
65
          else
66
            return '('+escape(s)+')'
67
          end
68
        end
69
         
70
        alias UTF8Cell Cell
71
        alias UTF8MultiCell MultiCell
72
         
73
        def Footer
74
          SetFont(@font_for_footer, 'I', 8)
75
          SetY(-15)
76
          SetX(15)
77
          UTF8Cell(0, 5, @footer_date, 0, 0, 'L')
78
          SetY(-15)
79
          SetX(-30)
80
          UTF8Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
81
        end
82
      end
83

  
30 84
      class IFPDF < FPDF
31 85
        include Redmine::I18n
32 86
        attr_accessor :footer_date
......
88 142
          end
89 143
        end
90 144
          
91
        def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
145
        def fix_text_encoding(txt)
92 146
          @ic ||= Iconv.new(l(:general_pdf_encoding), 'UTF-8')
93 147
          # these quotation marks are not correctly rendered in the pdf
94 148
          txt = txt.gsub(/[“�]/, '"') if txt
......
100 154
          rescue
101 155
            txt
102 156
          end || ''
103
          super w,h,txt,border,ln,align,fill,link
157
            return txt
158
        end
159
        
160
        def UTF8Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
161
            Cell(w,h,fix_text_encoding(txt),border,ln,align,fill,link)
162
        end
163
        
164
        def UTF8MultiCell(w,h=0,txt='',border=0,align='',fill=0)
165
            MultiCell(w,h,fix_text_encoding(txt),border,align,fill)
104 166
        end
105 167
        
106 168
        def Footer
107 169
          SetFont(@font_for_footer, 'I', 8)
108 170
          SetY(-15)
109 171
          SetX(15)
110
          Cell(0, 5, @footer_date, 0, 0, 'L')
172
          UTF8Cell(0, 5, @footer_date, 0, 0, 'L')
111 173
          SetY(-15)
112 174
          SetX(-30)
113
          Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
175
          UTF8Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
114 176
        end
177
        alias alias_nb_pages AliasNbPages
115 178
      end
116 179
      
117 180
      # Returns a PDF string of a list of issues
118 181
      def issues_to_pdf(issues, project, query)
119
        pdf = IFPDF.new(current_language)
182
        if l(:general_pdf_encoding).upcase == 'UTF-8'
183
          pdf = ITCPDF.new(current_language)
184
        else
185
          pdf = IFPDF.new(current_language)
186
        end
187

  
120 188
        title = query.new_record? ? l(:label_issue_plural) : query.name
121 189
        title = "#{project} - #{title}" if project
122 190
        pdf.SetTitle(title)
123
        pdf.AliasNbPages
191
        pdf.alias_nb_pages
124 192
        pdf.footer_date = format_date(Date.today)
125 193
        pdf.AddPage("L")
126 194
        
......
134 202
        
135 203
        # title
136 204
        pdf.SetFontStyle('B',11)    
137
        pdf.Cell(190,10, title)
205
        pdf.UTF8Cell(190,10, title)
138 206
        pdf.Ln
139 207
        
140 208
        # headers
141 209
        pdf.SetFontStyle('B',8)
142 210
        pdf.SetFillColor(230, 230, 230)
143
        pdf.Cell(15, row_height, "#", 1, 0, 'L', 1)
211
        pdf.UTF8Cell(15, row_height, "#", 1, 0, 'L', 1)
144 212
        query.columns.each_with_index do |column, i|
145
          pdf.Cell(col_width[i], row_height, column.caption, 1, 0, 'L', 1)
213
          pdf.UTF8Cell(col_width[i], row_height, column.caption, 1, 0, 'L', 1)
146 214
        end
147 215
        pdf.Ln
148 216
        
......
153 221
        issues.each do |issue|
154 222
          if query.grouped? && (group = query.group_by_column.value(issue)) != previous_group
155 223
            pdf.SetFontStyle('B',9)
156
            pdf.Cell(277, row_height, 
224
            pdf.UTF8Cell(277, row_height, 
157 225
              (group.blank? ? 'None' : group.to_s) + " (#{query.issue_count_by_group[group]})",
158 226
              1, 1, 'L')
159 227
            pdf.SetFontStyle('',8)
160 228
            previous_group = group
161 229
          end
162
          pdf.Cell(15, row_height, issue.id.to_s, 1, 0, 'L', 1)
230
          pdf.UTF8Cell(15, row_height, issue.id.to_s, 1, 0, 'L', 1)
163 231
          query.columns.each_with_index do |column, i|
164 232
            s = if column.is_a?(QueryCustomFieldColumn)
165 233
              cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
......
174 242
                value
175 243
              end
176 244
            end
177
            pdf.Cell(col_width[i], row_height, s.to_s, 1, 0, 'L', 1)
245
            pdf.UTF8Cell(col_width[i], row_height, s.to_s, 1, 0, 'L', 1)
178 246
          end
179 247
          pdf.Ln
180 248
        end
181 249
        if issues.size == Setting.issues_export_limit.to_i
182 250
          pdf.SetFontStyle('B',10)
183
          pdf.Cell(0, row_height, '...')
251
          pdf.UTF8Cell(0, row_height, '...')
184 252
        end
185 253
        pdf.Output
186 254
      end
187 255

  
188 256
      # Returns a PDF string of a single issue
189 257
      def issue_to_pdf(issue)
190
        pdf = IFPDF.new(current_language)
258
        if l(:general_pdf_encoding).upcase == 'UTF-8'
259
          pdf = ITCPDF.new(current_language)
260
        else
261
          pdf = IFPDF.new(current_language)
262
        end
191 263
        pdf.SetTitle("#{issue.project} - ##{issue.tracker} #{issue.id}")
192
        pdf.AliasNbPages
264
        pdf.alias_nb_pages
193 265
        pdf.footer_date = format_date(Date.today)
194 266
        pdf.AddPage
195 267
        
196 268
        pdf.SetFontStyle('B',11)    
197
        pdf.Cell(190,10, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
269
        pdf.UTF8Cell(190,10, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}")
198 270
        pdf.Ln
199 271
        
200 272
        y0 = pdf.GetY
201 273
        
202 274
        pdf.SetFontStyle('B',9)
203
        pdf.Cell(35,5, l(:field_status) + ":","LT")
275
        pdf.UTF8Cell(35,5, l(:field_status) + ":","LT")
204 276
        pdf.SetFontStyle('',9)
205
        pdf.Cell(60,5, issue.status.to_s,"RT")
277
        pdf.UTF8Cell(60,5, issue.status.to_s,"RT")
206 278
        pdf.SetFontStyle('B',9)
207
        pdf.Cell(35,5, l(:field_priority) + ":","LT")
279
        pdf.UTF8Cell(35,5, l(:field_priority) + ":","LT")
208 280
        pdf.SetFontStyle('',9)
209
        pdf.Cell(60,5, issue.priority.to_s,"RT")        
281
        pdf.UTF8Cell(60,5, issue.priority.to_s,"RT")        
210 282
        pdf.Ln
211 283
        
212 284
        pdf.SetFontStyle('B',9)
213
        pdf.Cell(35,5, l(:field_author) + ":","L")
285
        pdf.UTF8Cell(35,5, l(:field_author) + ":","L")
214 286
        pdf.SetFontStyle('',9)
215
        pdf.Cell(60,5, issue.author.to_s,"R")
287
        pdf.UTF8Cell(60,5, issue.author.to_s,"R")
216 288
        pdf.SetFontStyle('B',9)
217
        pdf.Cell(35,5, l(:field_category) + ":","L")
289
        pdf.UTF8Cell(35,5, l(:field_category) + ":","L")
218 290
        pdf.SetFontStyle('',9)
219
        pdf.Cell(60,5, issue.category.to_s,"R")
291
        pdf.UTF8Cell(60,5, issue.category.to_s,"R")
220 292
        pdf.Ln   
221 293
        
222 294
        pdf.SetFontStyle('B',9)
223
        pdf.Cell(35,5, l(:field_created_on) + ":","L")
295
        pdf.UTF8Cell(35,5, l(:field_created_on) + ":","L")
224 296
        pdf.SetFontStyle('',9)
225
        pdf.Cell(60,5, format_date(issue.created_on),"R")
297
        pdf.UTF8Cell(60,5, format_date(issue.created_on),"R")
226 298
        pdf.SetFontStyle('B',9)
227
        pdf.Cell(35,5, l(:field_assigned_to) + ":","L")
299
        pdf.UTF8Cell(35,5, l(:field_assigned_to) + ":","L")
228 300
        pdf.SetFontStyle('',9)
229
        pdf.Cell(60,5, issue.assigned_to.to_s,"R")
301
        pdf.UTF8Cell(60,5, issue.assigned_to.to_s,"R")
230 302
        pdf.Ln
231 303
        
232 304
        pdf.SetFontStyle('B',9)
233
        pdf.Cell(35,5, l(:field_updated_on) + ":","LB")
305
        pdf.UTF8Cell(35,5, l(:field_updated_on) + ":","LB")
234 306
        pdf.SetFontStyle('',9)
235
        pdf.Cell(60,5, format_date(issue.updated_on),"RB")
307
        pdf.UTF8Cell(60,5, format_date(issue.updated_on),"RB")
236 308
        pdf.SetFontStyle('B',9)
237
        pdf.Cell(35,5, l(:field_due_date) + ":","LB")
309
        pdf.UTF8Cell(35,5, l(:field_due_date) + ":","LB")
238 310
        pdf.SetFontStyle('',9)
239
        pdf.Cell(60,5, format_date(issue.due_date),"RB")
311
        pdf.UTF8Cell(60,5, format_date(issue.due_date),"RB")
240 312
        pdf.Ln
241 313
        
242 314
        for custom_value in issue.custom_field_values
243 315
          pdf.SetFontStyle('B',9)
244
          pdf.Cell(35,5, custom_value.custom_field.name + ":","L")
316
          pdf.UTF8Cell(35,5, custom_value.custom_field.name + ":","L")
245 317
          pdf.SetFontStyle('',9)
246
          pdf.MultiCell(155,5, (show_value custom_value),"R")
318
          pdf.UTF8MultiCell(155,5, (show_value custom_value),"R")
247 319
        end
248 320
        
249 321
        pdf.SetFontStyle('B',9)
250
        pdf.Cell(35,5, l(:field_subject) + ":","LTB")
322
        pdf.UTF8Cell(35,5, l(:field_subject) + ":","LTB")
251 323
        pdf.SetFontStyle('',9)
252
        pdf.Cell(155,5, issue.subject,"RTB")
324
        pdf.UTF8Cell(155,5, issue.subject,"RTB")
253 325
        pdf.Ln    
254 326
        
255 327
        pdf.SetFontStyle('B',9)
256
        pdf.Cell(35,5, l(:field_description) + ":")
328
        pdf.UTF8Cell(35,5, l(:field_description) + ":")
257 329
        pdf.SetFontStyle('',9)
258
        pdf.MultiCell(155,5, issue.description.to_s,"BR")
330
        pdf.UTF8MultiCell(155,5, issue.description.to_s,"BR")
259 331
        
260 332
        pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
261 333
        pdf.Line(pdf.GetX, pdf.GetY, 170, pdf.GetY)
......
263 335
        
264 336
        if issue.changesets.any? && User.current.allowed_to?(:view_changesets, issue.project)
265 337
          pdf.SetFontStyle('B',9)
266
          pdf.Cell(190,5, l(:label_associated_revisions), "B")
338
          pdf.UTF8Cell(190,5, l(:label_associated_revisions), "B")
267 339
          pdf.Ln
268 340
          for changeset in issue.changesets
269 341
            pdf.SetFontStyle('B',8)
270
            pdf.Cell(190,5, format_time(changeset.committed_on) + " - " + changeset.author.to_s)
342
            pdf.UTF8Cell(190,5, format_time(changeset.committed_on) + " - " + changeset.author.to_s)
271 343
            pdf.Ln
272 344
            unless changeset.comments.blank?
273 345
              pdf.SetFontStyle('',8)
274
              pdf.MultiCell(190,5, changeset.comments.to_s)
346
              pdf.UTF8MultiCell(190,5, changeset.comments.to_s)
275 347
            end   
276 348
            pdf.Ln
277 349
          end
278 350
        end
279 351
        
280 352
        pdf.SetFontStyle('B',9)
281
        pdf.Cell(190,5, l(:label_history), "B")
353
        pdf.UTF8Cell(190,5, l(:label_history), "B")
282 354
        pdf.Ln  
283 355
        for journal in issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
284 356
          pdf.SetFontStyle('B',8)
285
          pdf.Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name)
357
          pdf.UTF8Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name)
286 358
          pdf.Ln
287 359
          pdf.SetFontStyle('I',8)
288 360
          for detail in journal.details
289
            pdf.Cell(190,5, "- " + show_detail(detail, true))
361
            pdf.UTF8Cell(190,5, "- " + show_detail(detail, true))
290 362
            pdf.Ln
291 363
          end
292 364
          if journal.notes?
293 365
            pdf.SetFontStyle('',8)
294
            pdf.MultiCell(190,5, journal.notes.to_s)
366
            pdf.UTF8MultiCell(190,5, journal.notes.to_s)
295 367
          end   
296 368
          pdf.Ln
297 369
        end
298 370
        
299 371
        if issue.attachments.any?
300 372
          pdf.SetFontStyle('B',9)
301
          pdf.Cell(190,5, l(:label_attachment_plural), "B")
373
          pdf.UTF8Cell(190,5, l(:label_attachment_plural), "B")
302 374
          pdf.Ln
303 375
          for attachment in issue.attachments
304 376
            pdf.SetFontStyle('',8)
305
            pdf.Cell(80,5, attachment.filename)
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")
308
            pdf.Cell(65,5, attachment.author.name,0,0,"R")
377
            pdf.UTF8Cell(80,5, attachment.filename)
378
            pdf.UTF8Cell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
379
            pdf.UTF8Cell(25,5, format_date(attachment.created_on),0,0,"R")
380
            pdf.UTF8Cell(65,5, attachment.author.name,0,0,"R")
309 381
            pdf.Ln
310 382
          end
311 383
        end
(27-27/46)