From: Toshi MARUYAMA Date: Sat, 30 Apr 2011 00:29:22 +0000 (+0000) Subject: Wrap long text fields properly in PDF exports (#5629). X-Git-Tag: 1.2.0~280 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=880e8e575a14ba51bdfe26d0c7a3cb5ef28b21dd;p=redmine.git Wrap long text fields properly in PDF exports (#5629). Contributed by Hugo Ferreira. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@5604 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/lib/redmine/export/pdf.rb b/lib/redmine/export/pdf.rb index 0273ee554..1f8ca0667 100644 --- a/lib/redmine/export/pdf.rb +++ b/lib/redmine/export/pdf.rb @@ -198,16 +198,28 @@ module Redmine pdf.SetTitle(title) pdf.alias_nb_pages pdf.footer_date = format_date(Date.today) + pdf.SetAutoPageBreak(false) pdf.AddPage("L") - - row_height = 6 + + # Landscape A4 = 210 x 297 mm + page_height = 210 + page_width = 297 + right_margin = 10 + bottom_margin = 20 + col_id_width = 10 + row_height = 5 + + # column widths + table_width = page_width - right_margin - 10 # fixed left margin col_width = [] unless query.columns.empty? - col_width = query.columns.collect {|column| column.name == :subject ? 4.0 : 1.0 } - ratio = 262.0 / col_width.inject(0) {|s,w| s += w} + col_width = query.columns.collect do |c| + (c.name == :subject || (c.is_a?(QueryCustomFieldColumn) && ['string', 'text'].include?(c.custom_field.field_format)))? 4.0 : 1.0 + end + ratio = (table_width - col_id_width) / col_width.inject(0) {|s,w| s += w} col_width = col_width.collect {|w| w * ratio} end - + # title pdf.SetFontStyle('B',11) pdf.RDMCell(190,10, title) @@ -216,7 +228,7 @@ module Redmine # headers pdf.SetFontStyle('B',8) pdf.SetFillColor(230, 230, 230) - pdf.RDMCell(15, row_height, "#", 1, 0, 'L', 1) + pdf.RDMCell(col_id_width, row_height, "#", 1, 0, 'C', 1) query.columns.each_with_index do |column, i| pdf.RDMCell(col_width[i], row_height, column.caption, 1, 0, 'L', 1) end @@ -236,8 +248,8 @@ module Redmine pdf.SetFontStyle('',8) previous_group = group end - pdf.RDMCell(15, row_height, issue.id.to_s, 1, 0, 'L', 1) - query.columns.each_with_index do |column, i| + # fetch all the row values + col_values = query.columns.collect do |column| s = if column.is_a?(QueryCustomFieldColumn) cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id} show_value(cv) @@ -251,17 +263,63 @@ module Redmine value end end - pdf.RDMCell(col_width[i], row_height, s.to_s, 1, 0, 'L', 1) + s.to_s end - pdf.Ln + + # render it off-page to find the max height used + base_x = pdf.GetX + base_y = pdf.GetY + pdf.SetY(2 * page_height) + max_height = issues_to_pdf_write_cells(pdf, col_values, col_width, row_height) + pdf.SetXY(base_x, base_y) + + # make new page if it doesn't fit on the current one + space_left = page_height - base_y - bottom_margin + if max_height > space_left + pdf.AddPage("L") + base_x = pdf.GetX + base_y = pdf.GetY + end + + # write the cells on page + pdf.RDMCell(col_id_width, row_height, issue.id.to_s, "T", 0, 'C', 1) + issues_to_pdf_write_cells(pdf, col_values, col_width, row_height) + issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width) + pdf.SetY(base_y + max_height); end + if issues.size == Setting.issues_export_limit.to_i pdf.SetFontStyle('B',10) pdf.RDMCell(0, row_height, '...') end pdf.Output end - + + # Renders MultiCells and returns the maximum height used + def issues_to_pdf_write_cells(pdf, col_values, col_widths, row_height) + base_y = pdf.GetY + max_height = row_height + col_values.each_with_index do |column, i| + col_x = pdf.GetX + pdf.RDMMultiCell(col_widths[i], row_height, col_values[i], "T", 'L', 1) + max_height = (pdf.GetY - base_y) if (pdf.GetY - base_y) > max_height + pdf.SetXY(col_x + col_widths[i], base_y); + end + return max_height + end + + # Draw lines to close the row (MultiCell border drawing in not uniform) + def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y, id_width, col_widths) + col_x = top_x + id_width + pdf.Line(col_x, top_y, col_x, lower_y) # id right border + col_widths.each do |width| + col_x += width + pdf.Line(col_x, top_y, col_x, lower_y) # columns right border + end + pdf.Line(top_x, top_y, top_x, lower_y) # left border + pdf.Line(top_x, lower_y, col_x, lower_y) # bottom border + end + # Returns a PDF string of a single issue def issue_to_pdf(issue) if l(:general_pdf_encoding).upcase != 'UTF-8' @@ -273,14 +331,12 @@ module Redmine pdf.alias_nb_pages pdf.footer_date = format_date(Date.today) pdf.AddPage - - pdf.SetFontStyle('B',11) - pdf.RDMCell(190,10, - "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}") + pdf.SetFontStyle('B',11) + pdf.RDMMultiCell(190,5, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}") pdf.Ln - + y0 = pdf.GetY - + pdf.SetFontStyle('B',9) pdf.RDMCell(35,5, l(:field_status) + ":","LT") pdf.SetFontStyle('',9) @@ -329,18 +385,17 @@ module Redmine end pdf.SetFontStyle('B',9) - pdf.RDMCell(35,5, l(:field_subject) + ":","LTB") + pdf.RDMCell(35,5, l(:field_subject) + ":","LT") pdf.SetFontStyle('',9) - pdf.RDMCell(155,5, issue.subject,"RTB") - pdf.Ln - + pdf.RDMMultiCell(155,5, issue.subject,"RT") + pdf.SetFontStyle('B',9) - pdf.RDMCell(35,5, l(:field_description) + ":") + pdf.RDMCell(35,5, l(:field_description) + ":","LT") pdf.SetFontStyle('',9) - pdf.RDMMultiCell(155,5, issue.description.to_s,"BR") - + pdf.RDMMultiCell(155,5, issue.description.to_s,"RT") + pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY) - pdf.Line(pdf.GetX, pdf.GetY, 170, pdf.GetY) + pdf.Line(pdf.GetX, pdf.GetY, pdf.GetX + 190, pdf.GetY) pdf.Ln if issue.changesets.any? && @@ -373,10 +428,10 @@ module Redmine pdf.Ln pdf.SetFontStyle('I',8) for detail in journal.details - pdf.RDMCell(190,5, "- " + show_detail(detail, true)) - pdf.Ln + pdf.RDMMultiCell(190,5, "- " + show_detail(detail, true)) end if journal.notes? + pdf.Ln unless journal.details.empty? pdf.SetFontStyle('',8) pdf.RDMMultiCell(190,5, journal.notes.to_s) end