]> source.dussan.org Git - redmine.git/commitdiff
Allow switching the encoding to UTF-8 when exporting to CSV (#26279).
authorGo MAEDA <maeda@farend.jp>
Mon, 7 May 2018 01:13:12 +0000 (01:13 +0000)
committerGo MAEDA <maeda@farend.jp>
Mon, 7 May 2018 01:13:12 +0000 (01:13 +0000)
Patch by Mizuki ISHIKAWA.

git-svn-id: http://svn.redmine.org/redmine/trunk@17328 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/helpers/application_helper.rb
app/helpers/queries_helper.rb
app/helpers/timelog_helper.rb
app/views/issues/index.html.erb
app/views/timelog/index.html.erb
app/views/timelog/report.html.erb
lib/redmine/export/csv.rb
test/helpers/application_helper_test.rb
test/unit/lib/redmine/export/csv_test.rb

index 55b6230c6a1e9ffb46a13dfb2241d401775835b5..48794aa95c68c4e09d59487532a2aa6ab51cc79d 100644 (file)
@@ -1494,6 +1494,19 @@ module ApplicationHelper
     encoding = l(:general_csv_encoding)
   end
 
+  def export_csv_encoding_select_tag
+    return if l(:general_csv_encoding).casecmp('UTF-8') == 0
+    options = [l(:general_csv_encoding), 'UTF-8']
+    content_tag(:p) do
+      concat(
+        content_tag(:label) do
+          concat l(:label_encoding) + ' '
+          concat select_tag('encoding', options_for_select(options, l(:general_csv_encoding)))
+        end
+      )
+    end
+  end
+
   private
 
   def wiki_helper
index 9d3f2468e0ab7e5811f612d3f752c7294202bf04..01d10d883cffadc15c9d1ef013dd1d949fac4432 100644 (file)
@@ -275,7 +275,7 @@ module QueriesHelper
   def query_to_csv(items, query, options={})
     columns = query.columns
 
-    Redmine::Export::CSV.generate do |csv|
+    Redmine::Export::CSV.generate(:encoding => params[:encoding]) do |csv|
       # csv header fields
       csv << columns.map {|c| c.caption.to_s}
       # csv lines
@@ -370,7 +370,7 @@ module QueriesHelper
 
     tags
   end
+
   def query_hidden_sort_tag(query)
     hidden_field_tag("sort", query.sort_criteria.to_param, :id => nil)
   end
index d1174fe78a87034712599d73dc3392462feedc91..aa6e0f3b6e80742ef7738f769fd3d03d70b7ce75 100644 (file)
@@ -76,7 +76,7 @@ module TimelogHelper
   end
 
   def report_to_csv(report)
-    Redmine::Export::CSV.generate do |csv|
+    Redmine::Export::CSV.generate(:encoding => params[:encoding]) do |csv|
       # Column headers
       headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
       headers += report.periods
index 005b921386f8d8869e94137d22ea41b570acfbaf..c02c183683e4d59ceaf05c248acd0c701886b3c9 100644 (file)
@@ -38,6 +38,7 @@
     <label><%= check_box_tag 'c[]', 'description', @query.has_column?(:description) %> <%= l(:field_description) %></label>
     <label><%= check_box_tag 'c[]', 'last_notes', @query.has_column?(:last_notes) %> <%= l(:label_last_notes) %></label>
   </p>
+  <%= export_csv_encoding_select_tag %>
   <% if @issue_count > Setting.issues_export_limit.to_i %>
   <p class="icon icon-warning">
     <%= l(:setting_issues_export_limit) %>: <%= Setting.issues_export_limit.to_i %>
index 65ca4855d3a5d7483b8b8aec77203f48a5721858..9f320d63784772772f0ea798feaed459edca2162 100644 (file)
@@ -31,6 +31,7 @@
     <label><%= radio_button_tag 'c[]', '', true %> <%= l(:description_selected_columns) %></label><br />
     <label><%= radio_button_tag 'c[]', 'all_inline' %> <%= l(:description_all_columns) %></label>
   </p>
+  <%= export_csv_encoding_select_tag %>
   <p class="buttons">
     <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);", :data => { :disable_with => false } %>
     <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button', :data => { :disable_with => false } %>
index 0565c662b81915af0abce15c4b9ae523f9902deb..b5307c4afc4b8201bc5ff86b7a00ec5882108d09 100644 (file)
@@ -1,5 +1,5 @@
 <div class="contextual">
-<%= link_to l(:button_log_time), 
+<%= link_to l(:button_log_time),
             _new_time_entry_path(@project, @issue),
             :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project, :global => true) %>
 </div>
@@ -24,6 +24,7 @@
                                                           :disabled => (@report.criteria.length >= 3),
                                                           :id => "criterias") %>
      <%= link_to l(:button_clear), {:params => request.query_parameters.merge(:criteria => nil)}, :class => 'icon icon-reload' %></p>
+  <%= hidden_field_tag 'encoding', l(:general_csv_encoding) unless l(:general_csv_encoding).casecmp('UTF-8') == 0 %>
 <% end %>
 
 <% if @query.valid? %>
 </div>
 
 <% other_formats_links do |f| %>
-  <%= f.link_to_with_query_parameters 'CSV' %>
+  <%= f.link_to_with_query_parameters 'CSV', {}, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
 <% end %>
 <% end %>
+<div id="csv-export-options" style="display: none;">
+  <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
+  <%= export_csv_encoding_select_tag %>
+  <p class="buttons">
+    <%= submit_tag l(:button_export), :name => nil, :id => 'csv-export-button' %>
+    <%= submit_tag l(:button_cancel), :name => nil, :onclick => 'hideModal(this);', :type => 'button' %>
+  </p>
+</div>
 <% end %>
 <% end %>
 
 
 <% html_title(@query.new_record? ? l(:label_spent_time) : @query.name, l(:label_report)) %>
 
+
+<%= javascript_tag do %>
+$(document).ready(function(){
+  $('input#csv-export-button').click(function(){
+    $('form input#encoding').val($('select#encoding option:selected').val());
+    $('form#query_form').attr('action', '<%= report_time_entries_path(:format => 'csv') %>').submit();
+    $('form#query_form').attr('action', '<%= report_time_entries_path %>');
+    hideModal(this);
+  });
+});
+<% end %>
index dfbe36f4fdb3d70c05b5f8e45ce7410b5055b674..b0d48ef6f1b9221cc66b9239ac068d49352a67fb 100644 (file)
@@ -31,12 +31,12 @@ module Redmine
 
         class << self
 
-          def generate(&block)
+          def generate(options = {}, &block)
             col_sep = l(:general_csv_separator)
-            encoding = l(:general_csv_encoding)
+            encoding = Encoding.find(options[:encoding]) rescue Encoding.find(l(:general_csv_encoding))
 
             str = ''.force_encoding(encoding)
-            if encoding == 'UTF-8'
+            if encoding == Encoding::UTF_8
               # BOM
               str = "\xEF\xBB\xBF".force_encoding(encoding)
             end
index 78a4822f12fed4a6bc6cf7297a2a0dfef219d68a..692c6c6bb42a2e58a5c7c90bbe6a625479d3fbae 100644 (file)
@@ -1607,4 +1607,20 @@ RAW
     assert_equal '<span class="hours hours-int">0</span><span class="hours hours-dec">:45</span>', html_hours('0:45')
     assert_equal '<span class="hours hours-int">0</span><span class="hours hours-dec">.75</span>', html_hours('0.75')
   end
+
+  def test_export_csv_encoding_select_tag_should_return_nil_when_general_csv_encoding_is_UTF8
+    with_locale 'az' do
+      assert_equal l(:general_csv_encoding), 'UTF-8'
+      assert_nil export_csv_encoding_select_tag
+    end
+  end
+
+  def test_export_csv_encoding_select_tag_should_have_two_option_when_general_csv_encoding_is_not_UTF8
+    with_locale 'en' do
+      assert_not_equal l(:general_csv_encoding), 'UTF-8'
+      result = export_csv_encoding_select_tag
+      assert_select_in result, "option[selected='selected'][value=#{l(:general_csv_encoding)}]", :text => l(:general_csv_encoding)
+      assert_select_in result, "option[value='UTF-8']", :text => 'UTF-8'
+    end
+  end
 end
index 52e930c14d0eb5a0296d252c1fc9bdfc149410e8..d3727b620d9da4d6cac3e39d47dd3610ff23bc10 100644 (file)
@@ -18,7 +18,7 @@
 require File.expand_path('../../../../../test_helper', __FILE__)
 
 class CsvTest < ActiveSupport::TestCase
-
+  include Redmine::I18n
   BOM = "\xEF\xBB\xBF".force_encoding('UTF-8')
 
   def test_should_include_bom_when_utf8_encoded
@@ -28,4 +28,19 @@ class CsvTest < ActiveSupport::TestCase
       assert string.starts_with?(BOM)
     end
   end
+
+  def test_generate_should_return_strings_with_given_encoding
+    with_locale 'en' do
+      string = Redmine::Export::CSV.generate({encoding: 'ISO-8859-3'}) {|csv| csv << %w(Foo Bar)}
+      assert_equal 'ISO-8859-3', string.encoding.name
+      assert_not_equal l(:general_csv_encoding), string.encoding.name
+    end
+  end
+
+  def test_generate_should_return_strings_with_general_csv_encoding_if_invalid_encoding_is_given
+    with_locale 'en' do
+      string = Redmine::Export::CSV.generate({encoding: 'invalid-encoding-name'}) {|csv| csv << %w(Foo Bar)}
+      assert_equal l(:general_csv_encoding), string.encoding.name
+    end
+  end
 end