Introduced GroupElement class. Config syntax changed so that now rows have to be part of a group.

pull/6827/head
Richard 11 years ago
parent 07f1c58402
commit 115d7c4a2f
  1. 71
      lib/open_project/pdf_export/export_card/card_element.rb
  2. 48
      lib/open_project/pdf_export/export_card/group_element.rb
  3. 17
      lib/open_project/pdf_export/export_card/row_element.rb

@ -2,51 +2,69 @@ module OpenProject::PdfExport::ExportCard
class CardElement class CardElement
include OpenProject::PdfExport::Exceptions include OpenProject::PdfExport::Exceptions
def initialize(pdf, orientation, rows_config, work_package) def initialize(pdf, orientation, groups_config, work_package)
@pdf = pdf @pdf = pdf
@orientation = orientation @orientation = orientation
@rows_config = rows_config # @rows_config = rows_config
@groups_config = groups_config
@work_package = work_package @work_package = work_package
@row_elements = [] @group_elements = []
# TODO: This is redundant, the has should just be the rows # TODO: This is redundant, the has should just be the rows
# OR if we're going to have boxed groups then this is where they'd be # OR if we're going to have boxed groups then this is where they'd be
@rows = @rows_config["rows"] # @groups = @rows_config["rows"]
raise BadlyFormedExportCardConfigurationError.new("Badly formed YAML") if @rows.nil? # raise BadlyFormedExportCardConfigurationError.new("Badly formed YAML") if @rows.nil?
# Simpler to remove empty rows before calculating the row sizes # Simpler to remove empty rows before calculating the row sizes
RowElement.prune_empty_rows(@rows, work_package) RowElement.prune_empty_groups(@groups_config, work_package)
# Get an array of all the row hashes
rows = []
@groups_config.each do |gk, gv|
gv["rows"].each do |rk, rv|
rows << rv
end
end
# Assign the row height, ignoring groups
heights = assign_row_heights(rows)
heights = assign_row_heights
text_padding = @orientation[:text_padding] text_padding = @orientation[:text_padding]
current_row = 0
current_y_offset = text_padding current_y_offset = text_padding
@rows.each_with_index do |(key, value), i| # Initialize groups
current_y_offset += (heights[i - 1]) if i > 0 @groups_config.each_with_index do |(g_key, g_value), i|
row_orientation = { row_count = g_value["rows"].count
row_heights = heights.slice(current_row, row_count)
group_height = row_heights.sum
group_orientation = {
y_offset: @orientation[:height] - current_y_offset, y_offset: @orientation[:height] - current_y_offset,
x_offset: 0, x_offset: 0,
width: @orientation[:width], width: @orientation[:width],
height: heights[i], height: group_height,
row_heights: row_heights,
text_padding: text_padding text_padding: text_padding
} }
@group_elements << GroupElement.new(@pdf, group_orientation, g_value, @work_package)
@row_elements << RowElement.new(@pdf, row_orientation, value, @work_package) current_y_offset += group_height
current_row += row_count
end end
end end
def assign_row_heights def assign_row_heights(rows)
# Assign initial heights # Assign initial heights for rows in all groups
available = @orientation[:height] - @orientation[:text_padding] available = @orientation[:height] - @orientation[:text_padding]
c = @rows.count c = rows.count
assigned_heights = Array.new(c){ available / c } assigned_heights = Array.new(c){ available / c }
min_heights = min_row_heights(c) min_heights = min_row_heights(rows)
diffs = assigned_heights.zip(min_heights).map {|a, m| a - m} diffs = assigned_heights.zip(min_heights).map {|a, m| a - m}
diffs.each_with_index do |diff, i| diffs.each_with_index do |diff, i|
if diff < 0 if diff < 0
# Need to grab some pixels from a low priority row and add them to current one # Need to grab some pixels from a low priority row and add them to current one
reduce_low_priority_rows(assigned_heights, diffs, i) reduce_low_priority_rows(rows, assigned_heights, diffs, i)
end end
end end
@ -54,10 +72,11 @@ module OpenProject::PdfExport::ExportCard
assigned_heights assigned_heights
end end
def reduce_low_priority_rows(assigned_heights, diffs, conflicted_i) def reduce_low_priority_rows(rows, assigned_heights, diffs, conflicted_i)
# Get an array of row indexes sorted by inverse priority # Get an array of row indexes sorted by inverse priority
priorities = *(0..@rows_config["rows"].count - 1) # TODO RS: The priority should be on the row, not the column
.zip(@rows_config["rows"].map { |k, v| first_column_property(v, "priority") or 10 }) priorities = *(0..rows.count - 1)
.zip(rows.map { |k, v| first_column_property(v, "priority") or 10 })
.sort {|x,y| y[1] <=> x[1]} .sort {|x,y| y[1] <=> x[1]}
.map {|x| x[0]} .map {|x| x[0]}
@ -89,12 +108,12 @@ module OpenProject::PdfExport::ExportCard
diffs[b] += v diffs[b] += v
end end
def min_row_heights(c) def min_row_heights(rows)
# Calculate minimum user assigned heights... # Calculate minimum user assigned heights...
min_heights = Array.new(c) min_heights = Array.new(rows.count)
@rows_config["rows"].each_with_index do |(key, value), i| rows.each_with_index do |row, i|
# min lines * font height (first col) # TODO: get the biggest one # min lines * font height (first col) # TODO: get the biggest one
k, v = value["columns"].first k, v = row["columns"].first
min_lines = v["minimum_lines"] min_lines = v["minimum_lines"]
min_lines ||= 1 min_lines ||= 1
font_size = v["font_size"] font_size = v["font_size"]
@ -112,8 +131,8 @@ module OpenProject::PdfExport::ExportCard
@pdf.stroke_color '000000' @pdf.stroke_color '000000'
# Draw rows # Draw rows
@row_elements.each do |row| @group_elements.each do |group|
row.draw group.draw
end end
@pdf.stroke_bounds @pdf.stroke_bounds

