Compare commits

...

47 Commits

Author SHA1 Message Date
Kolan Sh 9ec90a50d4 Automatic character encoding detection in Mercurial repos. 2014-05-09 22:41:50 +04:00
Jean-Philippe Lang 9f3239a25a tagged version 2.5.1
git-svn-id: http://svn.redmine.org/redmine/tags/2.5.1@13035 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 16:56:15 +00:00
Jean-Philippe Lang 048036da81 Updates for 2.5.1 release.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13032 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 16:08:43 +00:00
Jean-Philippe Lang a8d3f491e6 Merged r13029 (#16415).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13030 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 16:04:07 +00:00
Jean-Philippe Lang 1807093b75 Merged r13018 (#16466).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13027 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:53:13 +00:00
Jean-Philippe Lang 665767db44 Merged r12969 and r12973 (#16353).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13026 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:41:09 +00:00
Jean-Philippe Lang 23ae3d1fa6 Merged r12986 (#16381).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13025 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:39:24 +00:00
Jean-Philippe Lang 2344dfe7f7 Merged r12968 (#16319).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13024 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:38:47 +00:00
Jean-Philippe Lang 33a7f6bc11 Merged r12990 and r12991 (#16326).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13023 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:38:11 +00:00
Jean-Philippe Lang 65c9223fe5 Merged r12990 (#16338).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13022 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:37:17 +00:00
Jean-Philippe Lang df7f00afce Merged r12970 (#16259).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13021 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:36:29 +00:00
Jean-Philippe Lang c5b52ec29f Merged r12989 and r12997 (#16236).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13020 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:35:47 +00:00
Jean-Philippe Lang 58786e8d80 Merged r12985 (#14298).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13019 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:34:28 +00:00
Toshi MARUYAMA d10f17f216 Merged r13015 from trunk to 2.5-stable (#16453)
Czech translation for 2.5-stable updated by Karel Pičman.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13017 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-28 11:23:20 +00:00
Toshi MARUYAMA 323527beb7 Merged r13004 from trunk to 2.5-stable.
add ChangeLog note that #15781 was forgotten to merge to v2.4.3.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13005 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-25 08:39:07 +00:00
Toshi MARUYAMA 0d3cb4e8e1 Merged r13001 from trunk to 2.5-stable.
Gemfile: pin rake version 10.1.

rake 10.2.0 requires Ruby version >= 1.9.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13002 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-25 08:17:07 +00:00
Toshi MARUYAMA 75855f21bb Merged r12981 from trunk to 2.5-stable (#16368)
Polish translation updated by Jan Inowolski.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12982 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-18 03:42:06 +00:00
Jean-Philippe Lang c61a6a707f Merged r12971 (#16255).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12979 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-17 08:30:30 +00:00
Jean-Philippe Lang 4aab2ed303 Merged r12967 (#16321).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12978 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-17 08:29:20 +00:00
Toshi MARUYAMA e0a8e692da Merged r12965 from trunk to 2.5-stable (#16356)
Spanish translation updated by Jesus Gutierrez de la Vega.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12966 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-15 06:27:34 +00:00
Toshi MARUYAMA 5e06374eb7 Merged r12963 from trunk to 2.5-stable (#16336)
Russian translation updated by Kirill Bezrukov.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12964 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-13 11:38:41 +00:00
Toshi MARUYAMA 9686c078f9 Merged r12961 from trunk to 2.5-stable (#16334)
Korean Translation updated by Jong-Ha Ahn.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12962 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-13 08:53:17 +00:00
Toshi MARUYAMA b3ac538a18 Merged r12959 from trunk to 2.5-stable (#16320)
fix Turkish translation typo by Gürkan Gür.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12960 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-12 00:37:58 +00:00
Toshi MARUYAMA a43716d6bb Merged r12955 from trunk to 2.5-stable (#16291)
Japanese translation updated by Go MAEDA.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12956 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-11 09:57:15 +00:00
Jean-Philippe Lang 91a161fadb Merged r12951.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12952 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 11:24:13 +00:00
Jean-Philippe Lang c75e07f8d3 Updates for 2.5.0 release.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12950 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 09:39:31 +00:00
Jean-Philippe Lang dbe03f5443 Merged r12944 (#16143).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12947 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 09:34:00 +00:00
Jean-Philippe Lang 5b1799f245 Merged r12896 (#16081).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12945 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 09:29:22 +00:00
Jean-Philippe Lang 8b1a61d856 Merged r12941 (#16161).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12942 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-28 12:53:05 +00:00
Jean-Philippe Lang 9cb17f598d Merged r12938 (#16169).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12939 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-28 11:39:01 +00:00
Toshi MARUYAMA 0d5dd6fc19 Merged r12935 from trunk to 2.5-stable (#16177)
use Python getattr instead of hasattr.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12936 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-26 16:53:51 +00:00
Toshi MARUYAMA fcc1f198e7 Merged r12930 from trunk to 2.5-stable (#16177)
Mercurial 2.9 compatibility.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12932 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-26 13:02:03 +00:00
Toshi MARUYAMA 41667cd5de Merged r12929 from trunk to 2.5-stable (#16177)
scm: mercurial: add one "closed" branch to test repository.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12931 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-26 13:01:43 +00:00
Toshi MARUYAMA 51175ede2c revert r12925 of 2.5-stable
I mistook to commit in stable branch.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12926 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-25 06:53:35 +00:00
Toshi MARUYAMA 9abdbd423d prevent issue tree hierarchy is broken in race conditions (#6579)
awesome_nested_set 2.1.6 uses lock.
Issue model uses as same way.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12925 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-25 06:49:53 +00:00
Jean-Philippe Lang 63212e5c16 Merged r12915 to 12918 (#16107).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12923 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:20:42 +00:00
Jean-Philippe Lang 88b3872179 Merged r12914 (#16134).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12922 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:15:37 +00:00
Jean-Philippe Lang 066e9b7f94 Merged r12912 and r12913 from trunk.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12921 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:14:59 +00:00
Jean-Philippe Lang 805debddd0 Merged r12910 and r12911 (#16091).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12920 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:11:59 +00:00
Jean-Philippe Lang 01aa2db0af Merged r12899 (#16077).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12919 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:10:31 +00:00
Toshi MARUYAMA 645749eea8 Merged r12906 from trunk to 2.5-stable
update Rails to 3.2.17

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12907 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-19 10:17:14 +00:00
Jean-Philippe Lang 8b9a2ff871 Merged r12897.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12898 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 10:04:48 +00:00
Jean-Philippe Lang 97434b5aaa Merged r12894 (#16091).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12895 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 09:01:16 +00:00
Jean-Philippe Lang 4308dd7d4c Merged r12892.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12893 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 08:34:57 +00:00
Jean-Philippe Lang 449a92640b Merged r12888 to r12890.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12891 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 08:31:07 +00:00
Jean-Philippe Lang 448c0a72ee Set version to 2.5.0.stable.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12887 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 07:40:56 +00:00
Jean-Philippe Lang 20180db41e 2.5-stable branch added
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12885 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 07:37:46 +00:00
57 changed files with 622 additions and 255 deletions

View File

@ -1,6 +1,7 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem "rails", "3.2.16" gem "rails", "3.2.17"
gem "rake", "~> 10.1.1"
gem "jquery-rails", "~> 2.0.2" gem "jquery-rails", "~> 2.0.2"
gem "coderay", "~> 1.1.0" gem "coderay", "~> 1.1.0"
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
@ -8,6 +9,8 @@ gem "builder", "3.0.0"
gem "mime-types" gem "mime-types"
gem "awesome_nested_set", "2.1.6" gem "awesome_nested_set", "2.1.6"
gem "chardet", ">= 0.9.0"
# Optional gem for LDAP authentication # Optional gem for LDAP authentication
group :ldap do group :ldap do
gem "net-ldap", "~> 0.3.1" gem "net-ldap", "~> 0.3.1"

View File

@ -119,7 +119,7 @@ class ApplicationController < ActionController::Base
if (key = api_key_from_request) if (key = api_key_from_request)
# Use API key # Use API key
user = User.find_by_api_key(key) user = User.find_by_api_key(key)
else elsif request.authorization.to_s =~ /\ABasic /i
# HTTP Basic, either username/password or API key/random # HTTP Basic, either username/password or API key/random
authenticate_with_http_basic do |username, password| authenticate_with_http_basic do |username, password|
user = User.try_to_login(username, password) || User.find_by_api_key(username) user = User.try_to_login(username, password) || User.find_by_api_key(username)
@ -379,7 +379,7 @@ class ApplicationController < ActionController::Base
begin begin
uri = URI.parse(back_url) uri = URI.parse(back_url)
# do not redirect user to another host or to the login or register page # do not redirect user to another host or to the login or register page
if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)}) if ((uri.relative? && back_url.match(%r{\A/\w})) || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
redirect_to(back_url) redirect_to(back_url)
return return
end end

View File

@ -62,10 +62,14 @@ class IssuesController < ApplicationController
case params[:format] case params[:format]
when 'csv', 'pdf' when 'csv', 'pdf'
@limit = Setting.issues_export_limit.to_i @limit = Setting.issues_export_limit.to_i
if params[:columns] == 'all'
@query.column_names = @query.available_inline_columns.map(&:name)
end
when 'atom' when 'atom'
@limit = Setting.feeds_limit.to_i @limit = Setting.feeds_limit.to_i
when 'xml', 'json' when 'xml', 'json'
@offset, @limit = api_offset_and_limit @offset, @limit = api_offset_and_limit
@query.column_names = %w(author)
else else
@limit = per_page_option @limit = per_page_option
end end

View File

@ -66,7 +66,7 @@ class JournalsController < ApplicationController
text = @issue.description text = @issue.description
end end
# Replaces pre blocks with [...] # Replaces pre blocks with [...]
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]') text = text.to_s.strip.gsub(%r{<pre>(.*?)</pre>}m, '[...]')
@content = "#{ll(Setting.default_language, :text_user_wrote, user)}\n> " @content = "#{ll(Setting.default_language, :text_user_wrote, user)}\n> "
@content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound

View File

@ -113,7 +113,7 @@ class MessagesController < ApplicationController
@subject = "RE: #{@subject}" unless @subject.starts_with?('RE:') @subject = "RE: #{@subject}" unless @subject.starts_with?('RE:')
@content = "#{ll(Setting.default_language, :text_user_wrote, @message.author)}\n> " @content = "#{ll(Setting.default_language, :text_user_wrote, @message.author)}\n> "
@content << @message.content.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" @content << @message.content.to_s.strip.gsub(%r{<pre>(.*?)</pre>}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
end end
def preview def preview

View File

@ -55,6 +55,9 @@ class WatchersController < ApplicationController
user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]] user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]]
@users = User.active.where(:id => user_ids).all @users = User.active.where(:id => user_ids).all
end end
if @users.blank?
render :nothing => true
end
end end
def destroy def destroy

View File

@ -978,19 +978,20 @@ module ApplicationHelper
end end
end end
TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE) TOC_RE = /<p>\{\{((<|&lt;)|(>|&gt;))?toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
# Renders the TOC with given headings # Renders the TOC with given headings
def replace_toc(text, headings) def replace_toc(text, headings)
text.gsub!(TOC_RE) do text.gsub!(TOC_RE) do
left_align, right_align = $2, $3
# Keep only the 4 first levels # Keep only the 4 first levels
headings = headings.select{|level, anchor, item| level <= 4} headings = headings.select{|level, anchor, item| level <= 4}
if headings.empty? if headings.empty?
'' ''
else else
div_class = 'toc' div_class = 'toc'
div_class << ' right' if $1 == '>' div_class << ' right' if right_align
div_class << ' left' if $1 == '<' div_class << ' left' if left_align
out = "<ul class=\"#{div_class}\"><li>" out = "<ul class=\"#{div_class}\"><li>"
root = headings.map(&:first).min root = headings.map(&:first).min
current = root current = root

View File

@ -51,6 +51,15 @@ module ProjectsHelper
content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id') content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id')
end end
def render_project_action_links
links = []
links << link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') if User.current.allowed_to?(:add_project, nil, :global => true)
links << link_to(l(:label_issue_view_all), issues_path) if User.current.allowed_to?(:view_issues, nil, :global => true)
links << link_to(l(:label_overall_spent_time), time_entries_path) if User.current.allowed_to?(:view_time_entries, nil, :global => true)
links << link_to(l(:label_overall_activity), { :controller => 'activities', :action => 'index', :id => nil })
links.join(" | ").html_safe
end
# Renders the projects index # Renders the projects index
def render_project_hierarchy(projects) def render_project_hierarchy(projects)
render_project_nested_lists(projects) do |project| render_project_nested_lists(projects) do |project|

View File

@ -129,6 +129,10 @@ module QueriesHelper
when 'IssueRelation' when 'IssueRelation'
other = value.other_issue(issue) other = value.other_issue(issue)
l(value.label_for(issue)) + " ##{other.id}" l(value.label_for(issue)) + " ##{other.id}"
when 'TrueClass'
l(:general_text_Yes)
when 'FalseClass'
l(:general_text_No)
else else
value.to_s value.to_s
end end

View File

@ -114,7 +114,7 @@ class CustomField < ActiveRecord::Base
end end
def possible_values def possible_values
values = super() values = read_attribute(:possible_values)
if values.is_a?(Array) if values.is_a?(Array)
values.each do |value| values.each do |value|
value.force_encoding('UTF-8') if value.respond_to?(:force_encoding) value.force_encoding('UTF-8') if value.respond_to?(:force_encoding)
@ -128,7 +128,8 @@ class CustomField < ActiveRecord::Base
# Makes possible_values accept a multiline string # Makes possible_values accept a multiline string
def possible_values=(arg) def possible_values=(arg)
if arg.is_a?(Array) if arg.is_a?(Array)
super(arg.compact.collect(&:strip).select {|v| !v.blank?}) values = arg.compact.collect(&:strip).select {|v| !v.blank?}
write_attribute(:possible_values, values)
else else
self.possible_values = arg.to_s.split(/[\n\r]+/) self.possible_values = arg.to_s.split(/[\n\r]+/)
end end
@ -241,9 +242,7 @@ class CustomField < ActiveRecord::Base
errs << ::I18n.t('activerecord.errors.messages.blank') errs << ::I18n.t('activerecord.errors.messages.blank')
end end
end end
if custom_value.value.present? errs += format.validate_custom_value(custom_value)
errs += format.validate_custom_value(custom_value)
end
errs errs
end end

View File

@ -200,7 +200,7 @@ class Issue < ActiveRecord::Base
# Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
def available_custom_fields def available_custom_fields
(project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : [] (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields) : []
end end
def visible_custom_field_values(user=nil) def visible_custom_field_values(user=nil)

View File

@ -333,8 +333,9 @@ class IssueQuery < Query
limit(options[:limit]). limit(options[:limit]).
offset(options[:offset]) offset(options[:offset])
if has_custom_field_column? scope = scope.preload(:custom_values)
scope = scope.preload(:custom_values) if has_column?(:author)
scope = scope.preload(:author)
end end
issues = scope.all issues = scope.all

View File

@ -80,7 +80,7 @@ class Mailer < ActionMailer::Base
def self.deliver_issue_edit(journal) def self.deliver_issue_edit(journal)
issue = journal.journalized.reload issue = journal.journalized.reload
to = journal.notified_users to = journal.notified_users
cc = journal.notified_watchers cc = journal.notified_watchers - to
journal.each_notification(to + cc) do |users| journal.each_notification(to + cc) do |users|
issue.each_notification(users) do |users2| issue.each_notification(users) do |users2|
Mailer.issue_edit(journal, to & users2, cc & users2).deliver Mailer.issue_edit(journal, to & users2, cc & users2).deliver

View File

@ -51,7 +51,7 @@ class News < ActiveRecord::Base
end end
def recipients def recipients
project.users.select {|user| user.notify_about?(self)}.map(&:mail) project.users.select {|user| user.notify_about?(self) && user.allowed_to?(:view_news, project)}.map(&:mail)
end end
# Returns the email addresses that should be cc'd when a new news is added # Returns the email addresses that should be cc'd when a new news is added

View File

@ -77,6 +77,16 @@ class TimeEntry < ActiveRecord::Base
end end
end end
def safe_attributes=(attrs, user=User.current)
attrs = super
if !new_record? && issue && issue.project_id != project_id
if user.allowed_to?(:log_time, issue.project)
self.project_id = issue.project_id
end
end
attrs
end
def set_project_if_nil def set_project_if_nil
self.project = issue.project if issue && project.nil? self.project = issue.project if issue && project.nil?
end end

View File

@ -384,8 +384,8 @@ class User < Principal
# Find a user account by matching the exact login and then a case-insensitive # Find a user account by matching the exact login and then a case-insensitive
# version. Exact matches will be given priority. # version. Exact matches will be given priority.
def self.find_by_login(login) def self.find_by_login(login)
login = Redmine::CodesetUtil.replace_invalid_utf8(login.to_s)
if login.present? if login.present?
login = login.to_s
# First look for an exact match # First look for an exact match
user = where(:login => login).detect {|u| u.login == login} user = where(:login => login).detect {|u| u.login == login}
unless user unless user

View File

@ -104,9 +104,11 @@ class WikiPage < ActiveRecord::Base
end end
def content_for_version(version=nil) def content_for_version(version=nil)
result = content.versions.find_by_version(version.to_i) if version if content
result ||= content result = content.versions.find_by_version(version.to_i) if version
result result ||= content
result
end
end end
def diff(version_to=nil, version_from=nil) def diff(version_to=nil, version_from=nil)

View File

@ -2,9 +2,9 @@
<div class="splitcontentleft"> <div class="splitcontentleft">
<div class="box tabular"> <div class="box tabular">
<p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %></p>
<p><%= f.text_field :name, :required => true %></p> <p><%= f.text_field :name, :required => true %></p>
<p><%= f.text_area :description, :rows => 7 %></p> <p><%= f.text_area :description, :rows => 7 %></p>
<p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %></p>
<% if @custom_field.format.multiple_supported %> <% if @custom_field.format.multiple_supported %>
<p> <p>

View File

@ -8,7 +8,7 @@
<tbody> <tbody>
<% @group.users.sort.each do |user| %> <% @group.users.sort.each do |user| %>
<tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>"> <tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>">
<td class="user"><%= link_to_user user %></td> <td class="name"><%= link_to_user user %></td>
<td class="buttons"> <td class="buttons">
<%= delete_link group_user_path(@group, :user_id => user), :remote => true %> <%= delete_link group_user_path(@group, :user_id => user), :remote => true %>
</td> </td>

View File

@ -43,3 +43,13 @@
<%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %> <%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %>
<% end %> <% end %>
<% heads_for_wiki_formatter %>
<%= javascript_tag do %>
$(document).ready(function(){
$("#issue_tracker_id, #issue_status_id").each(function(){
$(this).val($(this).find("option[selected=selected]").val());
});
});
<% end %>

View File

@ -3,12 +3,7 @@
<% end %> <% end %>
<div class="contextual"> <div class="contextual">
<%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %> <%= render_project_action_links %>
<%= link_to(l(:label_issue_view_all), issues_path) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %>
<%= link_to(l(:label_overall_spent_time), time_entries_path) + ' |' if User.current.allowed_to?(:view_time_entries, nil, :global => true) %>
<%= link_to l(:label_overall_activity),
{ :controller => 'activities', :action => 'index',
:id => nil } %>
</div> </div>
<h2><%= l(:label_project_plural) %></h2> <h2><%= l(:label_project_plural) %></h2>

View File

@ -23,8 +23,10 @@
:ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);" %> :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);" %>
</td> </td>
<td class="buttons"> <td class="buttons">
<input type="button" value="&#8648;" onclick="moveOptionTop(this.form.selected_columns);" /><br />
<input type="button" value="&#8593;" onclick="moveOptionUp(this.form.selected_columns);" /><br /> <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.selected_columns);" /><br />
<input type="button" value="&#8595;" onclick="moveOptionDown(this.form.selected_columns);" /> <input type="button" value="&#8595;" onclick="moveOptionDown(this.form.selected_columns);" /><br />
<input type="button" value="&#8650;" onclick="moveOptionBottom(this.form.selected_columns);" />
</td> </td>
</tr> </tr>
</table> </table>

View File

@ -1,4 +1,4 @@
# Update to 2.2, 2.4 by Karel Picman <karel.picman@kontron.com> # Update to 2.2, 2.4, 2.5 by Karel Picman <karel.picman@kontron.com>
# Update to 1.1 by Michal Gebauer <mishak@mishak.net> # Update to 1.1 by Michal Gebauer <mishak@mishak.net>
# Updated by Josef Liška <jl@chl.cz> # Updated by Josef Liška <jl@chl.cz>
# CZ translation by Maxim Krušina | Massimo Filippi, s.r.o. | maxim@mxm.cz # CZ translation by Maxim Krušina | Massimo Filippi, s.r.o. | maxim@mxm.cz
@ -1104,14 +1104,13 @@ cs:
notice_new_password_must_be_different: Nové heslo se musí lišit od stávajícího notice_new_password_must_be_different: Nové heslo se musí lišit od stávajícího
setting_mail_handler_excluded_filenames: Vyřadit přílohy podle jména setting_mail_handler_excluded_filenames: Vyřadit přílohy podle jména
text_convert_available: ImageMagick convert k dispozici (volitelné) text_convert_available: ImageMagick convert k dispozici (volitelné)
label_link: Link label_link: Odkaz
label_only: only label_only: jenom
label_drop_down_list: drop-down list label_drop_down_list: rozbalovací seznam
label_checkboxes: checkboxes label_checkboxes: zaškrtávátka
label_link_values_to: Link values to URL label_link_values_to: Propojit hodnoty s URL
setting_force_default_language_for_anonymous: Force default language for anonymous setting_force_default_language_for_anonymous: Vynutit výchozí jazyk pro anonymní uživatele
users users
setting_force_default_language_for_loggedin: Force default language for logged-in setting_force_default_language_for_loggedin: Vynutit výchozí jazyk pro přihlášené uživatele
users users
label_custom_field_select_type: Select the type of object to which the custom field label_custom_field_select_type: Vybrat typ objektu, ke kterému bude přiřazeno uživatelské pole
is to be attached

View File

@ -1144,5 +1144,4 @@ es:
label_link_values_to: Enlazar valores a la URL label_link_values_to: Enlazar valores a la URL
setting_force_default_language_for_anonymous: Forzar lenguaje por defecto a usuarios anónimos setting_force_default_language_for_anonymous: Forzar lenguaje por defecto a usuarios anónimos
setting_force_default_language_for_loggedin: Forzar lenguaje por defecto para usuarios identificados setting_force_default_language_for_loggedin: Forzar lenguaje por defecto para usuarios identificados
label_custom_field_select_type: Select the type of object to which the custom field label_custom_field_select_type: Seleccione el tipo de objeto al que unir el campo personalizado
is to be attached

View File

@ -100,7 +100,7 @@ fr:
units: units:
byte: byte:
one: "octet" one: "octet"
other: "octet" other: "octets"
kb: "ko" kb: "ko"
mb: "Mo" mb: "Mo"
gb: "Go" gb: "Go"
@ -146,7 +146,7 @@ fr:
not_same_project: "n'appartient pas au même projet" not_same_project: "n'appartient pas au même projet"
circular_dependency: "Cette relation créerait une dépendance circulaire" circular_dependency: "Cette relation créerait une dépendance circulaire"
cant_link_an_issue_with_a_descendant: "Une demande ne peut pas être liée à l'une de ses sous-tâches" cant_link_an_issue_with_a_descendant: "Une demande ne peut pas être liée à l'une de ses sous-tâches"
earlier_than_minimum_start_date: "ne peut pas être antérieure au %{date} à cause des demandes qui précédent" earlier_than_minimum_start_date: "ne peut pas être antérieure au %{date} à cause des demandes qui précèdent"
actionview_instancetag_blank_option: Choisir actionview_instancetag_blank_option: Choisir
@ -235,13 +235,13 @@ fr:
field_is_required: Obligatoire field_is_required: Obligatoire
field_firstname: Prénom field_firstname: Prénom
field_lastname: Nom field_lastname: Nom
field_mail: "Email " field_mail: Email
field_filename: Fichier field_filename: Fichier
field_filesize: Taille field_filesize: Taille
field_downloads: Téléchargements field_downloads: Téléchargements
field_author: Auteur field_author: Auteur
field_created_on: "Créé " field_created_on: Créé
field_updated_on: "Mis-à-jour " field_updated_on: Mis-à-jour
field_closed_on: Fermé field_closed_on: Fermé
field_field_format: Format field_field_format: Format
field_is_for_all: Pour tous les projets field_is_for_all: Pour tous les projets
@ -266,14 +266,14 @@ fr:
field_fixed_version: Version cible field_fixed_version: Version cible
field_user: Utilisateur field_user: Utilisateur
field_role: Rôle field_role: Rôle
field_homepage: "Site web " field_homepage: Site web
field_is_public: Public field_is_public: Public
field_parent: Sous-projet de field_parent: Sous-projet de
field_is_in_roadmap: Demandes affichées dans la roadmap field_is_in_roadmap: Demandes affichées dans la roadmap
field_login: "Identifiant " field_login: Identifiant
field_mail_notification: Notifications par mail field_mail_notification: Notifications par mail
field_admin: Administrateur field_admin: Administrateur
field_last_login_on: "Dernière connexion " field_last_login_on: Dernière connexion
field_language: Langue field_language: Langue
field_effective_date: Date field_effective_date: Date
field_password: Mot de passe field_password: Mot de passe
@ -547,10 +547,10 @@ fr:
label_login: Connexion label_login: Connexion
label_logout: Déconnexion label_logout: Déconnexion
label_help: Aide label_help: Aide
label_reported_issues: "Demandes soumises " label_reported_issues: Demandes soumises
label_assigned_to_me_issues: Demandes qui me sont assignées label_assigned_to_me_issues: Demandes qui me sont assignées
label_last_login: "Dernière connexion " label_last_login: Dernière connexion
label_registered_on: "Inscrit le " label_registered_on: Inscrit le
label_activity: Activité label_activity: Activité
label_overall_activity: Activité globale label_overall_activity: Activité globale
label_user_activity: "Activité de %{value}" label_user_activity: "Activité de %{value}"
@ -655,7 +655,7 @@ fr:
label_query_plural: Rapports personnalisés label_query_plural: Rapports personnalisés
label_query_new: Nouveau rapport label_query_new: Nouveau rapport
label_my_queries: Mes rapports personnalisés label_my_queries: Mes rapports personnalisés
label_filter_add: "Ajouter le filtre " label_filter_add: Ajouter le filtre
label_filter_plural: Filtres label_filter_plural: Filtres
label_equals: égal label_equals: égal
label_not_equals: différent label_not_equals: différent
@ -688,7 +688,7 @@ fr:
label_repository_new: Nouveau dépôt label_repository_new: Nouveau dépôt
label_repository_plural: Dépôts label_repository_plural: Dépôts
label_browse: Parcourir label_browse: Parcourir
label_revision: "Révision " label_revision: Révision
label_revision_plural: Révisions label_revision_plural: Révisions
label_associated_revisions: Révisions associées label_associated_revisions: Révisions associées
label_added: ajouté label_added: ajouté
@ -708,7 +708,7 @@ fr:
label_roadmap_due_in: "Échéance dans %{value}" label_roadmap_due_in: "Échéance dans %{value}"
label_roadmap_overdue: "En retard de %{value}" label_roadmap_overdue: "En retard de %{value}"
label_roadmap_no_issues: Aucune demande pour cette version label_roadmap_no_issues: Aucune demande pour cette version
label_search: "Recherche " label_search: Recherche
label_result_plural: Résultats label_result_plural: Résultats
label_all_words: Tous les mots label_all_words: Tous les mots
label_wiki: Wiki label_wiki: Wiki
@ -879,7 +879,7 @@ fr:
label_cross_project_system: Avec tous les projets label_cross_project_system: Avec tous les projets
label_gantt_progress_line: Ligne de progression label_gantt_progress_line: Ligne de progression
label_visibility_private: par moi uniquement label_visibility_private: par moi uniquement
label_visibility_roles: par ces roles uniquement label_visibility_roles: par ces rôles uniquement
label_visibility_public: par tout le monde label_visibility_public: par tout le monde
label_link: Lien label_link: Lien
label_only: seulement label_only: seulement
@ -1014,9 +1014,9 @@ fr:
text_project_closed: Ce projet est fermé et accessible en lecture seule. text_project_closed: Ce projet est fermé et accessible en lecture seule.
text_turning_multiple_off: "Si vous désactivez les valeurs multiples, les valeurs multiples seront supprimées pour n'en conserver qu'une par objet." text_turning_multiple_off: "Si vous désactivez les valeurs multiples, les valeurs multiples seront supprimées pour n'en conserver qu'une par objet."
default_role_manager: "Manager " default_role_manager: Manager
default_role_developer: "Développeur " default_role_developer: Développeur
default_role_reporter: "Rapporteur " default_role_reporter: Rapporteur
default_tracker_bug: Anomalie default_tracker_bug: Anomalie
default_tracker_feature: Evolution default_tracker_feature: Evolution
default_tracker_support: Assistance default_tracker_support: Assistance

View File

@ -1135,5 +1135,4 @@ ja:
label_link_values_to: 値に設定するリンクURL label_link_values_to: 値に設定するリンクURL
setting_force_default_language_for_anonymous: 匿名ユーザーに既定の言語を強制 setting_force_default_language_for_anonymous: 匿名ユーザーに既定の言語を強制
setting_force_default_language_for_loggedin: ログインユーザーに既定の言語を強制 setting_force_default_language_for_loggedin: ログインユーザーに既定の言語を強制
label_custom_field_select_type: Select the type of object to which the custom field label_custom_field_select_type: カスタムフィールドを追加するオブジェクトを選択してください
is to be attached

View File

@ -1131,33 +1131,28 @@ ko:
permission_add_documents: 문서 추가 permission_add_documents: 문서 추가
permission_edit_documents: 문서 편집 permission_edit_documents: 문서 편집
permission_delete_documents: 문서 삭제 permission_delete_documents: 문서 삭제
label_gantt_progress_line: Progress line label_gantt_progress_line: 진행 선
setting_jsonp_enabled: JSONP 허용 setting_jsonp_enabled: JSONP 허용
field_inherit_members: 상위 프로젝트로부터 구성원을 상속 field_inherit_members: 상위 프로젝트로부터 구성원을 상속
field_closed_on: 완료일 field_closed_on: 완료일
field_generate_password: Generate password field_generate_password: 비밀번호 생성
setting_default_projects_tracker_ids: 새 프로젝트에 기본적으로 추가할 일감 유형 setting_default_projects_tracker_ids: 새 프로젝트에 기본적으로 추가할 일감 유형
label_total_time: 합계 label_total_time: 합계
notice_account_not_activated_yet: You haven't activated your account yet. If you want notice_account_not_activated_yet: 계정이 활성화되지 않았습니다. 계정을 활성화하기 위해 메일을 다시 수신하려면 <a href="%{url}">여기를 클릭해 주세요</a>.
to receive a new activation email, please <a href="%{url}">click this link</a>. notice_account_locked: 계정이 잠겨 있습니다.
notice_account_locked: Your account is locked. label_hidden: 숨김
label_hidden: Hidden label_visibility_private: 자신 만
label_visibility_private: to me only label_visibility_roles: 다음 역할 만
label_visibility_roles: to these roles only label_visibility_public: 모든 사용자
label_visibility_public: to any users field_must_change_passwd: 다음 로그온 시 반드시 암호를 변경해야 함
field_must_change_passwd: Must change password at next logon notice_new_password_must_be_different: 새 암호는 현재 암호와 달라야 합니다.
notice_new_password_must_be_different: The new password must be different from the setting_mail_handler_excluded_filenames: 제외할 첨부 파일명
current password text_convert_available: ImageMagick 변환 사용 가능 (옵션)
setting_mail_handler_excluded_filenames: Exclude attachments by name label_link: 링크
text_convert_available: ImageMagick convert available (optional) label_only: 다음의 것만
label_link: Link label_drop_down_list: 드롭다운 목록
label_only: only label_checkboxes: 체크박스
label_drop_down_list: drop-down list label_link_values_to: URL 링크 값
label_checkboxes: checkboxes setting_force_default_language_for_anonymous: 익명 사용자의 기본 언어 강제
label_link_values_to: Link values to URL setting_force_default_language_for_loggedin: 로그인 사용자의 기본 언어 강제
setting_force_default_language_for_anonymous: Force default language for anonymous label_custom_field_select_type: 사용자 정의 필드에 추가할 대상을 선택해주세요.
users
setting_force_default_language_for_loggedin: Force default language for logged-in
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached

View File

@ -150,7 +150,7 @@ pl:
# Wiktor Wandachowicz <siryes@gmail.com>, 2010 # Wiktor Wandachowicz <siryes@gmail.com>, 2010
actionview_instancetag_blank_option: Proszę wybrać actionview_instancetag_blank_option: Proszę wybrać
actionview_instancetag_blank_option: Proszę wybierz actionview_instancetag_blank_option: wybierz
button_activate: Aktywuj button_activate: Aktywuj
button_add: Dodaj button_add: Dodaj
@ -228,18 +228,18 @@ pl:
field_attr_lastname: Nazwisko atrybut field_attr_lastname: Nazwisko atrybut
field_attr_login: Login atrybut field_attr_login: Login atrybut
field_attr_mail: E-mail atrybut field_attr_mail: E-mail atrybut
field_auth_source: Tryb identyfikacji field_auth_source: Tryb uwierzytelniania
field_author: Autor field_author: Autor
field_base_dn: Base DN field_base_dn: Base DN
field_category: Kategoria field_category: Kategoria
field_column_names: Nazwy kolumn field_column_names: Nazwy kolumn
field_comments: Komentarz field_comments: Komentarz
field_comments_sorting: Pokazuj komentarze field_comments_sorting: Pokazuj komentarze
field_created_on: Stworzone field_created_on: Data utworzenia
field_default_value: Domyślny field_default_value: Domyślny
field_delay: Opóźnienie field_delay: Opóźnienie
field_description: Opis field_description: Opis
field_done_ratio: "% Wykonane" field_done_ratio: "% Wykonania"
field_downloads: Pobrań field_downloads: Pobrań
field_due_date: Data oddania field_due_date: Data oddania
field_effective_date: Data field_effective_date: Data
@ -298,7 +298,7 @@ pl:
field_title: Tytuł field_title: Tytuł
field_tracker: Typ zagadnienia field_tracker: Typ zagadnienia
field_type: Typ field_type: Typ
field_updated_on: Zmienione field_updated_on: Data modyfikacji
field_url: URL field_url: URL
field_user: Użytkownik field_user: Użytkownik
field_value: Wartość field_value: Wartość
@ -337,10 +337,10 @@ pl:
label_attachment_plural: Pliki label_attachment_plural: Pliki
label_attribute: Atrybut label_attribute: Atrybut
label_attribute_plural: Atrybuty label_attribute_plural: Atrybuty
label_auth_source: Tryb identyfikacji label_auth_source: Tryb uwierzytelniania
label_auth_source_new: Nowy tryb identyfikacji label_auth_source_new: Nowy tryb uwierzytelniania
label_auth_source_plural: Tryby identyfikacji label_auth_source_plural: Tryby uwierzytelniania
label_authentication: Identyfikacja label_authentication: Uwierzytelnianie
label_blocked_by: blokowane przez label_blocked_by: blokowane przez
label_blocks: blokuje label_blocks: blokuje
label_board: Forum label_board: Forum
@ -411,7 +411,7 @@ pl:
label_diff_inline: w linii label_diff_inline: w linii
label_diff_side_by_side: obok siebie label_diff_side_by_side: obok siebie
label_disabled: zablokowany label_disabled: zablokowany
label_display_per_page: "Na stronę: %{value}" label_display_per_page: "Na stronie: %{value}"
label_document: Dokument label_document: Dokument
label_document_added: Dodano dokument label_document_added: Dodano dokument
label_document_new: Nowy dokument label_document_new: Nowy dokument
@ -477,8 +477,8 @@ pl:
label_last_week: ostatni tydzień label_last_week: ostatni tydzień
label_latest_revision: Najnowsza rewizja label_latest_revision: Najnowsza rewizja
label_latest_revision_plural: Najnowsze rewizje label_latest_revision_plural: Najnowsze rewizje
label_ldap_authentication: Autoryzacja LDAP label_ldap_authentication: Uwierzytelnianie LDAP
label_less_than_ago: dni mniej label_less_than_ago: dni temu
label_list: Lista label_list: Lista
label_loading: Ładowanie... label_loading: Ładowanie...
label_logged_as: Zalogowany jako label_logged_as: Zalogowany jako
@ -499,7 +499,7 @@ pl:
label_month: Miesiąc label_month: Miesiąc
label_months_from: miesiące od label_months_from: miesiące od
label_more: Więcej label_more: Więcej
label_more_than_ago: dni więcej label_more_than_ago: dni od teraz
label_my_account: Moje konto label_my_account: Moje konto
label_my_page: Moja strona label_my_page: Moja strona
label_my_projects: Moje projekty label_my_projects: Moje projekty
@ -603,7 +603,7 @@ pl:
label_string: Tekst label_string: Tekst
label_subproject_plural: Podprojekty label_subproject_plural: Podprojekty
label_text: Długi tekst label_text: Długi tekst
label_theme: Temat label_theme: Motyw
label_this_month: ten miesiąc label_this_month: ten miesiąc
label_this_week: ten tydzień label_this_week: ten tydzień
label_this_year: ten rok label_this_year: ten rok
@ -655,7 +655,7 @@ pl:
notice_account_unknown_email: Nieznany użytkownik. notice_account_unknown_email: Nieznany użytkownik.
notice_account_updated: Konto prawidłowo zaktualizowane. notice_account_updated: Konto prawidłowo zaktualizowane.
notice_account_wrong_password: Złe hasło notice_account_wrong_password: Złe hasło
notice_can_t_change_password: To konto ma zewnętrzne źródło identyfikacji. Nie możesz zmienić hasła. notice_can_t_change_password: To konto ma zewnętrzne źródło uwierzytelniania. Nie możesz zmienić hasła.
notice_default_data_loaded: Domyślna konfiguracja została pomyślnie załadowana. notice_default_data_loaded: Domyślna konfiguracja została pomyślnie załadowana.
notice_email_error: "Wystąpił błąd w trakcie wysyłania e-maila (%{value})" notice_email_error: "Wystąpił błąd w trakcie wysyłania e-maila (%{value})"
notice_email_sent: "E-mail został wysłany do %{value}" notice_email_sent: "E-mail został wysłany do %{value}"
@ -666,9 +666,9 @@ pl:
notice_no_issue_selected: "Nie wybrano zagadnienia! Zaznacz zagadnienie, które chcesz edytować." notice_no_issue_selected: "Nie wybrano zagadnienia! Zaznacz zagadnienie, które chcesz edytować."
notice_not_authorized: Nie posiadasz autoryzacji do oglądania tej strony. notice_not_authorized: Nie posiadasz autoryzacji do oglądania tej strony.
notice_successful_connection: Udane nawiązanie połączenia. notice_successful_connection: Udane nawiązanie połączenia.
notice_successful_create: Utworzenie zakończone sukcesem. notice_successful_create: Utworzenie zakończone pomyślnie.
notice_successful_delete: Usunięcie zakończone sukcesem. notice_successful_delete: Usunięcie zakończone pomyślnie.
notice_successful_update: Uaktualnienie zakończone sukcesem. notice_successful_update: Uaktualnienie zakończone pomyślnie.
notice_unable_delete_version: Nie można usunąć wersji notice_unable_delete_version: Nie można usunąć wersji
permission_add_issue_notes: Dodawanie notatek permission_add_issue_notes: Dodawanie notatek
permission_add_issue_watchers: Dodawanie obserwatorów permission_add_issue_watchers: Dodawanie obserwatorów
@ -732,7 +732,7 @@ pl:
setting_autofetch_changesets: Automatyczne pobieranie zmian setting_autofetch_changesets: Automatyczne pobieranie zmian
setting_autologin: Automatyczne logowanie setting_autologin: Automatyczne logowanie
setting_bcc_recipients: Odbiorcy kopii tajnej (kt/bcc) setting_bcc_recipients: Odbiorcy kopii tajnej (kt/bcc)
setting_commit_fix_keywords: Słowa zmieniające status setting_commit_fix_keywords: Słowo zmieniające status
setting_commit_ref_keywords: Słowa tworzące powiązania setting_commit_ref_keywords: Słowa tworzące powiązania
setting_cross_project_issue_relations: Zezwól na powiązania zagadnień między projektami setting_cross_project_issue_relations: Zezwól na powiązania zagadnień między projektami
setting_date_format: Format daty setting_date_format: Format daty
@ -758,7 +758,7 @@ pl:
setting_sys_api_enabled: Włączenie WS do zarządzania repozytorium setting_sys_api_enabled: Włączenie WS do zarządzania repozytorium
setting_text_formatting: Formatowanie tekstu setting_text_formatting: Formatowanie tekstu
setting_time_format: Format czasu setting_time_format: Format czasu
setting_user_format: Własny format wyświetlania setting_user_format: Format wyświetlania użytkownika
setting_welcome_text: Tekst powitalny setting_welcome_text: Tekst powitalny
setting_wiki_compression: Kompresja historii Wiki setting_wiki_compression: Kompresja historii Wiki
status_active: aktywny status_active: aktywny
@ -782,7 +782,7 @@ pl:
text_issue_category_reassign_to: Przydziel zagadnienie do tej kategorii text_issue_category_reassign_to: Przydziel zagadnienie do tej kategorii
text_issue_updated: "Zagadnienie %{id} zostało zaktualizowane (przez %{author})." text_issue_updated: "Zagadnienie %{id} zostało zaktualizowane (przez %{author})."
text_issues_destroy_confirmation: 'Czy jesteś pewien, że chcesz usunąć wskazane zagadnienia?' text_issues_destroy_confirmation: 'Czy jesteś pewien, że chcesz usunąć wskazane zagadnienia?'
text_issues_ref_in_commit_messages: Odwołania do zagadnień w komentarzach zatwierdzeń text_issues_ref_in_commit_messages: Odwołania do zagadnień Redmine w komentarzach w repozytorium
text_length_between: "Długość pomiędzy %{min} i %{max} znaków." text_length_between: "Długość pomiędzy %{min} i %{max} znaków."
text_load_default_configuration: Załaduj domyślną konfigurację text_load_default_configuration: Załaduj domyślną konfigurację
text_min_max_length_info: 0 oznacza brak restrykcji text_min_max_length_info: 0 oznacza brak restrykcji
@ -888,7 +888,7 @@ pl:
label_version_sharing_system: Ze wszystkimi projektami label_version_sharing_system: Ze wszystkimi projektami
label_version_sharing_tree: Z drzewem projektów label_version_sharing_tree: Z drzewem projektów
notice_api_access_key_reseted: Twój klucz dostępu do API został zresetowany. notice_api_access_key_reseted: Twój klucz dostępu do API został zresetowany.
notice_issue_done_ratios_updated: Uaktualnienie % wykonania zakończone sukcesem. notice_issue_done_ratios_updated: Uaktualnienie % wykonania zakończone pomyślnie.
permission_add_subprojects: Tworzenie podprojektów permission_add_subprojects: Tworzenie podprojektów
permission_delete_issue_watchers: Usuń obserwatorów permission_delete_issue_watchers: Usuń obserwatorów
permission_view_issues: Przeglądanie zagadnień permission_view_issues: Przeglądanie zagadnień
@ -935,45 +935,45 @@ pl:
project_module_calendar: Kalendarz project_module_calendar: Kalendarz
button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}" button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
field_text: Text field field_text: Text field
label_user_mail_option_only_owner: Only for things I am the owner of label_user_mail_option_only_owner: Tylko to, czego jestem właścicielem (autorem)
setting_default_notification_option: Default notification option setting_default_notification_option: Domyślna opcja powiadomień
label_user_mail_option_only_my_events: Only for things I watch or I'm involved in label_user_mail_option_only_my_events: "Tylko to, co obserwuję lub w czym biorę udział"
label_user_mail_option_only_assigned: Only for things I am assigned to label_user_mail_option_only_assigned: "Tylko to, do czego jestem przypisany"
label_user_mail_option_none: "Tylko to, co obserwuję lub w czym biorę udział" label_user_mail_option_none: "Brak powiadomień"
field_member_of_group: Assignee's group field_member_of_group: Grupa osoby przypisanej
field_assigned_to_role: Assignee's role field_assigned_to_role: Rola osoby przypisanej
notice_not_authorized_archived_project: The project you're trying to access has been archived. notice_not_authorized_archived_project: The project you're trying to access has been archived.
label_principal_search: "Szukaj użytkownika lub grupy:" label_principal_search: "Szukaj użytkownika lub grupy:"
label_user_search: "Szukaj użytkownika:" label_user_search: "Szukaj użytkownika:"
field_visible: Visible field_visible: Widoczne
setting_commit_logtime_activity_id: Activity for logged time setting_commit_logtime_activity_id: Aktywność dla śledzonego czasu
text_time_logged_by_changeset: Applied in changeset %{value}. text_time_logged_by_changeset: Applied in changeset %{value}.
setting_commit_logtime_enabled: Enable time logging setting_commit_logtime_enabled: Włącz śledzenie czasu
notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max}) notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
setting_gantt_items_limit: Maximum number of items displayed on the gantt chart setting_gantt_items_limit: Maksymalna liczba elementów wyświetlanych na diagramie Gantta
field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text field_warn_on_leaving_unsaved: Ostrzegaj mnie, gdy opuszczam stronę z niezapisanym tekstem
text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page. text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
label_my_queries: My custom queries label_my_queries: Moje kwerendy
text_journal_changed_no_detail: "%{label} updated" text_journal_changed_no_detail: "%{label} updated"
label_news_comment_added: Comment added to a news label_news_comment_added: Dodano komentarz do komunikatu
button_expand_all: Expand all button_expand_all: Rozwiń wszystkie
button_collapse_all: Collapse all button_collapse_all: Zwiń wszystkie
label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
label_bulk_edit_selected_time_entries: Bulk edit selected time entries label_bulk_edit_selected_time_entries: Bulk edit selected time entries
text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)? text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
label_role_anonymous: Anonymous label_role_anonymous: Anonimowy
label_role_non_member: Non member label_role_non_member: Bez roli
label_issue_note_added: Note added label_issue_note_added: Dodano notatkę
label_issue_status_updated: Status updated label_issue_status_updated: Uaktualniono status
label_issue_priority_updated: Priority updated label_issue_priority_updated: Uaktualniono priorytet
label_issues_visibility_own: Issues created by or assigned to the user label_issues_visibility_own: Utworzone lub przypisane do użytkownika
field_issues_visibility: Issues visibility field_issues_visibility: Widoczne zagadnienia
label_issues_visibility_all: All issues label_issues_visibility_all: Wszystkie
permission_set_own_issues_private: Set own issues public or private permission_set_own_issues_private: Ustawianie własnych zagadnień jako prywatne/publiczne
field_is_private: Private field_is_private: Prywatne
permission_set_issues_private: Set issues public or private permission_set_issues_private: Ustawianie zagadnień jako prywatne/publiczne
label_issues_visibility_public: All non private issues label_issues_visibility_public: Wszystkie nie prywatne
text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s). text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
field_commit_logs_encoding: Kodowanie komentarzy zatwierdzeń field_commit_logs_encoding: Kodowanie komentarzy zatwierdzeń
field_scm_path_encoding: Path encoding field_scm_path_encoding: Path encoding
@ -983,12 +983,12 @@ pl:
field_cvs_module: Module field_cvs_module: Module
field_cvsroot: CVSROOT field_cvsroot: CVSROOT
text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo) text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
text_scm_command: Command text_scm_command: Polecenie
text_scm_command_version: Version text_scm_command_version: Wersja
label_git_report_last_commit: Report last commit for files and directories label_git_report_last_commit: Report last commit for files and directories
notice_issue_successful_create: Issue %{id} created. notice_issue_successful_create: Issue %{id} created.
label_between: between label_between: pomiędzy
setting_issue_group_assignment: Allow issue assignment to groups setting_issue_group_assignment: Zezwól przypisywać zagadnienia do grup
label_diff: diff label_diff: diff
text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo) text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
description_query_sort_criteria_direction: Sort direction description_query_sort_criteria_direction: Sort direction
@ -997,7 +997,7 @@ pl:
description_user_mail_notification: Mail notification settings description_user_mail_notification: Mail notification settings
description_date_from: Enter start date description_date_from: Enter start date
description_message_content: Message content description_message_content: Message content
description_available_columns: Available Columns description_available_columns: Dostępne kolumny
description_date_range_interval: Choose range by selecting start and end date description_date_range_interval: Choose range by selecting start and end date
description_issue_category_reassign: Choose issue category description_issue_category_reassign: Choose issue category
description_search: Searchfield description_search: Searchfield
@ -1007,13 +1007,13 @@ pl:
description_date_to: Enter end date description_date_to: Enter end date
description_query_sort_criteria_attribute: Sort attribute description_query_sort_criteria_attribute: Sort attribute
description_wiki_subpages_reassign: Choose new parent page description_wiki_subpages_reassign: Choose new parent page
description_selected_columns: Selected Columns description_selected_columns: Wybrane kolumny
label_parent_revision: Parent label_parent_revision: Parent
label_child_revision: Child label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size. error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues setting_default_issue_start_date_to_creation_date: Użyj bieżącej daty jako daty rozpoczęcia nowych zagadnień
button_edit_section: Edit this section button_edit_section: Edit this section
setting_repositories_encodings: Attachments and repositories encodings setting_repositories_encodings: Kodowanie znaków załączników i repozytoriów
description_all_columns: All Columns description_all_columns: All Columns
button_export: Export button_export: Export
label_export_options: "%{export_format} export options" label_export_options: "%{export_format} export options"
@ -1030,107 +1030,105 @@ pl:
label_completed_versions: Completed versions label_completed_versions: Completed versions
text_project_identifier_info: 'Dozwolone małe litery (a-z), liczby i myślniki.<br />Raz zapisany, identyfikator nie może być zmieniony.' text_project_identifier_info: 'Dozwolone małe litery (a-z), liczby i myślniki.<br />Raz zapisany, identyfikator nie może być zmieniony.'
field_multiple: Multiple values field_multiple: Multiple values
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed setting_commit_cross_project_ref: Zezwól na odwołania do innych projektów i zamykanie zagadnień innych projektów
text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten) text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
notice_issue_update_conflict: The issue has been updated by an other user while you were editing it. notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link} text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
permission_manage_related_issues: Manage related issues permission_manage_related_issues: Zarządzanie powiązanymi zagadnieniami
field_auth_source_ldap_filter: LDAP filter field_auth_source_ldap_filter: LDAP filter
label_search_for_watchers: Search for watchers to add label_search_for_watchers: Wyszukaj obserwatorów do dodania
notice_account_deleted: Your account has been permanently deleted. notice_account_deleted: Twoje konto zostało trwale usunięte.
setting_unsubscribe: Allow users to delete their own account setting_unsubscribe: Zezwól użytkownikom usuwać swoje konta
button_delete_my_account: Delete my account button_delete_my_account: Usuń moje konto
text_account_destroy_confirmation: |- text_account_destroy_confirmation: |-
Are you sure you want to proceed? Czy jesteś pewien?
Your account will be permanently deleted, with no way to reactivate it. Twoje konto zostanie trwale usunięte, bez możliwości przywrócenia go.
error_session_expired: Your session has expired. Please login again. error_session_expired: Twoja sesja wygasła. Zaloguj się ponownie.
text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours." text_session_expiration_settings: "Uwaga: zmiana tych ustawień może spowodować przeterminowanie sesji obecnie zalogowanych użytkowników, w tym twojej."
setting_session_lifetime: Session maximum lifetime setting_session_lifetime: Maksymalny czas życia sesji
setting_session_timeout: Session inactivity timeout setting_session_timeout: Maksymalny czas życia nieaktywnej sesji
label_session_expiration: Session expiration label_session_expiration: Przeterminowywanie sesji
permission_close_project: Close / reopen the project permission_close_project: Zamykanie / otwieranie projektów
label_show_closed_projects: View closed projects label_show_closed_projects: Przeglądanie zamkniętych projektów
button_close: Close button_close: Zamknij projekt
button_reopen: Reopen button_reopen: Otwórz projekt
project_status_active: active project_status_active: aktywny
project_status_closed: closed project_status_closed: zamknięty
project_status_archived: archived project_status_archived: zarchiwizowany
text_project_closed: This project is closed and read-only. text_project_closed: Ten projekt jest zamknięty i dostępny tylko do odczytu.
notice_user_successful_create: User %{id} created. notice_user_successful_create: Utworzono użytkownika %{id}.
field_core_fields: Standard fields field_core_fields: Pola standardowe
field_timeout: Timeout (in seconds) field_timeout: Limit czasu (w sekundach)
setting_thumbnails_enabled: Display attachment thumbnails setting_thumbnails_enabled: Wyświetlaj miniatury załączników
setting_thumbnails_size: Thumbnails size (in pixels) setting_thumbnails_size: Rozmiar minuatury (w pikselach)
label_status_transitions: Status transitions label_status_transitions: Przejścia między statusami
label_fields_permissions: Fields permissions label_fields_permissions: Uprawnienia do pól
label_readonly: Read-only label_readonly: Tylko do odczytu
label_required: Required label_required: Wymagane
text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed. text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
field_board_parent: Parent forum field_board_parent: Parent forum
label_attribute_of_project: Project's %{name} label_attribute_of_project: Project's %{name}
label_attribute_of_author: Author's %{name} label_attribute_of_author: Author's %{name}
label_attribute_of_assigned_to: Assignee's %{name} label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: Target version's %{name} label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: Copy subtasks label_copy_subtasks: Kopiuj podzagadnienia
label_copied_to: copied to label_copied_to: skopiowane do
label_copied_from: copied from label_copied_from: skopiowane z
label_any_issues_in_project: any issues in project label_any_issues_in_project: dowolne zagadnienie w projekcie
label_any_issues_not_in_project: any issues not in project label_any_issues_not_in_project: dowolne zagadnienie w innym projekcie
field_private_notes: Private notes field_private_notes: Prywatne notatki
permission_view_private_notes: View private notes permission_view_private_notes: Podgląd prywatnych notatek
permission_set_notes_private: Set notes as private permission_set_notes_private: Ustawianie notatek jako prywatnych
label_no_issues_in_project: no issues in project label_no_issues_in_project: brak zagadnień w projekcie
label_any: wszystko label_any: wszystko
label_last_n_weeks: last %{count} weeks label_last_n_weeks: ostatnie %{count} tygodnie
setting_cross_project_subtasks: Allow cross-project subtasks setting_cross_project_subtasks: Powiązania zagadnień między projektami
label_cross_project_descendants: Z podprojektami label_cross_project_descendants: Z podprojektami
label_cross_project_tree: Z drzewem projektów label_cross_project_tree: Z drzewem projektów
label_cross_project_hierarchy: Z hierarchią projektów label_cross_project_hierarchy: Z hierarchią projektów
label_cross_project_system: Ze wszystkimi projektami label_cross_project_system: Ze wszystkimi projektami
button_hide: Hide button_hide: Ukryj
setting_non_working_week_days: Non-working days setting_non_working_week_days: Dni nie-robocze
label_in_the_next_days: in the next label_in_the_next_days: w ciągu następnych dni
label_in_the_past_days: in the past label_in_the_past_days: w ciągu poprzednich dni
label_attribute_of_user: User's %{name} label_attribute_of_user: User's %{name}
text_turning_multiple_off: If you disable multiple values, multiple values will be text_turning_multiple_off: If you disable multiple values, multiple values will be
removed in order to preserve only one value per item. removed in order to preserve only one value per item.
label_attribute_of_issue: Issue's %{name} label_attribute_of_issue: Issue's %{name}
permission_add_documents: Add documents permission_add_documents: Dodawanie dokumentów
permission_edit_documents: Edit documents permission_edit_documents: Edycja dokumentów
permission_delete_documents: Delete documents permission_delete_documents: Usuwanie dokumentów
label_gantt_progress_line: Progress line label_gantt_progress_line: Linia postępu
setting_jsonp_enabled: Enable JSONP support setting_jsonp_enabled: Uaktywnij wsparcie dla JSONP
field_inherit_members: Inherit members field_inherit_members: Dziedziczenie członków
field_closed_on: Closed field_closed_on: Data zamknięcia
field_generate_password: Generate password field_generate_password: Wygeneruj hasło
setting_default_projects_tracker_ids: Default trackers for new projects setting_default_projects_tracker_ids: Domyślne typy zagadnień dla nowych projektów
label_total_time: Ogółem label_total_time: Ogółem
text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it. text_scm_config: Możesz skonfigurować polecenia SCM w pliku config/configuration.yml. Zrestartuj aplikację po wykonaniu zmian.
text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel. text_scm_command_not_available: Polecenie SCM nie jest dostępne. Proszę sprawdzić ustawienia w panelu administracyjnym.
setting_emails_header: Email header setting_emails_header: Nagłówek e-maili
notice_account_not_activated_yet: You haven't activated your account yet. If you want notice_account_not_activated_yet: Jeszcze nie aktywowałeś swojego konta. Jeśli chcesz
to receive a new activation email, please <a href="%{url}">click this link</a>. otrzymać nowy e-mail aktywanyjny, <a href="%{url}">kliknij tutaj</a>.
notice_account_locked: Your account is locked. notice_account_locked: Twoje konto jest zablokowane.
notice_account_register_done: Account was successfully created. An email containing notice_account_register_done: Konto zostało pomyślnie utworzone. E-mail zawierający
the instructions to activate your account was sent to %{email}. instrukcję aktywacji konta został wysłany na adres %{email}.
label_hidden: Hidden label_hidden: Hidden
label_visibility_private: to me only label_visibility_private: tylko dla mnie
label_visibility_roles: to these roles only label_visibility_roles: tylko dla ról
label_visibility_public: to any users label_visibility_public: dla wszystkich
field_must_change_passwd: Must change password at next logon field_must_change_passwd: Musi zmienić hasło przy następnym logowaniu
notice_new_password_must_be_different: The new password must be different from the notice_new_password_must_be_different: The new password must be different from the
current password current password
setting_mail_handler_excluded_filenames: Exclude attachments by name setting_mail_handler_excluded_filenames: Wyklucz załączniki wg nazwy
text_convert_available: ImageMagick convert available (optional) text_convert_available: Konwersja przez ImageMagick dostępna (optional)
label_link: Link label_link: Link
label_only: only label_only: only
label_drop_down_list: drop-down list label_drop_down_list: drop-down list
label_checkboxes: checkboxes label_checkboxes: checkboxes
label_link_values_to: Link values to URL label_link_values_to: Link values to URL
setting_force_default_language_for_anonymous: Force default language for anonymous setting_force_default_language_for_anonymous: Wymuś domyślny język dla anonimowych użytkowników
users setting_force_default_language_for_loggedin: Wymuś domyślny język dla zalogowanych użytkowników
setting_force_default_language_for_loggedin: Force default language for logged-in
users
label_custom_field_select_type: Select the type of object to which the custom field label_custom_field_select_type: Select the type of object to which the custom field
is to be attached is to be attached

View File

@ -1217,5 +1217,4 @@ ru:
label_link_values_to: Значения ссылки для URL label_link_values_to: Значения ссылки для URL
setting_force_default_language_for_anonymous: Не определять язык для анонимных пользователей setting_force_default_language_for_anonymous: Не определять язык для анонимных пользователей
setting_force_default_language_for_loggedin: Не определять язык для зарегистрированных пользователей setting_force_default_language_for_loggedin: Не определять язык для зарегистрированных пользователей
label_custom_field_select_type: Select the type of object to which the custom field label_custom_field_select_type: Выберите тип объекта для которого будет создано настраиваемое поле
is to be attached

View File

@ -357,7 +357,7 @@ tr:
label_tracker_new: Yeni iş tipi label_tracker_new: Yeni iş tipi
label_workflow: İş akışı label_workflow: İş akışı
label_issue_status: İş durumu label_issue_status: İş durumu
label_issue_status_plural: İş durumuları label_issue_status_plural: İş durumları
label_issue_status_new: Yeni durum label_issue_status_new: Yeni durum
label_issue_category: İş kategorisi label_issue_category: İş kategorisi
label_issue_category_plural: İş kategorileri label_issue_category_plural: İş kategorileri

View File

@ -0,0 +1,12 @@
class ChangeChangesetsCommentsLimit < ActiveRecord::Migration
def up
if ActiveRecord::Base.connection.adapter_name =~ /mysql/i
max_size = 16.megabytes
change_column :changesets, :comments, :text, :limit => max_size
end
end
def down
# no-op
end
end

View File

@ -4,6 +4,83 @@ Redmine - project management software
Copyright (C) 2006-2014 Jean-Philippe Lang Copyright (C) 2006-2014 Jean-Philippe Lang
http://www.redmine.org/ http://www.redmine.org/
== 2014-03-29 v2.5.1
* Defect #14298: Error generated on 'search for watchers to add' after clicking add without selected users
* Defect #16236: Right-aligned table of contents (TOC) not working with markdown
* Defect #16255: Internal Error for specific version of non-existent wiki page
* Defect #16259: Changing Tracker value on new issue form makes hidden fields appearing after hitting F5
* Defect #16321: Custom Fields with "Link values to URL" set are displayed as escaped html in email
* Defect #16338: Can't choose an issue of a different project when updating time entries
* Defect #16353: Regexp bug in JournalsController regexp handling when quoting existing journal entries
* Feature #16326: Custom queries, buttons to move column to top and bottom
* Patch #16291: Japanese translation update
* Patch #16319: Random crash when using custom fields
* Patch #16320: Turkish typo fix
* Patch #16334: Korean Translation
* Patch #16336: Russian translation
* Patch #16356: Spanish Translation: label_custom_field_select_type
* Patch #16368: Polish translation update
* Patch #16381: Extract code to render project context links to helper
* Patch #16453: Czech localisation
* Defect #16466: Fixed back url verification
== 2014-03-02 v2.5.0
* Defect #3163: Large inline images overflow
* Defect #13385: Searchable checkbox displayed on edit form for not-searchable custom field formats.
* Defect #13396: Updating an issue with user or list format custom field, currently having value that is locked or removed, clears that field
* Defect #14361: Mercurial commit ids are short (12 digits) on database
* Defect #15377: bundle install --without development test fails
* Defect #15381: Error pages improvement
* Defect #15485: HTML 5 validation multiple ids
* Defect #15551: Validating a Setting with invalid name triggers an error
* Defect #15552: Preferences are not preserved after adding user with validation error
* Defect #15704: Journal for relation should store relation type instead of i18n key
* Defect #15709: TimeEntry custom_values are not deleted from the database when destroying the associated project
* Defect #15831: Successful update notice for workflows
* Defect #15848: REST API: Cannot retrieve memberships of closed projects
* Defect #15929: REST API: Integer custom field validation fails when using non-string values
* Defect #15947: Deadlock when delete issues in same time on multiple sessions
* Defect #15983: Project.activities returns different types depending on context
* Defect #16077: Table of contents macro conflicts with collapse macro
* Defect #16091: Export CSV with many custom field runs many queries
* Defect #16107: ApplicationController mishandles non-Basic authentication information, causing an internal error
* Defect #16143: Can't insert too long comment field from repository (MySQL)
* Feature #1179: Optionally allow Text and Long Text custom fields support wiki formatting
* Feature #1358: Link_to for Custom Field
* Feature #2083: CustomField of type "external-link-to" with configurable URL prefix
* Feature #2549: Enable the watching of news
* Feature #2691: Option to disable automated language-guessing based on HTTP_ACCEPT_LANGUAGE HTTP-header
* Feature #8152: Render Version and User custom fields as links
* Feature #8562: Watchers list too big in new issue form
* Feature #8572: Configuration of which versions (by version-status) are shown in version-format custom fields
* Feature #8842: REST API: Filter issues created/updated before or after specific timestamp
* Feature #13134: Focus first text field automatically
* Feature #14309: Add favicon to Atom feeds
* Feature #15275: Improve usage of label "button_update"
* Feature #15362: Wrap filters, options and buttons with extra div on the issue list
* Feature #15520: Markdown formatting
* Feature #15699: Description for custom fields
* Feature #15701: Add project identifier substitution option to the URL-pattern property of link format custom fields
* Feature #15790: Use the mime-types gem to get mime type for unknown extension
* Feature #15815: REST API : Add project status in API response
* Feature #15926: Redirect to back_url or referer when clicking "Sign in" while already logged-in
* Patch #12753: Update config.i18n.load_path for plugin-supplied locales
* Patch #13774: Show warning if CSV-Export exceeds limit
* Patch #14766: Better block detection on my page
* Patch #15403: Czech "message" and "changeset" translation change
* Patch #15420: Don't create duplicate wikis in tests
* Patch #15689: Make favicon themeable
* Patch #15785: Support more character encodings in incoming emails
== 2014-03-02 v2.4.4
* Defect #16081: Export CSV - Custom field true/false not using translation
* Defect #16161: Parent task search and datepicker not available after changing status
* Defect #16169: Wrong validation when updating integer custom field with spaces
* Defect #16177: Mercurial 2.9 compatibility
== 2014-02-08 v2.4.3 == 2014-02-08 v2.4.3
* Defect #13544: Commit reference: autogenerated issue note has wrong commit link syntax in multi-repo or cross-project context * Defect #13544: Commit reference: autogenerated issue note has wrong commit link syntax in multi-repo or cross-project context
@ -16,6 +93,11 @@ http://www.redmine.org/
* Defect #16038: Issue#css_classes corrupts user.groups association cache * Defect #16038: Issue#css_classes corrupts user.groups association cache
* Patch #15960: pt-BR translation for 2.4-stable * Patch #15960: pt-BR translation for 2.4-stable
Additional note:
#15781 was forgotten to merge to v2.4.3.
It is in v2.5.0.
== 2013-12-23 v2.4.2 == 2013-12-23 v2.4.2
* Defect #15398: HTML 5 invalid <center> tag * Defect #15398: HTML 5 invalid <center> tag

View File

@ -131,7 +131,8 @@ module Redmine
# Returns the validation error messages for custom_value # Returns the validation error messages for custom_value
# Should return an empty array if custom_value is valid # Should return an empty array if custom_value is valid
def validate_custom_value(custom_value) def validate_custom_value(custom_value)
errors = Array.wrap(custom_value.value).reject(&:blank?).map do |value| values = Array.wrap(custom_value.value).reject {|value| value.to_s == ''}
errors = values.map do |value|
validate_single_value(custom_value.custom_field, value, custom_value.customized) validate_single_value(custom_value.custom_field, value, custom_value.customized)
end end
errors.flatten.uniq errors.flatten.uniq
@ -147,7 +148,7 @@ module Redmine
def formatted_value(view, custom_field, value, customized=nil, html=false) def formatted_value(view, custom_field, value, customized=nil, html=false)
casted = cast_value(custom_field, value, customized) casted = cast_value(custom_field, value, customized)
if custom_field.url_pattern.present? if html && custom_field.url_pattern.present?
texts_and_urls = Array.wrap(casted).map do |single_value| texts_and_urls = Array.wrap(casted).map do |single_value|
text = view.format_object(single_value, false).to_s text = view.format_object(single_value, false).to_s
url = url_from_pattern(custom_field, single_value, customized) url = url_from_pattern(custom_field, single_value, customized)
@ -252,16 +253,15 @@ module Redmine
class Unbounded < Base class Unbounded < Base
def validate_single_value(custom_field, value, customized=nil) def validate_single_value(custom_field, value, customized=nil)
errs = super errs = super
if value.present? value = value.to_s
unless custom_field.regexp.blank? or value =~ Regexp.new(custom_field.regexp) unless custom_field.regexp.blank? or value =~ Regexp.new(custom_field.regexp)
errs << ::I18n.t('activerecord.errors.messages.invalid') errs << ::I18n.t('activerecord.errors.messages.invalid')
end end
if custom_field.min_length && value.length < custom_field.min_length if custom_field.min_length && value.length < custom_field.min_length
errs << ::I18n.t('activerecord.errors.messages.too_short', :count => custom_field.min_length) errs << ::I18n.t('activerecord.errors.messages.too_short', :count => custom_field.min_length)
end end
if custom_field.max_length && custom_field.max_length > 0 && value.length > custom_field.max_length if custom_field.max_length && custom_field.max_length > 0 && value.length > custom_field.max_length
errs << ::I18n.t('activerecord.errors.messages.too_long', :count => custom_field.max_length) errs << ::I18n.t('activerecord.errors.messages.too_long', :count => custom_field.max_length)
end
end end
errs errs
end end
@ -528,8 +528,9 @@ module Redmine
end end
def validate_custom_value(custom_value) def validate_custom_value(custom_value)
invalid_values = Array.wrap(custom_value.value) - Array.wrap(custom_value.value_was) - custom_value.custom_field.possible_values values = Array.wrap(custom_value.value).reject {|value| value.to_s == ''}
if invalid_values.select(&:present?).any? invalid_values = values - Array.wrap(custom_value.value_was) - custom_value.custom_field.possible_values
if invalid_values.any?
[::I18n.t('activerecord.errors.messages.inclusion')] [::I18n.t('activerecord.errors.messages.inclusion')]
else else
[] []

View File

@ -79,8 +79,13 @@ def _tags(ui, repo):
def _branches(ui, repo): def _branches(ui, repo):
# see mercurial/commands.py:branches # see mercurial/commands.py:branches
def iterbranches(): def iterbranches():
for t, n in repo.branchtags().iteritems(): if getattr(repo, 'branchtags', None) is not None:
yield t, n, repo.changelog.rev(n) # Mercurial < 2.9
for t, n in repo.branchtags().iteritems():
yield t, n, repo.changelog.rev(n)
else:
for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
yield tag, tip, repo.changelog.rev(tip)
def branchheads(branch): def branchheads(branch):
try: try:
return repo.branchheads(branch, closed=False) return repo.branchheads(branch, closed=False)

View File

@ -17,6 +17,8 @@
require 'redmine/scm/adapters/abstract_adapter' require 'redmine/scm/adapters/abstract_adapter'
require 'cgi' require 'cgi'
require 'rubygems'
require 'UniversalDetector'
module Redmine module Redmine
module Scm module Scm
@ -255,7 +257,18 @@ module Redmine
diff = [] diff = []
hg *hg_args do |io| hg *hg_args do |io|
io.each_line do |line| io.each_line do |line|
diff << line iconv_line = line
if !line.nil?
detected = UniversalDetector::chardet(line)
enc = detected['encoding']
if !enc.nil?
begin
iconv_line = Iconv.conv('UTF-8', enc, line)
rescue Iconv::Failure => err
end
end
end
diff << iconv_line
end end
end end
diff diff
@ -267,7 +280,18 @@ module Redmine
p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path)) p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path))
hg 'rhcat', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io| hg 'rhcat', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io|
io.binmode io.binmode
io.read str = io.read
return nil if str.nil?
iconv_str = str
detected = UniversalDetector::chardet(str)
enc = detected['encoding']
if !enc.nil?
begin
iconv_str = Iconv.conv('UTF-8', enc, str)
rescue Iconv::Failure => err
end
end
return iconv_str
end end
rescue HgCommandAborted rescue HgCommandAborted
nil # means not found nil # means not found
@ -282,7 +306,19 @@ module Redmine
next unless line =~ %r{^([^:]+)\s(\d+)\s([0-9a-f]+):\s(.*)$} next unless line =~ %r{^([^:]+)\s(\d+)\s([0-9a-f]+):\s(.*)$}
r = Revision.new(:author => $1.strip, :revision => $2, :scmid => $3, r = Revision.new(:author => $1.strip, :revision => $2, :scmid => $3,
:identifier => $3) :identifier => $3)
blame.add_line($4.rstrip, r) str = $4.rstrip
iconv_str = str
if !str.nil?
detected = UniversalDetector::chardet(str)
enc = detected['encoding']
if !enc.nil?
begin
iconv_str = Iconv.conv('UTF-8', enc, str)
rescue Iconv::Failure => err
end
end
end
blame.add_line(iconv_str, r)
end end
end end
blame blame

View File

@ -3,14 +3,14 @@ require 'rexml/document'
module Redmine module Redmine
module VERSION #:nodoc: module VERSION #:nodoc:
MAJOR = 2 MAJOR = 2
MINOR = 4 MINOR = 5
TINY = 3 TINY = 1
# Branch values: # Branch values:
# * official release: nil # * official release: nil
# * stable branch: stable # * stable branch: stable
# * trunk: devel # * trunk: devel
BRANCH = 'devel' BRANCH = 'stable'
# Retrieves the revision from the working copy # Retrieves the revision from the working copy
def self.revision def self.revision

View File

@ -221,7 +221,7 @@ module Redmine
out = ''.html_safe out = ''.html_safe
out << link_to_function(show_label, js, :id => "#{html_id}-show", :class => 'collapsible collapsed') out << link_to_function(show_label, js, :id => "#{html_id}-show", :class => 'collapsible collapsed')
out << link_to_function(hide_label, js, :id => "#{html_id}-hide", :class => 'collapsible', :style => 'display:none;') out << link_to_function(hide_label, js, :id => "#{html_id}-hide", :class => 'collapsible', :style => 'display:none;')
out << content_tag('div', textilizable(text, :object => obj), :id => html_id, :class => 'collapsed-text', :style => 'display:none;') out << content_tag('div', textilizable(text, :object => obj, :headings => false), :id => html_id, :class => 'collapsed-text', :style => 'display:none;')
out out
end end

View File

@ -51,6 +51,17 @@ function moveOptionUp(theSel) {
} }
} }
function moveOptionTop(theSel) {
var index = theSel.selectedIndex;
if (index > 0) {
for (i=index; i>0; i--) {
swapOptions(theSel, i-1, i);
}
theSel.selectedIndex = 0;
}
}
function moveOptionDown(theSel) { function moveOptionDown(theSel) {
var index = theSel.selectedIndex; var index = theSel.selectedIndex;
if (index < theSel.length - 1) { if (index < theSel.length - 1) {
@ -59,6 +70,17 @@ function moveOptionDown(theSel) {
} }
} }
function moveOptionBottom(theSel) {
var index = theSel.selectedIndex;
var indexTop = theSel.length - 1;
if (index < theSel.length - 1) {
for (i=index; i<indexTop; i++) {
swapOptions(theSel, i+1, i);
}
theSel.selectedIndex = indexTop;
}
}
// OK // OK
function selectAllOptions(id) { function selectAllOptions(id) {
var select = $('#'+id); var select = $('#'+id);

View File

@ -125,7 +125,7 @@ table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%;
table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; } table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
table.list td {text-align:center; vertical-align:top; padding-right:10px;} table.list td {text-align:center; vertical-align:top; padding-right:10px;}
table.list td.id { width: 2%; text-align: center;} table.list td.id { width: 2%; text-align: center;}
table.list td.name, table.list td.description, table.list td.subject, table.list td.comments {text-align: left;} table.list td.name, table.list td.description, table.list td.subject, table.list td.comments, table.list td.roles {text-align: left;}
table.list td.tick {width:15%} table.list td.tick {width:15%}
table.list td.checkbox { width: 15px; padding: 2px 0 0 0; } table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
table.list td.checkbox input {padding:0px;} table.list td.checkbox input {padding:0px;}
@ -263,6 +263,7 @@ table.query-columns td.buttons {
vertical-align: middle; vertical-align: middle;
text-align: center; text-align: center;
} }
table.query-columns td.buttons input[type=button] {width:35px;}
td.center {text-align:center;} td.center {text-align:center;}

View File

@ -66,8 +66,14 @@ class AccountControllerTest < ActionController::TestCase
end end
def test_login_should_not_redirect_to_another_host def test_login_should_not_redirect_to_another_host
post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.foo/fake' back_urls = [
assert_redirected_to '/my/page' 'http://test.foo/fake',
'//test.foo/fake'
]
back_urls.each do |back_url|
post :login, :username => 'jsmith', :password => 'jsmith', :back_url => back_url
assert_redirected_to '/my/page'
end
end end
def test_login_with_wrong_password def test_login_with_wrong_password

View File

@ -26,7 +26,7 @@ class RepositoriesMercurialControllerTest < ActionController::TestCase
REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
CHAR_1_HEX = "\xc3\x9c" CHAR_1_HEX = "\xc3\x9c"
PRJ_ID = 3 PRJ_ID = 3
NUM_REV = 32 NUM_REV = 34
ruby19_non_utf8_pass = ruby19_non_utf8_pass =
(RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8') (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')

View File

@ -289,6 +289,28 @@ class TimelogControllerTest < ActionController::TestCase
assert_equal 2, entry.user_id assert_equal 2, entry.user_id
end end
def test_update_should_allow_to_change_issue_to_another_project
entry = TimeEntry.generate!(:issue_id => 1)
@request.session[:user_id] = 1
put :update, :id => entry.id, :time_entry => {:issue_id => '5'}
assert_response 302
entry.reload
assert_equal 5, entry.issue_id
assert_equal 3, entry.project_id
end
def test_update_should_not_allow_to_change_issue_to_an_invalid_project
entry = TimeEntry.generate!(:issue_id => 1)
Project.find(3).disable_module!(:time_tracking)
@request.session[:user_id] = 1
put :update, :id => entry.id, :time_entry => {:issue_id => '5'}
assert_response 200
assert_include "Issue is invalid", assigns(:time_entry).errors.full_messages
end
def test_get_bulk_edit def test_get_bulk_edit
@request.session[:user_id] = 2 @request.session[:user_id] = 2
get :bulk_edit, :ids => [1, 2] get :bulk_edit, :ids => [1, 2]

View File

@ -237,6 +237,13 @@ class WatchersControllerTest < ActionController::TestCase
end end
end end
def test_append_without_user_should_render_nothing
@request.session[:user_id] = 2
xhr :post, :append, :project_id => 'ecookbook'
assert_response :success
assert response.body.blank?
end
def test_remove_watcher def test_remove_watcher
@request.session[:user_id] = 2 @request.session[:user_id] = 2
assert_difference('Watcher.count', -1) do assert_difference('Watcher.count', -1) do

View File

@ -161,6 +161,11 @@ class WikiControllerTest < ActionController::TestCase
assert_template 'edit' assert_template 'edit'
end end
def test_show_specific_version_of_an_unexistent_page_without_edit_right
get :show, :project_id => 1, :id => 'Unexistent page', :version => 1
assert_response 404
end
def test_show_unexistent_page_with_parent_should_preselect_parent def test_show_unexistent_page_with_parent_should_preselect_parent
@request.session[:user_id] = 2 @request.session[:user_id] = 2
get :show, :project_id => 1, :id => 'Unexistent page', :parent => 'Another_page' get :show, :project_id => 1, :id => 'Unexistent page', :parent => 'Another_page'

View File

@ -28,6 +28,29 @@ class Redmine::ApiTest::AuthenticationTest < Redmine::ApiTest::Base
Setting.rest_api_enabled = '0' Setting.rest_api_enabled = '0'
end end
def test_api_should_trigger_basic_http_auth_with_basic_authorization_header
ApplicationController.any_instance.expects(:authenticate_with_http_basic).once
get '/users/current.xml', {}, credentials('jsmith')
assert_response 401
end
def test_api_should_not_trigger_basic_http_auth_with_non_basic_authorization_header
ApplicationController.any_instance.expects(:authenticate_with_http_basic).never
get '/users/current.xml', {}, 'HTTP_AUTHORIZATION' => 'Digest foo bar'
assert_response 401
end
def test_invalid_utf8_credentials_should_not_trigger_an_error
invalid_utf8 = "\x82"
if invalid_utf8.respond_to?(:force_encoding)
invalid_utf8.force_encoding('UTF-8')
assert !invalid_utf8.valid_encoding?
end
assert_nothing_raised do
get '/users/current.xml', {}, credentials(invalid_utf8, "foo")
end
end
def test_api_request_should_not_use_user_session def test_api_request_should_not_use_user_session
log_user('jsmith', 'jsmith') log_user('jsmith', 'jsmith')

View File

@ -119,6 +119,14 @@ class ActiveSupport::TestCase
User.current = saved_user User.current = saved_user
end end
def with_locale(locale, &block)
saved_localed = ::I18n.locale
::I18n.locale = locale
yield
ensure
::I18n.locale = saved_localed
end
def change_user_password(login, new_password) def change_user_password(login, new_password)
user = User.where(:login => login).first user = User.where(:login => login).first
user.password, user.password_confirmation = new_password, new_password user.password, user.password_confirmation = new_password, new_password

View File

@ -113,9 +113,8 @@ class Redmine::UiTest::IssuesTest < Redmine::UiTest::Base
assert page.has_no_content?('Some Watcher') assert page.has_no_content?('Some Watcher')
click_link 'Search for watchers to add' click_link 'Search for watchers to add'
within('form#new-watcher-form') do within('form#new-watcher-form') do
assert page.has_content?('Some One')
fill_in 'user_search', :with => 'watch' fill_in 'user_search', :with => 'watch'
assert page.has_no_content?('Some One') assert page.has_content?('Some Watcher')
check 'Some Watcher' check 'Some Watcher'
click_button 'Add' click_button 'Add'
end end

View File

@ -536,6 +536,17 @@ class ChangesetTest < ActiveSupport::TestCase
end end
end end
def test_comments_should_accept_more_than_64k
c = Changeset.new(:repository => Repository.first,
:committed_on => Time.now,
:revision => '123',
:scmid => '12345',
:comments => "a" * 500.kilobyte)
assert c.save
c.reload
assert_equal 500.kilobyte, c.comments.size
end
def test_identifier def test_identifier
c = Changeset.find_by_revision('1') c = Changeset.find_by_revision('1')
assert_equal c.revision, c.identifier assert_equal c.revision, c.identifier

View File

@ -146,6 +146,7 @@ class CustomFieldTest < ActiveSupport::TestCase
assert f.valid_field_value?(nil) assert f.valid_field_value?(nil)
assert f.valid_field_value?('') assert f.valid_field_value?('')
assert !f.valid_field_value?(' ')
assert f.valid_field_value?('a' * 2) assert f.valid_field_value?('a' * 2)
assert !f.valid_field_value?('a') assert !f.valid_field_value?('a')
assert !f.valid_field_value?('a' * 6) assert !f.valid_field_value?('a' * 6)
@ -156,6 +157,7 @@ class CustomFieldTest < ActiveSupport::TestCase
assert f.valid_field_value?(nil) assert f.valid_field_value?(nil)
assert f.valid_field_value?('') assert f.valid_field_value?('')
assert !f.valid_field_value?(' ')
assert f.valid_field_value?('ABC') assert f.valid_field_value?('ABC')
assert !f.valid_field_value?('abc') assert !f.valid_field_value?('abc')
end end
@ -165,6 +167,7 @@ class CustomFieldTest < ActiveSupport::TestCase
assert f.valid_field_value?(nil) assert f.valid_field_value?(nil)
assert f.valid_field_value?('') assert f.valid_field_value?('')
assert !f.valid_field_value?(' ')
assert f.valid_field_value?('1975-07-14') assert f.valid_field_value?('1975-07-14')
assert !f.valid_field_value?('1975-07-33') assert !f.valid_field_value?('1975-07-33')
assert !f.valid_field_value?('abc') assert !f.valid_field_value?('abc')
@ -175,6 +178,7 @@ class CustomFieldTest < ActiveSupport::TestCase
assert f.valid_field_value?(nil) assert f.valid_field_value?(nil)
assert f.valid_field_value?('') assert f.valid_field_value?('')
assert !f.valid_field_value?(' ')
assert f.valid_field_value?('value2') assert f.valid_field_value?('value2')
assert !f.valid_field_value?('abc') assert !f.valid_field_value?('abc')
end end
@ -184,6 +188,7 @@ class CustomFieldTest < ActiveSupport::TestCase
assert f.valid_field_value?(nil) assert f.valid_field_value?(nil)
assert f.valid_field_value?('') assert f.valid_field_value?('')
assert !f.valid_field_value?(' ')
assert f.valid_field_value?('123') assert f.valid_field_value?('123')
assert f.valid_field_value?('+123') assert f.valid_field_value?('+123')
assert f.valid_field_value?('-123') assert f.valid_field_value?('-123')
@ -195,6 +200,7 @@ class CustomFieldTest < ActiveSupport::TestCase
assert f.valid_field_value?(nil) assert f.valid_field_value?(nil)
assert f.valid_field_value?('') assert f.valid_field_value?('')
assert !f.valid_field_value?(' ')
assert f.valid_field_value?('11.2') assert f.valid_field_value?('11.2')
assert f.valid_field_value?('-6.250') assert f.valid_field_value?('-6.250')
assert f.valid_field_value?('5') assert f.valid_field_value?('5')
@ -206,9 +212,11 @@ class CustomFieldTest < ActiveSupport::TestCase
assert f.valid_field_value?(nil) assert f.valid_field_value?(nil)
assert f.valid_field_value?('') assert f.valid_field_value?('')
assert !f.valid_field_value?(' ')
assert f.valid_field_value?([]) assert f.valid_field_value?([])
assert f.valid_field_value?([nil]) assert f.valid_field_value?([nil])
assert f.valid_field_value?(['']) assert f.valid_field_value?([''])
assert !f.valid_field_value?([' '])
assert f.valid_field_value?('value2') assert f.valid_field_value?('value2')
assert !f.valid_field_value?('abc') assert !f.valid_field_value?('abc')

View File

@ -1167,6 +1167,24 @@ RAW
assert textilizable(raw).gsub("\n", "").include?(expected) assert textilizable(raw).gsub("\n", "").include?(expected)
end end
def test_toc_with_textile_formatting_should_be_parsed
with_settings :text_formatting => 'textile' do
assert_select_in textilizable("{{toc}}\n\nh1. Heading"), 'ul.toc li', :text => 'Heading'
assert_select_in textilizable("{{<toc}}\n\nh1. Heading"), 'ul.toc.left li', :text => 'Heading'
assert_select_in textilizable("{{>toc}}\n\nh1. Heading"), 'ul.toc.right li', :text => 'Heading'
end
end
if Object.const_defined?(:Redcarpet)
def test_toc_with_markdown_formatting_should_be_parsed
with_settings :text_formatting => 'markdown' do
assert_select_in textilizable("{{toc}}\n\n# Heading"), 'ul.toc li', :text => 'Heading'
assert_select_in textilizable("{{<toc}}\n\n# Heading"), 'ul.toc.left li', :text => 'Heading'
assert_select_in textilizable("{{>toc}}\n\n# Heading"), 'ul.toc.right li', :text => 'Heading'
end
end
end
def test_section_edit_links def test_section_edit_links
raw = <<-RAW raw = <<-RAW
h1. Title h1. Title

View File

@ -36,4 +36,18 @@ class QueriesHelperTest < ActionView::TestCase
assert_equal filter_count + 1, fo.size assert_equal filter_count + 1, fo.size
assert_equal [], fo[0] assert_equal [], fo[0]
end end
def test_query_to_csv_should_translate_boolean_custom_field_values
f = IssueCustomField.generate!(:field_format => 'bool', :name => 'Boolean', :is_for_all => true, :trackers => Tracker.all)
issues = [
Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {f.id.to_s => '0'}),
Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {f.id.to_s => '1'})
]
with_locale 'fr' do
csv = query_to_csv(issues, IssueQuery.new, :columns => 'all')
assert_include "Oui", csv
assert_include "Non", csv
end
end
end end

View File

@ -51,4 +51,12 @@ class Redmine::FieldFormatTest < ActionView::TestCase
assert_equal "*foo*\nbar", field.format.formatted_custom_value(self, custom_value, false) assert_equal "*foo*\nbar", field.format.formatted_custom_value(self, custom_value, false)
assert_include "<strong>foo</strong>", field.format.formatted_custom_value(self, custom_value, true) assert_include "<strong>foo</strong>", field.format.formatted_custom_value(self, custom_value, true)
end end
def test_text_field_with_url_pattern_should_format_as_link
field = IssueCustomField.new(:field_format => 'string', :url_pattern => 'http://foo/%value%')
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "bar")
assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
assert_equal '<a href="http://foo/bar">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
end
end end

View File

@ -0,0 +1,31 @@
# Redmine - project management software
# Copyright (C) 2006-2014 Jean-Philippe Lang
#
# 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.
require File.expand_path('../../../../../test_helper', __FILE__)
require 'redmine/field_format'
class Redmine::NumericFieldFormatTest < ActionView::TestCase
include ApplicationHelper
def test_integer_field_with_url_pattern_should_format_as_link
field = IssueCustomField.new(:field_format => 'int', :url_pattern => 'http://foo/%value%')
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "3")
assert_equal 3, field.format.formatted_custom_value(self, custom_value, false)
assert_equal '<a href="http://foo/3">3</a>', field.format.formatted_custom_value(self, custom_value, true)
end
end

View File

@ -89,8 +89,8 @@ begin
adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo) adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo)
repo_path = adp.info.root_url.gsub(/\\/, "/") repo_path = adp.info.root_url.gsub(/\\/, "/")
assert_equal REPOSITORY_PATH, repo_path assert_equal REPOSITORY_PATH, repo_path
assert_equal '31', adp.info.lastrev.revision assert_equal '33', adp.info.lastrev.revision
assert_equal '31eeee7395c8c78e66dd54c50addd078d10b2355',adp.info.lastrev.scmid assert_equal '2e6d546429230f377d7d19c2078abd2dd909f235',adp.info.lastrev.scmid
end end
end end

View File

@ -235,6 +235,22 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
assert_select_in result, 'a.collapsible', :text => 'Hide example' assert_select_in result, 'a.collapsible', :text => 'Hide example'
end end
def test_macro_collapse_should_not_break_toc
text = <<-RAW
{{toc}}
h1. Title
{{collapse(Show example, Hide example)
h2. Heading
}}"
RAW
expected_toc = '<ul class="toc"><li><a href="#Title">Title</a><ul><li><a href="#Heading">Heading</a></li></ul></li></ul>'
assert_include expected_toc, textilizable(text).gsub(/[\r\n]/, '')
end
def test_macro_child_pages def test_macro_child_pages
expected = "<p><ul class=\"pages-hierarchy\">\n" + expected = "<p><ul class=\"pages-hierarchy\">\n" +
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" + "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +

View File

@ -23,7 +23,7 @@ class RepositoryMercurialTest < ActiveSupport::TestCase
include Redmine::I18n include Redmine::I18n
REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
NUM_REV = 32 NUM_REV = 34
CHAR_1_HEX = "\xc3\x9c" CHAR_1_HEX = "\xc3\x9c"
def setup def setup
@ -263,7 +263,7 @@ class RepositoryMercurialTest < ActiveSupport::TestCase
# with_limit # with_limit
changesets = @repository.latest_changesets('', nil, 2) changesets = @repository.latest_changesets('', nil, 2)
assert_equal %w|31 30|, changesets.collect(&:revision) assert_equal ["#{NUM_REV - 1}", "#{NUM_REV - 2}"], changesets.collect(&:revision)
# with_filepath # with_filepath
changesets = @repository.latest_changesets( changesets = @repository.latest_changesets(
@ -600,7 +600,7 @@ class RepositoryMercurialTest < ActiveSupport::TestCase
@repository.fetch_changesets @repository.fetch_changesets
@project.reload @project.reload
assert_equal NUM_REV, @repository.changesets.count assert_equal NUM_REV, @repository.changesets.count
%w|31 31eeee7395c8 31eee|.each do |r1| ["#{NUM_REV - 1}", "2e6d54642923", "2e6d5"].each do |r1|
changeset = @repository.find_changeset_by_name(r1) changeset = @repository.find_changeset_by_name(r1)
assert_nil changeset.next assert_nil changeset.next
end end