Revision 1298:4f746d8966dd lib/redmine/export

View differences:

lib/redmine/export/pdf.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  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
......
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
require 'iconv'
21 20
require 'tcpdf'
22 21
require 'fpdf/chinese'
23 22
require 'fpdf/japanese'
24 23
require 'fpdf/korean'
25 24

  
25
if RUBY_VERSION < '1.9'
26
  require 'iconv'
27
end
28

  
26 29
module Redmine
27 30
  module Export
28 31
    module PDF
......
86 89

  
87 90
        def SetTitle(txt)
88 91
          txt = begin
89
            utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
92
            utf16txt = to_utf16(txt)
90 93
            hextxt = "<FEFF"  # FEFF is BOM
91 94
            hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
92 95
            hextxt << ">"
......
116 119
          html
117 120
        end
118 121

  
122
        # Encodes an UTF-8 string to UTF-16BE
123
        def to_utf16(str)
124
          if str.respond_to?(:encode)
125
            str.encode('UTF-16BE')
126
          else
127
            Iconv.conv('UTF-16BE', 'UTF-8', str)
128
          end
129
        end
130

  
119 131
        def RDMCell(w ,h=0, txt='', border=0, ln=0, align='', fill=0, link='')
120 132
          Cell(w, h, fix_text_encoding(txt), border, ln, align, fill, link)
121 133
        end
......
160 172

  
161 173
        def bookmark_title(txt)
162 174
          txt = begin
163
            utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
175
            utf16txt = to_utf16(txt)
164 176
            hextxt = "<FEFF"  # FEFF is BOM
165 177
            hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
166 178
            hextxt << ">"
......
368 380
        col_width
369 381
      end
370 382

  
371
      def render_table_header(pdf, query, col_width, row_height, col_id_width, table_width)
383
      def render_table_header(pdf, query, col_width, row_height, table_width)
372 384
        # headers
373 385
        pdf.SetFontStyle('B',8)
374 386
        pdf.SetFillColor(230, 230, 230)
......
377 389
        base_x = pdf.GetX
378 390
        base_y = pdf.GetY
379 391
        max_height = issues_to_pdf_write_cells(pdf, query.inline_columns, col_width, row_height, true)
380
        pdf.Rect(base_x, base_y, table_width + col_id_width, max_height, 'FD');
392
        pdf.Rect(base_x, base_y, table_width, max_height, 'FD');
381 393
        pdf.SetXY(base_x, base_y);
382 394

  
383 395
        # write the cells on page
384
        pdf.RDMCell(col_id_width, row_height, "#", "T", 0, 'C', 1)
385 396
        issues_to_pdf_write_cells(pdf, query.inline_columns, col_width, row_height, true)
386
        issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
397
        issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
387 398
        pdf.SetY(base_y + max_height);
388 399

  
389 400
        # rows
......
405 416
        # Landscape A4 = 210 x 297 mm
406 417
        page_height   = 210
407 418
        page_width    = 297
419
        left_margin   = 10
408 420
        right_margin  = 10
409 421
        bottom_margin = 20
410
        col_id_width  = 10
411 422
        row_height    = 4
412 423

  
413 424
        # column widths
414
        table_width = page_width - right_margin - 10  # fixed left margin
425
        table_width = page_width - right_margin - left_margin
415 426
        col_width = []
416 427
        unless query.inline_columns.empty?
417
          col_width = calc_col_width(issues, query, table_width - col_id_width, pdf)
428
          col_width = calc_col_width(issues, query, table_width, pdf)
418 429
          table_width = col_width.inject(0) {|s,v| s += v}
419 430
        end
420 431

  
421
				# use full width if the description is displayed
432
        # use full width if the description is displayed
422 433
        if table_width > 0 && query.has_column?(:description)
423
          col_width = col_width.map {|w| w = w * (page_width - right_margin - 10 - col_id_width) / table_width}
434
          col_width = col_width.map {|w| w * (page_width - right_margin - left_margin) / table_width}
424 435
          table_width = col_width.inject(0) {|s,v| s += v}
425 436
        end
426 437

  
......
428 439
        pdf.SetFontStyle('B',11)
429 440
        pdf.RDMCell(190,10, title)
430 441
        pdf.Ln
431
        render_table_header(pdf, query, col_width, row_height, col_id_width, table_width)
442
        render_table_header(pdf, query, col_width, row_height, table_width)
432 443
        previous_group = false
433 444
        issue_list(issues) do |issue, level|
434 445
          if query.grouped? &&
......
437 448
            group_label = group.blank? ? 'None' : group.to_s.dup
438 449
            group_label << " (#{query.issue_count_by_group[group]})"
439 450
            pdf.Bookmark group_label, 0, -1
440
            pdf.RDMCell(table_width + col_id_width, row_height * 2, group_label, 1, 1, 'L')
451
            pdf.RDMCell(table_width, row_height * 2, group_label, 1, 1, 'L')
441 452
            pdf.SetFontStyle('',8)
442 453
            previous_group = group
443 454
          end
......
456 467
          space_left = page_height - base_y - bottom_margin
457 468
          if max_height > space_left
458 469
            pdf.AddPage("L")
459
            render_table_header(pdf, query, col_width, row_height, col_id_width, table_width)
470
            render_table_header(pdf, query, col_width, row_height, table_width)
460 471
            base_x = pdf.GetX
461 472
            base_y = pdf.GetY
462 473
          end
463 474

  
464 475
          # write the cells on page
465
          pdf.RDMCell(col_id_width, row_height, issue.id.to_s, "T", 0, 'C', 1)
466 476
          issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
467
          issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
477
          issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
468 478
          pdf.SetY(base_y + max_height);
469 479

  
470 480
          if query.has_column?(:description) && issue.description?
......
501 511
      end
502 512

  
503 513
      # Draw lines to close the row (MultiCell border drawing in not uniform)
514
      #
515
      #  parameter "col_id_width" is not used. it is kept for compatibility.
504 516
      def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y,
505
                                     id_width, col_widths)
506
        col_x = top_x + id_width
517
                                     col_id_width, col_widths)
518
        col_x = top_x
507 519
        pdf.Line(col_x, top_y, col_x, lower_y)    # id right border
508 520
        col_widths.each do |width|
509 521
          col_x += width

Also available in: Unified diff