Merge pull request #71 from finnlabs/use-pdf-export-plugin

Use pdf export plugin
pull/6827/head
ulferts 11 years ago
commit 54f81f7888
  1. 2
      app/controllers/rb_application_controller.rb
  2. 32
      app/controllers/rb_export_card_configurations_controller.rb
  3. 9
      app/controllers/rb_master_backlogs_controller.rb
  4. 12
      app/controllers/rb_stories_controller.rb
  5. 31
      app/helpers/rb_master_backlogs_helper.rb
  6. 16
      app/views/rb_export_card_configurations/index.html.erb
  7. 6
      app/views/shared/_settings.html.erb
  8. 18
      app/views/shared/_view_work_packages_sidebar.html.erb
  9. 6
      config/routes.rb
  10. 103
      features/export_card_configurations.feature
  11. 2
      features/plugin_administration.feature
  12. 9
      features/scrum_master.feature
  13. 11
      features/step_definitions/_given_steps.rb
  14. 4
      features/step_definitions/_then_steps.rb
  15. 10
      features/step_definitions/_when_steps.rb
  16. 6
      lib/open_project/backlogs/engine.rb
  17. 37
      lib/open_project/backlogs/taskboard_card.rb
  18. 132
      lib/open_project/backlogs/taskboard_card/bottom_attributes.rb
  19. 69
      lib/open_project/backlogs/taskboard_card/card.rb
  20. 120
      lib/open_project/backlogs/taskboard_card/card_area.rb
  21. 73
      lib/open_project/backlogs/taskboard_card/description.rb
  22. 163
      lib/open_project/backlogs/taskboard_card/document.rb
  23. 69
      lib/open_project/backlogs/taskboard_card/header.rb
  24. 66
      lib/open_project/backlogs/taskboard_card/measurement.rb
  25. 200
      lib/open_project/backlogs/taskboard_card/page_layout.rb
  26. 109
      lib/open_project/backlogs/taskboard_card/top_attributes.rb
  27. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSans-Bold.ttf
  28. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSans-BoldOblique.ttf
  29. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSans-ExtraLight.ttf
  30. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSans-Oblique.ttf
  31. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSans.ttf
  32. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansCondensed-Bold.ttf
  33. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansCondensed-BoldOblique.ttf
  34. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansCondensed-Oblique.ttf
  35. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansCondensed.ttf
  36. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansMono-Bold.ttf
  37. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansMono-BoldOblique.ttf
  38. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansMono-Oblique.ttf
  39. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSansMono.ttf
  40. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerif-Bold.ttf
  41. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerif-BoldItalic.ttf
  42. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerif-Italic.ttf
  43. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerif.ttf
  44. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerifCondensed-Bold.ttf
  45. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerifCondensed-BoldItalic.ttf
  46. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerifCondensed-Italic.ttf
  47. BIN
      lib/open_project/backlogs/taskboard_card/ttf/DejaVuSerifCondensed.ttf
  48. 3
      openproject-backlogs.gemspec
  49. 81
      spec/models/taskboard_card/card_area_spec.rb
  50. 4
      spec/routing/rb_stories_routing_spec.rb
  51. 32
      spec/routing/rb_taskboard_card_configurations_routing_spec.rb
  52. 84
      spec/views/rb_master_backlogs/index.html.erb_spec.rb

@ -39,7 +39,7 @@ class RbApplicationController < ApplicationController
helper :rb_common
before_filter :load_sprint_and_project, :authorize, :check_if_plugin_is_configured
before_filter :load_sprint_and_project, :check_if_plugin_is_configured, :authorize
private

@ -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

@ -38,6 +38,8 @@ class RbMasterBacklogsController < RbApplicationController
menu_item :backlogs
before_filter :set_export_card_config_meta
def index
@owner_backlogs = Backlog.owner_backlogs(@project)
@sprint_backlogs = Backlog.sprint_backlogs(@project)
@ -47,6 +49,13 @@ class RbMasterBacklogsController < RbApplicationController
private
def set_export_card_config_meta
@export_card_config_meta = {
count: ExportCardConfiguration.active.count,
default: ExportCardConfiguration.active.select { |c| c.is_default? }.first
}
end
def default_breadcrumb
l(:label_backlogs)
end

@ -35,17 +35,7 @@
class RbStoriesController < RbApplicationController
unloadable
include OpenProject::Backlogs::TaskboardCard
def index
cards_document = OpenProject::Backlogs::TaskboardCard::Document.new(current_language)
@sprint.stories(@project).each { |story| cards_document.add_story(story) }
respond_to do |format|
format.pdf { send_data(cards_document.render, :disposition => 'attachment', :type => 'application/pdf') }
end
end
include OpenProject::PdfExport::ExportCard
def create
params['author_id'] = User.current.id