@ -0,0 +1,48 @@
module OpenProject::PdfExport::ExportCard
class GroupElement
include OpenProject::PdfExport::Exceptions
def initialize(pdf, orientation, config, work_package)
@pdf = pdf
@orientation = orientation
@config = config
@rows_config = config["rows"]
@work_package = work_package
@row_elements = []
current_y_offset = 0 # OR text padding?
row_heights = @orientation[:row_heights]
@rows_config.each_with_index do |(r_key, r_value), i|
current_y_offset += (row_heights[i - 1]) if i > 0
row_orientation = {
y_offset: @orientation[:height] - current_y_offset,
x_offset: 0,
width: @orientation[:width],
height: row_heights[i],
text_padding: @orientation[:text_padding]
}
@row_elements << RowElement.new(@pdf, row_orientation, r_value, @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 '000000'
# Draw rows
@row_elements.each do |row|
row.draw
end
@pdf.stroke_bounds
end
end
end
end

@ -52,8 +52,23 @@ module OpenProject::PdfExport::ExportCard
end end
def self.prune_empty_groups(groups, wp)
# Prune rows in groups
groups.each do |gk, gv|
self.prune_empty_rows(gv["rows"], wp)
end
# Prune empty groups
groups.each do |gk, gv|
if gv["rows"].count == 0
groups.delete(gk)
end
end
end
def self.prune_empty_rows(rows, wp) def self.prune_empty_rows(rows, wp)
rows.each_with_index do |(rk, rv), i| rows.each do |rk, rv|
# TODO RS: This is still only checking the first column, need to check all
ck, cv = rv["columns"].first ck, cv = rv["columns"].first
if is_empty_column(ck, cv, wp) if is_empty_column(ck, cv, wp)
rows.delete(rk) rows.delete(rk)

Loading…
Cancel
Save