From 8ede393ea465d08a49da83ec9316c37ad13f369e Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 15 Jan 2014 10:57:09 +0100 Subject: [PATCH] refactoring. modularised the page elements into models and now rendering text boxes as a heirarchy. --- .../pdf_export/taskboard_card/card_element.rb | 43 +++++++++ .../taskboard_card/column_element.rb | 31 ++++++ .../taskboard_card/document_generator.rb | 96 +++++++------------ .../pdf_export/taskboard_card/row_element.rb | 25 +++++ 4 files changed, 131 insertions(+), 64 deletions(-) create mode 100644 lib/open_project/pdf_export/taskboard_card/card_element.rb create mode 100644 lib/open_project/pdf_export/taskboard_card/column_element.rb create mode 100644 lib/open_project/pdf_export/taskboard_card/row_element.rb diff --git a/lib/open_project/pdf_export/taskboard_card/card_element.rb b/lib/open_project/pdf_export/taskboard_card/card_element.rb new file mode 100644 index 0000000000..95b48daf19 --- /dev/null +++ b/lib/open_project/pdf_export/taskboard_card/card_element.rb @@ -0,0 +1,43 @@ +module OpenProject::PdfExport::TaskboardCard + class CardElement + def initialize(pdf, orientation, rows_config, work_package) + @pdf = pdf + @orientation = orientation + @rows_config = rows_config + @work_package = work_package + @row_elements = [] + + # Initialize row elements + row_y_offset = 0 + rows_config["rows"].each do |key, value| + # TODO: Intelligently configure the orientation of row elements + row_orientation = { + y_offset: @orientation[:height] - row_y_offset, + x_offset: 0, + width: 400, # TODO: Calculate + height: 40 # TODO: Calculate + } + row_y_offset += 40 # TODO: Calculate from text size, lines, priority, whatever + + @row_elements << RowElement.new(@pdf, row_orientation, value["columns"], @work_package) + end + end + + def draw + top_left = [@orientation[:x_offset], @orientation[:y_offset]] + bounds = @orientation.slice(:width, :height) + + @pdf.bounding_box(top_left, bounds) do + @pdf.stroke_color 'FF0000' + + # Draw rows + @row_elements.each do |row| + row.draw + end + + @pdf.stroke_bounds + end + + end + end +end \ No newline at end of file diff --git a/lib/open_project/pdf_export/taskboard_card/column_element.rb b/lib/open_project/pdf_export/taskboard_card/column_element.rb new file mode 100644 index 0000000000..906c1a6de6 --- /dev/null +++ b/lib/open_project/pdf_export/taskboard_card/column_element.rb @@ -0,0 +1,31 @@ +module OpenProject::PdfExport::TaskboardCard + class ColumnElement + def initialize(pdf, property_name, config, orientation, work_package) + @pdf = pdf + @property_name = property_name + @config = config + @orientation = orientation + @work_package = work_package + end + + def draw + # Get value from model + has_label = @config['has_label'] + + value = @work_package.send(@property_name) if @work_package.respond_to?(@property_name) + value = value.to_s + + text = "" + text = text + "#{@property_name}:- " if has_label + text = text + value + + # Draw on pdf + offset = [@orientation[:x_offset], @orientation[:y_offset]] + box = @pdf.text_box(text, + {:height => 20, + :at => offset, + :size => 20, + :padding_bottom => 5}) + end + end +end \ No newline at end of file diff --git a/lib/open_project/pdf_export/taskboard_card/document_generator.rb b/lib/open_project/pdf_export/taskboard_card/document_generator.rb index ec8a105f01..8ab11b822b 100644 --- a/lib/open_project/pdf_export/taskboard_card/document_generator.rb +++ b/lib/open_project/pdf_export/taskboard_card/document_generator.rb @@ -2,10 +2,13 @@ require 'prawn' module OpenProject::PdfExport::TaskboardCard class DocumentGenerator + attr_reader :config attr_reader :work_packages attr_reader :pdf attr_reader :current_position + attr_reader :paper_width + attr_reader :paper_height def initialize(config, work_packages) defaults = { page_size: "A4" } @@ -15,6 +18,9 @@ module OpenProject::PdfExport::TaskboardCard page_layout = :landscape page_size = config.page_size or defaults[:page_size] + geom = Prawn::Document::PageGeometry::SIZES[page_size] + @paper_width = geom[0] + @paper_height = geom[1] @pdf = Prawn::Document.new( :page_layout => page_layout, @@ -29,79 +35,41 @@ module OpenProject::PdfExport::TaskboardCard # TODO RS: Define pdf page defaults, sizes, borders etc... # pdf.start_new_page render_cards - pdf.render end def render_cards - # TESTING: RENDER FIRST WORK PACKAGE - render_rows(work_packages.first) - # TODO: Removed for testing convenience - # Iterate over all work packages - # work_packages.each_with_index do |wp, i| - # render_rows wp - # end - end - - def render_rows(work_package) - @current_position = { - y_offset: pdf.bounds.height, - x_offset: 0 + # TODO: This needs to be done for x cards per page and the appropriate offsets and bounds + # calculated for each. Just now doing the default 1 per page and only the first work package. + orientation = { + y_offset: pdf.bounds.height - 20, + x_offset: 20, + width: 400, # TODO: Calculate these based on page layout + height: 400 } - config.rows_hash["rows"].each do |key, value| - render_row(work_package, value) - adjust_current_position(value) - end + card_element = CardElement.new(pdf, orientation, config.rows_hash, work_packages.first) + card_element.draw end - def render_row(work_package, row_hash) - row_hash["columns"].each do |key, value| - render_column(work_package, key, value) - end - end - - def render_column(work_package, property_name, column_hash) - column = ColumnElement.new(pdf, work_package, property_name, column_hash) - column.draw(current_position) - end - - def adjust_current_position(row_config) - # The current position needs to be manipulated based on the minimun lines, font size and - # priority of the column. This will need to take into consideration all of the rows at once - # to decide on which ones get prioritised, and so will need something a lot more clever - # than just adjusting it inline like this. - current_position[:y_offset] -= (pdf.bounds.height * 0.05) - end + # def to_pts(v) + # return if v.nil? + # if v =~ /[a-z]{2}$/i + # units = v[-2, 2].downcase + # v = v[0..-3] + # else + # units = 'pt' + # end + + # v = "#{v}0" if v =~ /\.$/ + + # return Float(v).mm if units == 'mm' + # return Float(v).cm if units == 'cm' + # return Float(v).in if units == 'in' + # return Float(v).pt if units == 'pt' + # raise "Unexpected units '#{units}'" + # end end - class ColumnElement - def initialize(pdf, work_package, property_name, config) - @pdf = pdf - @work_package = work_package - @property_name = property_name - @config = config - end - - def draw(position) - # Get value from model - has_label = @config['has_label'] - - value = @work_package.send(@property_name) if @work_package.respond_to?(@property_name) - value = value.to_s - - text = "" - text = text + "#{@property_name}:- " if has_label - text = text + value - - # Draw on pdf - offset = [0, position[:y_offset]] - box = @pdf.text_box(text, - {:height => 20, - :at => offset, - :size => 20, - :padding_bottom => 5}) - end - end end \ No newline at end of file diff --git a/lib/open_project/pdf_export/taskboard_card/row_element.rb b/lib/open_project/pdf_export/taskboard_card/row_element.rb new file mode 100644 index 0000000000..650a5e543e --- /dev/null +++ b/lib/open_project/pdf_export/taskboard_card/row_element.rb @@ -0,0 +1,25 @@ +module OpenProject::PdfExport::TaskboardCard + class RowElement + def initialize(pdf, orientation, columns_config, work_package) + @pdf = pdf + @orientation = orientation + @columns_config = columns_config + @work_package = work_package + @column_elements = [] + + # Initialise column elements + columns_config.each do |key, value| + # TODO: Intelligently configure the orientation of column elements + column_orientation = @orientation + @column_elements << ColumnElement.new(@pdf, key, value, column_orientation, @work_package) + end + end + + def draw + # Draw columns + @column_elements.each do |c| + c.draw + end + end + end +end \ No newline at end of file