@ -61,7 +61,7 @@ module RbMasterBacklogsHelper
end
menu = []
[:new_story, :stories_tasks, :task_board, :burndown, :cards, :wiki].each do |key|
[:new_story, :stories_tasks, :task_board, :burndown, :cards, :wiki, :configs].each do |key|
menu << items[key] if items.keys.include?(key)
end
@ -82,18 +82,33 @@ module RbMasterBacklogsHelper
:project_id => @project,
:sprint_id => backlog.sprint)
if OpenProject::Backlogs::TaskboardCard::PageLayout.selected_label.present?
items[:cards] = link_to(l(:label_sprint_cards),
:controller => '/rb_stories',
:action => 'index',
:project_id => @project,
:sprint_id => backlog.sprint,
:format => :pdf)
if @export_card_config_meta[:count] > 0
items[:configs] = export_export_cards_link(backlog)
end
items
end
def export_export_cards_link(backlog)
if @export_card_config_meta[:count] == 1
link_to(l(:label_backlogs_export_card_export),
:controller => '/rb_export_card_configurations',
:action => 'show',
:project_id => @project,
:sprint_id => backlog.sprint,
:id => @export_card_config_meta[:default],
:format => :pdf)
else
export_modal_link(backlog)
end
end
def export_modal_link(backlog, options = {})
path = backlogs_project_sprint_export_card_configurations_path(@project.id, backlog.sprint.id)
html_id = "modal_work_package_#{SecureRandom.hex(10)}"
link_to(l(:label_backlogs_export_card_export), path, options.merge(:id => html_id, :'data-modal' => ''))
end
def sprint_backlog_menu_items_for(backlog)
items = {}

@ -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 %>

