commit
54f81f7888
@ -0,0 +1,32 @@ |
||||
|
||||
class RbExportCardConfigurationsController < RbApplicationController |
||||
unloadable |
||||
include OpenProject::PdfExport::ExportCard |
||||
|
||||
before_filter :load_project_and_sprint |
||||
|
||||
def index |
||||
@configs = ExportCardConfiguration.active |
||||
end |
||||
|
||||
def show |
||||
config = ExportCardConfiguration.find(params[:id]) |
||||
|
||||
cards_document = OpenProject::PdfExport::ExportCard::DocumentGenerator.new(config, @sprint.stories(@project)) |
||||
|
||||
filename = "#{@project.to_s}-#{@sprint.to_s}-#{Time.now.strftime("%B-%d-%Y")}.pdf" |
||||
respond_to do |format| |
||||
format.pdf { send_data(cards_document.render, |
||||
:disposition => 'attachment', |
||||
:type => 'application/pdf', |
||||
:filename => filename) } |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def load_project_and_sprint |
||||
@project = Project.find(params[:project_id]) |
||||
@sprint = Sprint.find(params[:sprint_id]) |
||||
end |
||||
end |
@ -0,0 +1,16 @@ |
||||
|
||||
<div class='contextual'></div> |
||||
<h2> |
||||
<%= l(:label_backlogs_export_card_config_select) %> |
||||
</h2> |
||||
|
||||
<% @configs.each do |config| %> |
||||
<%= link_to(config.name, |
||||
:controller => '/rb_export_card_configurations', |
||||
:action => 'show', |
||||
:project_id => @project.id, |
||||
:sprint_id => @sprint.id, |
||||
:id => config.id, |
||||
:format => :pdf) %> |
||||
<br> |
||||
<% end %> |
@ -0,0 +1,103 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
Feature: Export sprint stories as PDF on the Backlogs view |
||||
As a team member |
||||
I want to export stories as a PDF on the scrum backlogs view |
||||
So that I do not loose context while filling in details |
||||
|
||||
Background: |
||||
Given there is 1 project with: |
||||
| name | ecookbook | |
||||
And I am working in project "ecookbook" |
||||
And the project uses the following modules: |
||||
| backlogs | |
||||
And the following types are configured to track stories: |
||||
| Story | |
||||
| Epic | |
||||
| Bug | |
||||
And the type "Task" is configured to track tasks |
||||
And the project uses the following types: |
||||
| Story | |
||||
| Bug | |
||||
| Task | |
||||
And there is 1 user with: |
||||
| login | mathias | |
||||
And there is a role "team member" |
||||
And the role "team member" may have the following rights: |
||||
| view_master_backlog | |
||||
| create_stories | |
||||
| update_stories | |
||||
| view_work_packages | |
||||
| edit_work_packages | |
||||
| add_work_packages | |
||||
| manage_subtasks | |
||||
And the user "mathias" is a "team member" |
||||
And the project has the following sprints: |
||||
| name | start_date | effective_date | |
||||
| Sprint 001 | 2010-01-01 | 2010-01-31 | |
||||
And there are the following issue status: |
||||
| name | is_closed | is_default | |
||||
| New | false | true | |
||||
| In Progress | false | false | |
||||
| Resolved | false | false | |
||||
| Closed | true | false | |
||||
| Rejected | true | false | |
||||
And the type "Story" has the default workflow for the role "team member" |
||||
And there is a default issuepriority with: |
||||
| name | Normal | |
||||
And the project has the following stories in the following sprints: |
||||
| subject | sprint | story_points | |
||||
| Story A | Sprint 001 | 10 | |
||||
| Story B | Sprint 001 | 20 | |
||||
And I am already logged in as "mathias" |
||||
|
||||
@javascript |
||||
Scenario: Export sprint stories as a PDF using the default configuration |
||||
Given there is the single default export card configuration |
||||
And I am on the master backlog |
||||
When I open the "Sprint 001" backlogs menu |
||||
And I follow "Export" of the "Sprint 001" backlogs menu |
||||
Then the PDF download dialog should be displayed |
||||
|
||||
@javascript |
||||
Scenario: Export sprint stories as a PDF using a selected configuration |
||||
Given there are multiple export card configurations |
||||
And I am on the master backlog |
||||
When I open the "Sprint 001" backlogs menu |
||||
And I follow "Export" of the "Sprint 001" backlogs menu |
||||
And I should see a modal window |
||||
And I click on the link on the modal window with text "Custom 2" |
||||
Then the PDF download dialog should be displayed |
@ -1,37 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
end |
@ -1,132 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class BottomAttributes < CardArea |
||||
unloadable |
||||
|
||||
include Redmine::I18n |
||||
|
||||
class << self |
||||
def min_size_total |
||||
[500, 200] |
||||
end |
||||
|
||||
def pref_size_percent |
||||
[1.0, 0.3] |
||||
end |
||||
|
||||
def margin |
||||
9 |
||||
end |
||||
|
||||
def render(pdf, work_package, options) |
||||
render_bounding_box(pdf, options.merge(:border => true, :margin => margin)) do |
||||
|
||||
category_box = render_category(pdf, work_package, {:at => [0, pdf.bounds.height], |
||||
:align => :right}) |
||||
|
||||
assigned_to_box = render_assigned_to(pdf, work_package, {:at => [0, category_box.y], |
||||
:width => pdf.bounds.width - category_box.width, |
||||
:padding_bottom => 20}) |
||||
|
||||
render_sub_work_packages(pdf, work_package, {:at => [0, assigned_to_box.y - assigned_to_box.height]}) |
||||
end |
||||
end |
||||
|
||||
|
||||
def render_assigned_to(pdf, work_package, options) |
||||
|
||||
assigned_to = "#{WorkPackage.human_attribute_name(:assigned_to)}: #{work_package.assigned_to ? work_package.assigned_to : "-"}" |
||||
|
||||
text_box(pdf, |
||||
assigned_to, |
||||
{:width => pdf.bounds.width, |
||||
:height => 12, |
||||
:size => 12}.merge(options)) |
||||
end |
||||
|
||||
def render_category(pdf, work_package, options) |
||||
|
||||
category = "#{WorkPackage.human_attribute_name(:category)}: #{work_package.category ? work_package.category : "-"}" |
||||
|
||||
text_box(pdf, |
||||
category, |
||||
{:width => pdf.bounds.width, |
||||
:height => 12}.merge(options)) |
||||
|
||||
end |
||||
|
||||
def render_sub_work_packages(pdf, work_package, options) |
||||
at = options.delete(:at) |
||||
box = Box.new(at[0], at[1], 0, 0) |
||||
|
||||
pdf.font_size(12) do |
||||
temp_box = text_box(pdf, |
||||
"#{l(:label_subtask_plural)}: #{work_package.children.size == 0 ? "-" : ""}", |
||||
{:height => pdf.font.height, |
||||
:at => box.at, |
||||
:paddint_bottom => 6}) |
||||
|
||||
box.height += temp_box.height |
||||
box.width = temp_box.width |
||||
|
||||
work_package.children.each_with_index do |child, i| |
||||
|
||||
if box.height + pdf.font.height > pdf.font.height || work_package.children.size - i == 1 |
||||
temp_box = text_box(pdf, |
||||
"#{child.type.name} ##{child.id}: #{child.subject}", |
||||
{:height => pdf.font.height, |
||||
:at => [10, at[1] - box.height], |
||||
:padding_bottom => 3}) |
||||
else |
||||
temp_box = text_box(pdf, |
||||
l('backlogs.x_more', :count => work_package.children.size - i), |
||||
:height => pdf.font.height, |
||||
:at => [10, at[1] - box.height]) |
||||
break |
||||
end |
||||
|
||||
box.height += temp_box.height |
||||
end |
||||
end |
||||
|
||||
box |
||||
end |
||||
|
||||
end |
||||
|
||||
end |
||||
end |
@ -1,69 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class Card < CardArea |
||||
unloadable |
||||
|
||||
include Redmine::I18n |
||||
|
||||
class << self |
||||
def areas |
||||
[OpenProject::Backlogs::TaskboardCard::Header, |
||||
OpenProject::Backlogs::TaskboardCard::TopAttributes, |
||||
OpenProject::Backlogs::TaskboardCard::Description, |
||||
OpenProject::Backlogs::TaskboardCard::BottomAttributes |
||||
] |
||||
end |
||||
|
||||
def margin |
||||
20 |
||||
end |
||||
|
||||
def render(pdf, work_package, options) |
||||
render_bounding_box(pdf, options.merge(:border => true, :margin => margin)) do |
||||
y_offset = pdf.bounds.height |
||||
|
||||
Card.areas.each do |card| |
||||
height = pdf.bounds.height * card.pref_size_percent[1] |
||||
card.render(pdf, work_package, {:at => [0, y_offset], |
||||
:height => height}) |
||||
y_offset -= height + pdf.bounds.height * 0.01 |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,120 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class CardArea |
||||
unloadable |
||||
|
||||
def self.pref_size_percent |
||||
raise NotImplementedError.new('Subclasses need to implement this methods') |
||||
end |
||||
|
||||
def self.text_box(pdf, text, options) |
||||
options = adapted_text_box_options(pdf, text, options) |
||||
text = abbreviate_text(pdf, text, options) |
||||
|
||||
pdf.text_box(text, options) |
||||
|
||||
Box.new(options[:at][0], options[:at][1], options[:width], options[:height] + options[:padding_bottom]) |
||||
end |
||||
|
||||
def self.render_bounding_box(pdf, options) |
||||
opts = { :width => pdf.bounds.width } |
||||
offset = options[:at] || [0, pdf.bounds.height] |
||||
|
||||
pdf.bounding_box(offset, opts.merge(options)) do |
||||
|
||||
pdf.stroke_bounds if options[:border] |
||||
|
||||
if options[:margin] |
||||
pdf.bounding_box([options[:margin], pdf.bounds.height - options[:margin]], |
||||
:width => pdf.bounds.width - (2 * options[:margin]), |
||||
:height => pdf.bounds.height - (2 * options[:margin])) do |
||||
|
||||
yield |
||||
end |
||||
else |
||||
yield |
||||
end |
||||
end |
||||
end |
||||
|
||||
def self.min_size |
||||
[0, 0] |
||||
end |
||||
|
||||
def self.margin |
||||
0 |
||||
end |
||||
|
||||
def self.render(pdf, work_package, offset) |
||||
raise NotImplementedError.new('Subclasses need to implement this methods') |
||||
end |
||||
|
||||
def self.strip_tags(string) |
||||
ActionController::Base.helpers.strip_tags(string) |
||||
end |
||||
|
||||
private |
||||
|
||||
def self.adapted_text_box_options(pdf, text, options) |
||||
align = options.delete(:align) |
||||
if align == :right |
||||
options[:width] = pdf.width_of(text, options) |
||||
options[:at][0] = pdf.bounds.width - options[:width] |
||||
end |
||||
|
||||
opts = {:width => pdf.bounds.width, |
||||
:padding_bottom => 10, |
||||
:document => pdf} |
||||
|
||||
opts.merge(options) |
||||
end |
||||
|
||||
def self.abbreviate_text(pdf, text, options) |
||||
text_box = Prawn::Text::Box.new(text, options) |
||||
left_over = text_box.render(:dry_run => true) |
||||
|
||||
# Be sure to do length arithmetics on chars, not bytes! |
||||
left_over = left_over.mb_chars |
||||
text = text.to_s.mb_chars |
||||
|
||||
text = left_over.size > 0 ? text[0 ... -(left_over.size + 5)] + "[...]" : text |
||||
text.to_s |
||||
rescue Prawn::Errors::CannotFit |
||||
'' |
||||
end |
||||
end |
||||
end |
@ -1,73 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class Description < CardArea |
||||
unloadable |
||||
|
||||
include Redmine::I18n |
||||
|
||||
class << self |
||||
def min_size_total |
||||
[500, 300] |
||||
end |
||||
|
||||
def pref_size_percent |
||||
[1.0, 0.5] |
||||
end |
||||
|
||||
def margin |
||||
9 |
||||
end |
||||
|
||||
def render(pdf, work_package, options) |
||||
render_bounding_box(pdf, options.merge(:border => true, :margin => margin)) do |
||||
description = work_package.description ? work_package.description : "" |
||||
|
||||
r = RedCloth3.new(description) |
||||
line = r.to_html |
||||
line = Description.strip_tags(line) |
||||
|
||||
text_box(pdf, |
||||
line, |
||||
{:height => pdf.bounds.height, |
||||
:at => [0, pdf.bounds.height], |
||||
:size => 20, |
||||
:padding_bottom => 0}) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,163 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'prawn' |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class Document |
||||
unloadable |
||||
|
||||
include Redmine::I18n |
||||
include Measurement |
||||
|
||||
attr_reader :pdf |
||||
attr_reader :paper_width |
||||
attr_reader :paper_height |
||||
attr_reader :top_margin |
||||
attr_reader :vertical_pitch |
||||
attr_reader :height |
||||
attr_reader :left_margin |
||||
attr_reader :inner_margin |
||||
attr_reader :horizontal_pitch |
||||
attr_reader :width |
||||
attr_reader :across |
||||
attr_reader :down |
||||
attr_reader :work_packages |
||||
|
||||
def initialize(lang) |
||||
set_language_if_valid lang |
||||
|
||||
raise "No label stock selected" unless Setting.plugin_openproject_backlogs["card_spec"] |
||||
label = PageLayout.selected_label |
||||
raise "Label stock \"#{Setting.plugin_openproject_backlogs["card_spec"]}\" not found" unless label |
||||
|
||||
label['papersize'].upcase! |
||||
|
||||
geom = Prawn::Document::PageGeometry::SIZES[label['papersize']] |
||||
raise "Paper size '#{label['papersize']}' not supported" if geom.nil? |
||||
|
||||
page_layout = :landscape |
||||
|
||||
if page_layout == :portrait |
||||
@paper_width = geom[0] |
||||
@paper_height = geom[1] |
||||
@top_margin = Document.to_pts(label['top_margin']) |
||||
@vertical_pitch = Document.to_pts(label['vertical_pitch']) |
||||
@height = Document.to_pts(label['height']) |
||||
|
||||
@left_margin = Document.to_pts(label['left_margin']) |
||||
@horizontal_pitch = Document.to_pts(label['horizontal_pitch']) |
||||
@width = Document.to_pts(label['width']) |
||||
else |
||||
@paper_width = geom[1] |
||||
@paper_height = geom[0] |
||||
@left_margin = Document.to_pts(label['top_margin']) |
||||
@horizontal_pitch = Document.to_pts(label['vertical_pitch']) |
||||
@width = Document.to_pts(label['height']) |
||||
|
||||
@top_margin = Document.to_pts(label['left_margin']) |
||||
@vertical_pitch = Document.to_pts(label['horizontal_pitch']) |
||||
@height = Document.to_pts(label['width']) |
||||
end |
||||
|
||||
@across = label['across'] |
||||
@down = label['down'] |
||||
|
||||
@inner_margin = Document.to_pts(label['inner_margin']) || 1.mm |
||||
|
||||
@pdf = Prawn::Document.new( |
||||
:page_layout => page_layout, |
||||
:left_margin => 0, |
||||
:right_margin => 0, |
||||
:top_margin => 0, |
||||
:bottom_margin => 0, |
||||
:page_size => label['papersize']) |
||||
|
||||
fontdir = File.dirname(__FILE__) + '/ttf' |
||||
@pdf.font_families.update( |
||||
"DejaVuSans" => { |
||||
:bold => "#{fontdir}/DejaVuSans-Bold.ttf", |
||||
:italic => "#{fontdir}/DejaVuSans-Oblique.ttf", |
||||
:bold_italic => "#{fontdir}/DejaVuSans-BoldOblique.ttf", |
||||
:normal => "#{fontdir}/DejaVuSans.ttf" |
||||
} |
||||
) |
||||
@pdf.font "DejaVuSans" |
||||
|
||||
@work_packages = [] |
||||
end |
||||
|
||||
def add_story(story, add_tasks = true) |
||||
add_work_package(story) |
||||
|
||||
if add_tasks |
||||
story.tasks.each do |task| |
||||
add_work_package(task) |
||||
end |
||||
end |
||||
end |
||||
|
||||
def render |
||||
render_cards |
||||
self.pdf.render |
||||
end |
||||
|
||||
private |
||||
|
||||
def add_work_package(story) |
||||
self.work_packages << story |
||||
end |
||||
|
||||
def render_cards |
||||
self.work_packages.each_with_index do |work_package, i| |
||||
row = (i % self.down) + 1 |
||||
col = ((i / self.down) % self.across) + 1 |
||||
|
||||
self.pdf.start_new_page if row == 1 and col == 1 and i != 0 |
||||
|
||||
Card.render(pdf, work_package, {:height => self.height, |
||||
:width => self.width, |
||||
:at => card_top_left(row, col)}) |
||||
end |
||||
end |
||||
|
||||
def card_top_left(row, col) |
||||
top = self.paper_height - (self.top_margin + self.vertical_pitch * (row - 1)) |
||||
left = self.left_margin + (self.horizontal_pitch * (col - 1)) |
||||
|
||||
[left, top] |
||||
end |
||||
end |
||||
end |
@ -1,69 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class Header < CardArea |
||||
unloadable |
||||
|
||||
def self.min_size_total |
||||
[500, 50] |
||||
end |
||||
|
||||
def self.pref_size_percent |
||||
[1.0, 0.05] |
||||
end |
||||
|
||||
def self.render(pdf, work_package, options) |
||||
render_bounding_box(pdf, options) do |
||||
|
||||
offset = [0, pdf.bounds.height] |
||||
|
||||
work_package_identification = "#{work_package.type.name} ##{work_package.id}" |
||||
|
||||
box = text_box(pdf, |
||||
work_package_identification, |
||||
{:height => 20, |
||||
:at => offset, |
||||
:size => 20, |
||||
:padding_bottom => 5}) |
||||
|
||||
offset[1] -= box.height |
||||
pdf.line offset, [pdf.bounds.width, offset[1]] |
||||
end |
||||
|
||||
end |
||||
|
||||
end |
||||
end |
@ -1,66 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'prawn/measurement_extensions' |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
module Measurement |
||||
def self.included(base) |
||||
base.extend(ClassMethods) |
||||
end |
||||
|
||||
|
||||
module ClassMethods |
||||
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 |
||||
end |
||||
end |
@ -1,200 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'net/http' |
||||
require 'rexml/document' |
||||
|
||||
require 'yaml' |
||||
require 'uri/common' |
||||
|
||||
require 'prawn' |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class PageLayout |
||||
unloadable |
||||
|
||||
include Measurement |
||||
|
||||
LABELS_FILE_NAME = File.join(File.dirname(__FILE__), '../../../..', 'config', 'labels.yml') |
||||
MALFORMED_LABELS_FILE_NAME = File.join(File.dirname(__FILE__), '../../../..', 'config', 'labels-malformed.yml') |
||||
|
||||
if File.exist? LABELS_FILE_NAME |
||||
LABELS = YAML::load_file(LABELS_FILE_NAME) |
||||
else |
||||
puts "Using default card label dimensions. Be sure to run " + |
||||
"`rake redmine:backlogs:current_labels` to get current definitions " + |
||||
"from git.gnome.org." |
||||
LABELS = YAML::load_file(LABELS_FILE_NAME + '.default') |
||||
end |
||||
|
||||
class << self |
||||
def available? |
||||
selected_label.present? |
||||
end |
||||
|
||||
def selected_label |
||||
LABELS[Setting.plugin_openproject_backlogs["card_spec"]] |
||||
end |
||||
|
||||
def measurement(x) |
||||
x = "#{x}pt" if x =~ /[0-9]$/ |
||||
x |
||||
end |
||||
|
||||
def malformed?(label) |
||||
to_pts(label['height']) > to_pts(label['vertical_pitch']) || |
||||
to_pts(label['width']) > to_pts(label['horizontal_pitch']) |
||||
end |
||||
|
||||
def fetch_labels |
||||
LABELS.clear |
||||
|
||||
malformed_labels = {} |
||||
|
||||
fetched_templates.each do |filename| |
||||
uri = URI.parse("http://git.gnome.org/browse/glabels/plain/templates/#{filename}") |
||||
labels = nil |
||||
|
||||
if ENV['http_proxy'].present? |
||||
begin |
||||
proxy = URI.parse(ENV['http_proxy']) |
||||
if proxy.userinfo |
||||
user, pass = proxy.userinfo.split(/:/) |
||||
else |
||||
user = pass = nil |
||||
end |
||||
labels = Net::HTTP::Proxy(proxy.host, proxy.port, user, pass).start(uri.host) {|http| http.get(uri.path)}.body |
||||
rescue URI::Error => e |
||||
puts "Setup proxy failed: #{e}" |
||||
labels = nil |
||||
end |
||||
end |
||||
|
||||
begin |
||||
labels = Net::HTTP.get_response(uri).body if labels.nil? |
||||
rescue |
||||
labels = nil |
||||
end |
||||
|
||||
if labels.nil? |
||||
puts "Could not fetch #{filename}" |
||||
next |
||||
end |
||||
|
||||
doc = REXML::Document.new(labels) |
||||
|
||||
doc.elements.each('Glabels-templates/Template') do |specs| |
||||
label = nil |
||||
|
||||
papersize = specs.attributes['size'] |
||||
papersize = 'Letter' if papersize == 'US-Letter' |
||||
|
||||
specs.elements.each('Label-rectangle') do |geom| |
||||
margin = nil |
||||
geom.elements.each('Markup-margin') do |m| |
||||
margin = m.attributes['size'] |
||||
end |
||||
margin = "1mm" if margin.blank? |
||||
|
||||
geom.elements.each('Layout') do |layout| |
||||
label = { |
||||
'inner_margin' => PageLayout.measurement(margin), |
||||
'across' => Integer(layout.attributes['nx']), |
||||
'down' => Integer(layout.attributes['ny']), |
||||
'top_margin' => PageLayout.measurement(layout.attributes['y0']), |
||||
'height' => PageLayout.measurement(geom.attributes['height']), |
||||
'horizontal_pitch' => PageLayout.measurement(layout.attributes['dx']), |
||||
'left_margin' => PageLayout.measurement(layout.attributes['x0']), |
||||
'width' => PageLayout.measurement(geom.attributes['width']), |
||||
'vertical_pitch' => PageLayout.measurement(layout.attributes['dy']), |
||||
'papersize' => papersize, |
||||
'source' => 'glabel' |
||||
} |
||||
end |
||||
end |
||||
|
||||
next if label.nil? || label['across'] != 1 || label['down'] != 1 || label['papersize'].downcase == 'other' |
||||
|
||||
key = "#{specs.attributes['brand']} #{specs.attributes['part']}" |
||||
|
||||
if PageLayout.malformed?(label) |
||||
puts "Skipping malformed label '#{key}' from #{filename}" |
||||
malformed_labels[key] = label |
||||
else |
||||
LABELS[key] = label if not LABELS[key] or LABELS[key]['source'] == 'glabel' |
||||
|
||||
specs.elements.each('Alias') do |also| |
||||
key = "#{also.attributes['brand']} #{also.attributes['part']}" |
||||
LABELS[key] = label.dup if not LABELS[key] or LABELS[key]['source'] == 'glabel' |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
File.open(LABELS_FILE_NAME, 'w') do |dump| |
||||
YAML.dump(LABELS, dump) |
||||
end |
||||
File.open(MALFORMED_LABELS_FILE_NAME, 'w') do |dump| |
||||
YAML.dump(malformed_labels, dump) |
||||
end |
||||
|
||||
if Setting.plugin_openproject_backlogs["card_spec"] && ! PageLayout.selected_label && LABELS.size != 0 |
||||
# current label non-existant |
||||
label = LABELS.keys[0] |
||||
puts "Non-existant label stock '#{Setting.plugin_openproject_backlogs["card_spec"]}' selected, replacing with random '#{label}'" |
||||
s = Setting.plugin_openproject_backlogs |
||||
s["card_spec"] = label |
||||
Setting.plugin_openproject_backlogs = s |
||||
end |
||||
end |
||||
|
||||
def fetched_templates |
||||
['avery-iso-templates.xml', |
||||
'avery-other-templates.xml', |
||||
'avery-us-templates.xml', |
||||
'brother-other-templates.xml', |
||||
'dymo-other-templates.xml', |
||||
'maco-us-templates.xml', |
||||
'misc-iso-templates.xml', |
||||
'misc-other-templates.xml', |
||||
'misc-us-templates.xml', |
||||
'pearl-iso-templates.xml', |
||||
'uline-us-templates.xml', |
||||
'worldlabel-us-templates.xml', |
||||
'zweckform-iso-templates.xml'] |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,109 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module OpenProject::Backlogs::TaskboardCard |
||||
class TopAttributes < CardArea |
||||
unloadable |
||||
include Redmine::I18n |
||||
|
||||
class << self |
||||
def min_size_total |
||||
[500, 100] |
||||
end |
||||
|
||||
def pref_size_percent |
||||
[1.0, 0.1] |
||||
end |
||||
|
||||
def margin |
||||
9 |
||||
end |
||||
|
||||
def render(pdf, work_package, options) |
||||
render_bounding_box(pdf, options.merge(:border => true, :margin => margin)) do |
||||
|
||||
sprint_box = render_sprint(pdf, work_package, {:at => [0, pdf.bounds.height], |
||||
:align => :right}) |
||||
|
||||
render_parent_work_package(pdf, work_package, {:at => [0, sprint_box.y], |
||||
:width => pdf.bounds.width - sprint_box.width}) |
||||
|
||||
effort_box = render_effort(pdf, work_package, {:at => [0, pdf.bounds.height - sprint_box.height], |
||||
:align => :right}) |
||||
|
||||
render_subject(pdf, work_package, {:at => [0, effort_box.y], |
||||
:width => pdf.bounds.width - effort_box.width}) |
||||
end |
||||
end |
||||
|
||||
def render_parent_work_package(pdf, work_package, options) |
||||
parent_name = work_package.parent.present? ? "#{work_package.parent.type.name} ##{work_package.parent.id}: #{work_package.parent.subject}" : "" |
||||
|
||||
text_box(pdf, |
||||
parent_name, |
||||
{:height => 12, |
||||
:size => 12}.merge(options)) |
||||
end |
||||
|
||||
def render_sprint(pdf, work_package, options) |
||||
name = work_package.fixed_version ? work_package.fixed_version.name : "-" |
||||
|
||||
text_box(pdf, |
||||
name, |
||||
{:height => 12, |
||||
:size => 12}.merge(options)) |
||||
end |
||||
|
||||
def render_subject(pdf, work_package, options) |
||||
text_box(pdf, |
||||
work_package.subject, |
||||
{:height => 20, |
||||
:size => 20}.merge(options)) |
||||
end |
||||
|
||||
def render_effort(pdf, work_package, options) |
||||
type = work_package.is_task? |
||||
score = (type == :task ? work_package.estimated_hours : work_package.story_points) |
||||
score ||= '-' |
||||
score = "#{score} #{type == :task ? l(:label_hours) : l(:label_points)}" |
||||
|
||||
text_box(pdf, |
||||
score, |
||||
{:height => 20, |
||||
:size => 20}.merge(options)) |
||||
end |
||||
end |
||||
end |
||||
end |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,81 +0,0 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject Backlogs Plugin |
||||
# |
||||
# Copyright (C)2013 the OpenProject Foundation (OPF) |
||||
# Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda |
||||
# Copyright (C)2010-2011 friflaj |
||||
# Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns |
||||
# Copyright (C)2009-2010 Mark Maglana |
||||
# Copyright (C)2009 Joe Heck, Nate Lowrie |
||||
# |
||||
# This program is free software; you can redistribute it and/or modify it under |
||||
# the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject Backlogs is a derivative work based on ChiliProject Backlogs. |
||||
# The copyright follows: |
||||
# Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj |
||||
# Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') |
||||
|
||||
describe OpenProject::Backlogs::TaskboardCard::CardArea do |
||||
let(:pdf) { Prawn::Document.new(:margin => 0) } |
||||
|
||||
let(:options) do |
||||
{ |
||||
:width => 120.0, |
||||
:height => 12, |
||||
:size => 12, |
||||
:at => [0, 0], |
||||
:single_line => true |
||||
} |
||||
end |
||||
|
||||
describe '.text_box' do |
||||
it 'shortens long texts' do |
||||
box = OpenProject::Backlogs::TaskboardCard::CardArea.text_box(pdf, |
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', |
||||
options) |
||||
|
||||
text = PDF::Inspector::Text.analyze(pdf.render) |
||||
|
||||
text.strings.join.should == 'Lorem ipsum dolor[...]' |
||||
end |
||||
|
||||
it 'does not shorten short texts' do |
||||
box = OpenProject::Backlogs::TaskboardCard::CardArea.text_box(pdf, 'Lorem ipsum', options) |
||||
|
||||
text = PDF::Inspector::Text.analyze(pdf.render) |
||||
|
||||
text.strings.join.should == 'Lorem ipsum' |
||||
end |
||||
|
||||
it 'handles multibyte characters gracefully' do |
||||
box = OpenProject::Backlogs::TaskboardCard::CardArea.text_box(pdf, |
||||
'Lörëm ïpsüm dölör sït ämët, cönsëctëtür ädïpïscïng ëlït.', |
||||
options) |
||||
|
||||
text = PDF::Inspector::Text.analyze(pdf.render) |
||||
|
||||
text.strings.join.should == 'Lörëm ïpsüm dölör[...]' |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,84 @@ |
||||
|
||||
require File.dirname(__FILE__) + '/../../spec_helper' |
||||
|
||||
describe 'rb_master_backlogs/index' do |
||||
let(:user) { FactoryGirl.create(:user) } |
||||
let(:role_allowed) { FactoryGirl.create(:role, |
||||
:permissions => [:view_master_backlog, :view_taskboards]) |
||||
} |
||||
let(:statuses) { [FactoryGirl.create(:status, is_default: true), |
||||
FactoryGirl.create(:status), |
||||
FactoryGirl.create(:status)] } |
||||
let(:type_task) { FactoryGirl.create(:type_task) } |
||||
let(:type_feature) { FactoryGirl.create(:type_feature) } |
||||
let(:issue_priority) { FactoryGirl.create(:priority) } |
||||
let(:project) do |
||||
project = FactoryGirl.create(:project, :types => [type_feature, type_task]) |
||||
project.members = [FactoryGirl.create(:member, :principal => user,:project => project,:roles => [role_allowed])] |
||||
project |
||||
end |
||||
let(:story_a) { FactoryGirl.create(:story, :status => statuses[0], |
||||
:project => project, |
||||
:type => type_feature, |
||||
:fixed_version => sprint, |
||||
:priority => issue_priority |
||||
)} |
||||
let(:story_b) { FactoryGirl.create(:story, :status => statuses[1], |
||||
:project => project, |
||||
:type => type_feature, |
||||
:fixed_version => sprint, |
||||
:priority => issue_priority |
||||
)} |
||||
let(:story_c) { FactoryGirl.create(:story, :status => statuses[2], |
||||
:project => project, |
||||
:type => type_feature, |
||||
:fixed_version => sprint, |
||||
:priority => issue_priority |
||||
)} |
||||
let(:stories) { [story_a, story_b, story_c] } |
||||
let(:sprint) { FactoryGirl.create(:sprint, :project => project) } |
||||
|
||||
before :each do |
||||
Setting.stub(:plugin_openproject_backlogs).and_return({"story_types" => [type_feature.id], "task_type" => type_task.id}) |
||||
view.extend RbCommonHelper |
||||
view.extend RbMasterBacklogsHelper |
||||
view.stub(:current_user).and_return(user) |
||||
|
||||
assign(:project, project) |
||||
assign(:sprint, sprint) |
||||
assign(:owner_backlogs, Backlog.owner_backlogs(project)) |
||||
assign(:sprint_backlogs, Backlog.sprint_backlogs(project)) |
||||
|
||||
User.stub(:current).and_return(user) |
||||
|
||||
# We directly force the creation of stories by calling the method |
||||
stories |
||||
end |
||||
|
||||
it 'shows link to export with the default export card configuration' do |
||||
default_export_card_config = FactoryGirl.create(:export_card_configuration) |
||||
assign(:export_card_config_meta, { |
||||
default: default_export_card_config, |
||||
count: 1}) |
||||
|
||||
render |
||||
|
||||
assert_select ".menu ul.items a" do |a| |
||||
url = backlogs_project_sprint_export_card_configuration_path(project.identifier, sprint.id, default_export_card_config.id, format: :pdf) |
||||
a.last.should have_content 'Export' |
||||
a.last.should have_css("a[href='#{url}']") |
||||
end |
||||
end |
||||
|
||||
it 'shows link to display export card configuration choice modal' do |
||||
assign(:export_card_config_meta, { count: 2 }) |
||||
render |
||||
|
||||
assert_select ".menu ul.items a" do |a| |
||||
url = backlogs_project_sprint_export_card_configurations_path(project.id, sprint.id) |
||||
a.last.should have_content 'Export' |
||||
a.last.should have_css("a[href='#{url}']") |
||||
a.last.should have_css("a[data-modal]") |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue