diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9da044c04..23624cb43 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1487,6 +1487,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 diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index 9d3f2468e..01d10d883 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -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 diff --git a/app/helpers/timelog_helper.rb b/app/helpers/timelog_helper.rb index d1174fe78..aa6e0f3b6 100644 --- a/app/helpers/timelog_helper.rb +++ b/app/helpers/timelog_helper.rb @@ -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 diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index e055fc88f..daaaf1416 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -38,6 +38,7 @@

+ <%= export_csv_encoding_select_tag %> <% if @issue_count > Setting.issues_export_limit.to_i %>

<%= l(:setting_issues_export_limit) %>: <%= Setting.issues_export_limit.to_i %> diff --git a/app/views/timelog/index.html.erb b/app/views/timelog/index.html.erb index f777dac30..eddf821af 100644 --- a/app/views/timelog/index.html.erb +++ b/app/views/timelog/index.html.erb @@ -31,6 +31,7 @@

+ <%= export_csv_encoding_select_tag %>

<%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %> <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %> diff --git a/app/views/timelog/report.html.erb b/app/views/timelog/report.html.erb index 0565c662b..b5307c4af 100644 --- a/app/views/timelog/report.html.erb +++ b/app/views/timelog/report.html.erb @@ -1,5 +1,5 @@

-<%= 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) %>
@@ -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' %>

+ <%= hidden_field_tag 'encoding', l(:general_csv_encoding) unless l(:general_csv_encoding).casecmp('UTF-8') == 0 %> <% end %> <% if @query.valid? %> @@ -62,9 +63,17 @@ <% 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 %> + <% end %> <% end %> @@ -74,3 +83,14 @@ <% 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 %> diff --git a/lib/redmine/export/csv.rb b/lib/redmine/export/csv.rb index dfbe36f4f..b0d48ef6f 100644 --- a/lib/redmine/export/csv.rb +++ b/lib/redmine/export/csv.rb @@ -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 diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index 81b3f7859..fbf7e8046 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -1568,4 +1568,20 @@ RAW assert_equal '0:45', html_hours('0:45') assert_equal '0.75', 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 diff --git a/test/unit/lib/redmine/export/csv_test.rb b/test/unit/lib/redmine/export/csv_test.rb index 52e930c14..918ba5a5e 100644 --- a/test/unit/lib/redmine/export/csv_test.rb +++ b/test/unit/lib/redmine/export/csv_test.rb @@ -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_encoded_with_general_csv_encoding + with_locale 'en' do + string = Redmine::Export::CSV.generate({encoding: 'dummy-encoding'}) {|csv| csv << %w(Foo Bar)} + assert_equal l(:general_csv_encoding), string.encoding.name + end + end + + def test_generate_should_return_strings_encoded_with_encoding_option_if_encoding_option_exists + with_locale 'en' do + string = Redmine::Export::CSV.generate({encoding: 'UTF-8'}) {|csv| csv << %w(Foo Bar)} + assert_equal 'UTF-8', string.encoding.name + assert_not_equal l(:general_csv_encoding), string.encoding.name + end + end end