@ -83,12 +83,6 @@ See doc/COPYRIGHT.rdoc for more details.
options_for_select([[l(:label_points_burn_up), 'up'], [l(:label_points_burn_down), 'down']],
Setting.plugin_openproject_backlogs["points_burn_direction"])) %>
</p>
<p>
<%= label_tag("settings[card_spec]", l(:backlogs_card_specification)) %>
<%= select_tag("settings[card_spec]",
options_for_select(OpenProject::Backlogs::TaskboardCard::PageLayout::LABELS.keys.sort.collect{|label| [label, label]},
Setting.plugin_openproject_backlogs["card_spec"])) %>
</p>
<p>
<%= label_tag("settings[wiki_template]", l(:backlogs_wiki_template)) %>
<%= text_field_tag("settings[wiki_template]",

@ -56,16 +56,14 @@ See doc/COPYRIGHT.rdoc for more details.
})
%><br/>
<% if OpenProject::Backlogs::TaskboardCard::PageLayout.available? %>
<%= link_to(l(:label_sprint_cards), {
:controller => '/rb_stories',
:action => 'index',
:project_id => project,
:sprint_id => sprint,
:format => 'pdf'
})
%><br/>
<% end %>
<%= link_to(l(:label_sprint_cards), {
:controller => '/rb_stories',
:action => 'index',
:project_id => project,
:sprint_id => sprint,
:format => 'pdf'
})
%><br/>
<% if project.module_enabled? "wiki" %>
<%= link_to(l(:label_wiki), {

@ -57,8 +57,12 @@ OpenProject::Application.routes.draw do
resources :tasks, :controller => :rb_tasks, :only => [:create, :update]
resources :stories, :controller => :rb_stories, :only => [:index, :create, :update]
resources :export_card_configurations, :controller => :rb_export_card_configurations, :only => [:index, :show] do
resources :stories, :controller => :rb_stories, :only => [:index]
end
resources :stories, :controller => :rb_stories, :only => [:create, :update]
end
end
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

@ -41,4 +41,4 @@ Feature: Plugin Administration
Scenario: Fields for configuration
Given I am already admin
When I go to the configuration page of the "openproject_backlogs" plugin
Then there should be a "settings_card_spec" field
Then there should be a "settings_task_type" field

@ -264,15 +264,6 @@ Feature: Scrum Master
And Story A should be in the 2nd position of the sprint named Sprint 001
And Story B should be the higher item of Story A
Scenario: Download printable cards for the task board
Given I have selected card label stock Avery 8435B
And I move the story named Story 4 up to the 1st position of the sprint named Sprint 001
And I am on the work_packages index page
And I follow "Sprint 001"
Then the request should complete successfully
When I follow "Export cards"
Then the request should complete successfully
Scenario: view the sprint notes
Given I have set the content for wiki page Sprint Template to Sprint Template
And I have made Sprint Template the template page for sprint notes

@ -266,7 +266,6 @@ Given /^I have selected card label stock (.+)$/ do |stock|
# to get the ones, shipped with the plugin or
# rake openproject:backlogs:current_labels
# to get current one, downloaded from the internet.
OpenProject::Backlogs::TaskboardCard::PageLayout.should be_available
end
Given /^I have set my API access key$/ do
@ -343,3 +342,13 @@ Given /^the status of "([^"]*)" is "([^"]*)"$/ do |work_package_subject, status_
s.status = Status.find_by_name(status_name)
s.save!
end
Given /^there is the single default export card configuration$/ do
config = ExportCardConfiguration.create!({
name: "Default",
per_page: 1,
page_size: "A4",
orientation: "landscape",
rows: "rows:\n row1:\n has_border: false\n columns:\n id:\n has_label: false\n font_size: 15"
})
end

@ -277,3 +277,7 @@ end
Then /^I should be notified that the work_package "(.+?)" is an invalid parent to the work_package "(.+?)" because of cross project limitations$/ do |parent_name, child_name|
step %Q{I should see "Parent is invalid because the work_package '#{child_name}' is a backlogs task and as such can not have the backlogs story '#{parent_name}' as it's parent as long as the story is in a different project" within "#errorExplanation"}
end
Then /^the PDF download dialog should be displayed$/ do
# As far as I'm aware there's nothing that can be done here to check for this.
end

@ -172,6 +172,12 @@ When /^I click on the text "(.+?)"$/ do |locator|
find(:xpath, %Q{//*[contains(text(), "#{locator}")]}).click
end
When /^I click on the link on the modal window with text "(.+?)"$/ do |locator|
browser = page.driver.browser
browser.switch_to.frame("modalIframe")
click_link(locator)
end
When /^I click on the element with class "([^"]+?)"$/ do |locator|
find(:css, ".#{locator}").click
end
@ -226,3 +232,7 @@ end
When /^I change the fold state of a version$/ do
find(".backlog .toggler").click
end
When /^I click on the Export link$/ do
click_link("Export")
end

@ -149,7 +149,8 @@ module OpenProject::Backlogs
:rb_stories => [:index, :show],
:rb_queries => :show,
:rb_server_variables => :show,
:rb_burndown_charts => :show
:rb_burndown_charts => :show,
:rb_export_card_configurations => [:index, :show]
}
permission :view_taskboards, {
@ -160,7 +161,8 @@ module OpenProject::Backlogs
:rb_impediments => [:index, :show],
:rb_wikis => :show,
:rb_server_variables => :show,
:rb_burndown_charts => :show
:rb_burndown_charts => :show,
:rb_export_card_configurations => [:index, :show]
}
# Sprint permissions

@ -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

@ -16,10 +16,9 @@ Gem::Specification.new do |s|
s.test_files = Dir["spec/**/*"]
s.add_dependency "rails", "~> 3.2.9"
s.add_dependency "prawn"
s.add_dependency "acts_as_silent_list"
s.add_dependency "openproject-plugins"
s.add_dependency "openproject-pdf_export"
s.add_development_dependency "factory_girl_rails", "~> 4.0"
s.add_development_dependency "pdf-inspector", "~>1.0.0"
end

@ -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

@ -37,10 +37,6 @@ require 'spec_helper'
describe RbStoriesController do
describe "routing" do
it { get('/projects/project_42/sprints/21/stories').should route_to(:controller => 'rb_stories',
:action => 'index',
:project_id => 'project_42',
:sprint_id => '21') }
it { post('/projects/project_42/sprints/21/stories').should route_to(:controller => 'rb_stories',
:action => 'create',
:project_id => 'project_42',

@ -33,27 +33,19 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
module OpenProject::Backlogs::TaskboardCard
class Box
attr_accessor :x
attr_accessor :y
attr_accessor :width
attr_accessor :height
require 'spec_helper'
def initialize(x,y,w,h)
@x = x
@y = y
@width = w
@height = h
end
describe RbExportCardConfigurationsController do
describe "routing" do
it { get('/projects/project_42/sprints/21/export_card_configurations/10').should route_to(:controller => 'rb_export_card_configurations',
:action => 'show',
:project_id => 'project_42',
:sprint_id => '21',
:id => '10') }
def at
[x, y]
end
def at=(pos)
x = pos[0]
y = pos[1]
end
it { get('/projects/project_42/sprints/21/export_card_configurations').should route_to(:controller => 'rb_export_card_configurations',
:action => 'index',
:project_id => 'project_42',
:sprint_id => '21') }
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…
Cancel
Save