From 4b15b0a0b9b484ee93517fb60b70e5544d9da96e Mon Sep 17 00:00:00 2001 From: Christian Noack Date: Tue, 1 Feb 2011 17:06:31 +0100 Subject: [PATCH] wrap lines bei pdf-export Content-Type: text/plain; charset="utf-8" --- lib/redmine/export/pdf.rb | 475 ++++++++++++++++++++++++++------------------- 1 files changed, 271 insertions(+), 204 deletions(-) diff --git a/lib/redmine/export/pdf.rb b/lib/redmine/export/pdf.rb index 5639b66..f78a4cc 100644 --- a/lib/redmine/export/pdf.rb +++ b/lib/redmine/export/pdf.rb @@ -26,69 +26,69 @@ module Redmine module PDF include ActionView::Helpers::TextHelper include ActionView::Helpers::NumberHelper - + class IFPDF < FPDF include Redmine::I18n attr_accessor :footer_date - + def initialize(lang) super() set_language_if_valid lang case current_language.to_s.downcase - when 'ko' - extend(PDF_Korean) - AddUHCFont() - @font_for_content = 'UHC' - @font_for_footer = 'UHC' - when 'ja' - extend(PDF_Japanese) - AddSJISFont() - @font_for_content = 'SJIS' - @font_for_footer = 'SJIS' - when 'zh' - extend(PDF_Chinese) - AddGBFont() - @font_for_content = 'GB' - @font_for_footer = 'GB' - when 'zh-tw' - extend(PDF_Chinese) - AddBig5Font() - @font_for_content = 'Big5' - @font_for_footer = 'Big5' - else - @font_for_content = 'Arial' - @font_for_footer = 'Helvetica' + when 'ko' + extend(PDF_Korean) + AddUHCFont() + @font_for_content = 'UHC' + @font_for_footer = 'UHC' + when 'ja' + extend(PDF_Japanese) + AddSJISFont() + @font_for_content = 'SJIS' + @font_for_footer = 'SJIS' + when 'zh' + extend(PDF_Chinese) + AddGBFont() + @font_for_content = 'GB' + @font_for_footer = 'GB' + when 'zh-tw' + extend(PDF_Chinese) + AddBig5Font() + @font_for_content = 'Big5' + @font_for_footer = 'Big5' + else + @font_for_content = 'Arial' + @font_for_footer = 'Helvetica' end SetCreator(Redmine::Info.app_name) SetFont(@font_for_content) end - + def SetFontStyle(style, size) SetFont(@font_for_content, style, size) end - + def SetTitle(txt) txt = begin utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt) - hextxt = "" rescue txt end || '' super(txt) end - + def textstring(s) # Format a text string - if s =~ /^ space_left + pdf.AddPage("L") + base_x = pdf.GetX + base_y = pdf.GetY + end + + # write the cells on page + pdf.Cell(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.SetFontStyle('B', 10) pdf.Cell(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.MultiCell(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) pdf = IFPDF.new(current_language) @@ -192,126 +260,125 @@ module Redmine pdf.AliasNbPages pdf.footer_date = format_date(Date.today) pdf.AddPage - - pdf.SetFontStyle('B',11) - pdf.Cell(190,10, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}") + + pdf.SetFontStyle('B', 11) + pdf.MultiCell(190, 5, "#{issue.project} - #{issue.tracker} # #{issue.id}: #{issue.subject}") pdf.Ln - + y0 = pdf.GetY - - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_status) + ":","LT") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, issue.status.to_s,"RT") - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_priority) + ":","LT") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, issue.priority.to_s,"RT") + + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_status) + ":", "LT") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, issue.status.to_s, "RT") + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_priority) + ":", "LT") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, issue.priority.to_s, "RT") pdf.Ln - - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_author) + ":","L") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, issue.author.to_s,"R") - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_category) + ":","L") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, issue.category.to_s,"R") - pdf.Ln - - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_created_on) + ":","L") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, format_date(issue.created_on),"R") - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_assigned_to) + ":","L") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, issue.assigned_to.to_s,"R") + + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_author) + ":", "L") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, issue.author.to_s, "R") + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_category) + ":", "L") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, issue.category.to_s, "R") + pdf.Ln + + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_created_on) + ":", "L") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, format_date(issue.created_on), "R") + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_assigned_to) + ":", "L") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, issue.assigned_to.to_s, "R") pdf.Ln - - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_updated_on) + ":","LB") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, format_date(issue.updated_on),"RB") - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_due_date) + ":","LB") - pdf.SetFontStyle('',9) - pdf.Cell(60,5, format_date(issue.due_date),"RB") + + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_updated_on) + ":", "LB") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, format_date(issue.updated_on), "RB") + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_due_date) + ":", "LB") + pdf.SetFontStyle('', 9) + pdf.Cell(60, 5, format_date(issue.due_date), "RB") pdf.Ln - + for custom_value in issue.custom_field_values - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, custom_value.custom_field.name + ":","L") - pdf.SetFontStyle('',9) - pdf.MultiCell(155,5, (show_value custom_value),"R") + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, custom_value.custom_field.name + ":", "L") + pdf.SetFontStyle('', 9) + pdf.MultiCell(155, 5, (show_value custom_value), "R") end - - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_subject) + ":","LTB") - pdf.SetFontStyle('',9) - pdf.Cell(155,5, issue.subject,"RTB") - pdf.Ln - - pdf.SetFontStyle('B',9) - pdf.Cell(35,5, l(:field_description) + ":") - pdf.SetFontStyle('',9) - pdf.MultiCell(155,5, issue.description,"BR") - + + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_subject) + ":", "LT") + pdf.SetFontStyle('', 9) + pdf.MultiCell(155, 5, issue.subject, "RT") + + pdf.SetFontStyle('B', 9) + pdf.Cell(35, 5, l(:field_description) + ":", "LT") + pdf.SetFontStyle('', 9) + pdf.MultiCell(155, 5, @issue.description, "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? && User.current.allowed_to?(:view_changesets, issue.project) - pdf.SetFontStyle('B',9) - pdf.Cell(190,5, l(:label_associated_revisions), "B") + pdf.SetFontStyle('B', 9) + pdf.Cell(190, 5, l(:label_associated_revisions), "B") pdf.Ln for changeset in issue.changesets - pdf.SetFontStyle('B',8) - pdf.Cell(190,5, format_time(changeset.committed_on) + " - " + changeset.author.to_s) + pdf.SetFontStyle('B', 8) + pdf.Cell(190, 5, format_time(changeset.committed_on) + " - " + changeset.author.to_s) pdf.Ln unless changeset.comments.blank? - pdf.SetFontStyle('',8) - pdf.MultiCell(190,5, changeset.comments) - end + pdf.SetFontStyle('', 8) + pdf.MultiCell(190, 5, changeset.comments) + end pdf.Ln end end - - pdf.SetFontStyle('B',9) - pdf.Cell(190,5, l(:label_history), "B") - pdf.Ln + + pdf.SetFontStyle('B', 9) + pdf.Cell(190, 5, l(:label_history), "B") + pdf.Ln for journal in issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC") - pdf.SetFontStyle('B',8) - pdf.Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name) + pdf.SetFontStyle('B', 8) + pdf.Cell(190, 5, format_time(journal.created_on) + " - " + journal.user.name) pdf.Ln - pdf.SetFontStyle('I',8) + pdf.SetFontStyle('I', 8) for detail in journal.details - pdf.Cell(190,5, "- " + show_detail(detail, true)) - pdf.Ln + pdf.MultiCell(190, 5, "- " + show_detail(detail, true)) end if journal.notes? - pdf.SetFontStyle('',8) - pdf.MultiCell(190,5, journal.notes) - end + pdf.Ln unless journal.details.empty? + pdf.SetFontStyle('', 8) + pdf.MultiCell(190, 5, journal.notes) + end pdf.Ln end - + if issue.attachments.any? - pdf.SetFontStyle('B',9) - pdf.Cell(190,5, l(:label_attachment_plural), "B") + pdf.SetFontStyle('B', 9) + pdf.Cell(190, 5, l(:label_attachment_plural), "B") pdf.Ln for attachment in issue.attachments - pdf.SetFontStyle('',8) - pdf.Cell(80,5, attachment.filename) - pdf.Cell(20,5, number_to_human_size(attachment.filesize),0,0,"R") - pdf.Cell(25,5, format_date(attachment.created_on),0,0,"R") - pdf.Cell(65,5, attachment.author.name,0,0,"R") + pdf.SetFontStyle('', 8) + pdf.Cell(80, 5, attachment.filename) + pdf.Cell(20, 5, number_to_human_size(attachment.filesize), 0, 0, "R") + pdf.Cell(25, 5, format_date(attachment.created_on), 0, 0, "R") + pdf.Cell(65, 5, attachment.author.name, 0, 0, "R") pdf.Ln end end pdf.Output end - + # Returns a PDF string of a gantt chart def gantt_to_pdf(gantt, project) pdf = IFPDF.new(current_language) @@ -319,19 +386,19 @@ module Redmine pdf.AliasNbPages pdf.footer_date = format_date(Date.today) pdf.AddPage("L") - pdf.SetFontStyle('B',12) + pdf.SetFontStyle('B', 12) pdf.SetX(15) pdf.Cell(70, 20, project.to_s) pdf.Ln - pdf.SetFontStyle('B',9) - + pdf.SetFontStyle('B', 9) + subject_width = 100 header_heigth = 5 - + headers_heigth = header_heigth show_weeks = false show_days = false - + if gantt.months < 7 show_weeks = true headers_heigth = 2*header_heigth @@ -340,27 +407,27 @@ module Redmine headers_heigth = 3*header_heigth end end - + g_width = 280 - subject_width zoom = (g_width) / (gantt.date_to - gantt.date_from + 1) g_height = 120 t_height = g_height + headers_heigth - + y_start = pdf.GetY - + # Months headers month_f = gantt.date_from left = subject_width height = header_heigth - gantt.months.times do - width = ((month_f >> 1) - month_f) * zoom + gantt.months.times do + width = ((month_f >> 1) - month_f) * zoom pdf.SetY(y_start) pdf.SetX(left) pdf.Cell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C") left = left + width month_f = month_f >> 1 - end - + end + # Weeks headers if show_weeks left = subject_width @@ -386,14 +453,14 @@ module Redmine week_f = week_f+7 end end - + # Days headers if show_days left = subject_width height = header_heigth wday = gantt.date_from.cwday - pdf.SetFontStyle('B',7) - (gantt.date_to - gantt.date_from + 1).to_i.times do + pdf.SetFontStyle('B', 7) + (gantt.date_to - gantt.date_from + 1).to_i.times do width = zoom pdf.SetY(y_start + 2 * header_heigth) pdf.SetX(left) @@ -403,18 +470,18 @@ module Redmine wday = 1 if wday > 7 end end - + pdf.SetY(y_start) pdf.SetX(15) pdf.Cell(subject_width+g_width-15, headers_heigth, "", 1) - + # Tasks top = headers_heigth + y_start - pdf.SetFontStyle('B',7) + pdf.SetFontStyle('B', 7) gantt.events.each do |i| pdf.SetY(top) pdf.SetX(15) - + text = "" if i.is_a? Issue text = "#{i.tracker} #{i.id}: #{i.subject}" @@ -423,61 +490,61 @@ module Redmine end text = "#{i.project} - #{text}" unless project && project == i.project pdf.Cell(subject_width-15, 5, text, "LR") - + pdf.SetY(top + 0.2) pdf.SetX(subject_width) pdf.SetFillColor(255, 255, 255) pdf.Cell(g_width, 4.6, "", "LR", 0, "", 1) pdf.SetY(top+1.5) - + if i.is_a? Issue - i_start_date = (i.start_date >= gantt.date_from ? i.start_date : gantt.date_from ) - i_end_date = (i.due_before <= gantt.date_to ? i.due_before : gantt.date_to ) - + i_start_date = (i.start_date >= gantt.date_from ? i.start_date : gantt.date_from) + i_end_date = (i.due_before <= gantt.date_to ? i.due_before : gantt.date_to) + i_done_date = i.start_date + ((i.due_before - i.start_date+1)*i.done_ratio/100).floor - i_done_date = (i_done_date <= gantt.date_from ? gantt.date_from : i_done_date ) - i_done_date = (i_done_date >= gantt.date_to ? gantt.date_to : i_done_date ) - + i_done_date = (i_done_date <= gantt.date_from ? gantt.date_from : i_done_date) + i_done_date = (i_done_date >= gantt.date_to ? gantt.date_to : i_done_date) + i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today - - i_left = ((i_start_date - gantt.date_from)*zoom) + + i_left = ((i_start_date - gantt.date_from)*zoom) i_width = ((i_end_date - i_start_date + 1)*zoom) d_width = ((i_done_date - i_start_date)*zoom) l_width = ((i_late_date - i_start_date+1)*zoom) if i_late_date l_width ||= 0 - + pdf.SetX(subject_width + i_left) - pdf.SetFillColor(200,200,200) + pdf.SetFillColor(200, 200, 200) pdf.Cell(i_width, 2, "", 0, 0, "", 1) - + if l_width > 0 pdf.SetY(top+1.5) pdf.SetX(subject_width + i_left) - pdf.SetFillColor(255,100,100) + pdf.SetFillColor(255, 100, 100) pdf.Cell(l_width, 2, "", 0, 0, "", 1) - end + end if d_width > 0 pdf.SetY(top+1.5) pdf.SetX(subject_width + i_left) - pdf.SetFillColor(100,100,255) + pdf.SetFillColor(100, 100, 255) pdf.Cell(d_width, 2, "", 0, 0, "", 1) end - + pdf.SetY(top+1.5) pdf.SetX(subject_width + i_left + i_width) pdf.Cell(30, 2, "#{i.status} #{i.done_ratio}%") else - i_left = ((i.start_date - gantt.date_from)*zoom) - + i_left = ((i.start_date - gantt.date_from)*zoom) + pdf.SetX(subject_width + i_left) - pdf.SetFillColor(50,200,50) - pdf.Cell(2, 2, "", 0, 0, "", 1) - + pdf.SetFillColor(50, 200, 50) + pdf.Cell(2, 2, "", 0, 0, "", 1) + pdf.SetY(top+1.5) pdf.SetX(subject_width + i_left + 3) pdf.Cell(30, 2, "#{i.name}") end - + top = top + 5 pdf.SetDrawColor(200, 200, 200) pdf.Line(15, top, subject_width+g_width, top) @@ -488,7 +555,7 @@ module Redmine end pdf.SetDrawColor(0, 0, 0) end - + pdf.Line(15, top, subject_width+g_width, top) pdf.Output end -- 1.7.2.3