Compare commits

..

71 Commits

Author SHA1 Message Date
Toshi MARUYAMA
5ce399b0fb Merged r12229 from trunk to 2.3-stable (#15185)
Simplified Chinese translation for 2.3-stable updated.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12233 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-10-24 06:35:11 +00:00
Toshi MARUYAMA
e143f01e84 2.3-stable: Gemfile: pin selenium-webdriver version 2.35.1.
selenium-webdriver requires rubyzip 1.0.0.
rubyzip 1.0.0 requires Ruby version >= 1.9.2.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12227 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-10-20 10:47:19 +00:00
Jean-Philippe Lang
75e90593e0 Merged r12202 (#14977).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12214 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-10-13 08:28:26 +00:00
Jean-Philippe Lang
daf2d54f27 Merged r12162 from trunk (#14902).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12213 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-10-13 08:27:02 +00:00
Jean-Philippe Lang
8849727bd9 Merged r12164 from trunk (#14592).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12212 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-10-13 08:26:18 +00:00
Jean-Philippe Lang
c4eb7c380e Merged r12163 from trunk (#14590, #14592).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12211 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-10-13 08:24:48 +00:00
Toshi MARUYAMA
4deca5976e Merged r12189 from trunk to 2.3-stable (#13632)
pdf: fix empty page attached when exporting.

Contributed by Jun NAITOH.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12191 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-30 12:22:26 +00:00
Toshi MARUYAMA
8a046027e5 Merged r12180 from trunk to 2.3-stable (#14886)
Norwegian translation updated by Lennart Nordgreen.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12183 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-30 06:20:47 +00:00
Toshi MARUYAMA
711a8aa09b Merged r12173 from trunk to 2.3-stable (#14919)
Gemfile: update ruby-openid version above 2.3.0.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12178 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-30 03:19:44 +00:00
Toshi MARUYAMA
7ec18933e0 Merged r12172 from trunk to 2.3-stable (#14883)
Gemfile: update jdbc adapter version above 1.2.6.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12174 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-30 00:36:44 +00:00
Toshi MARUYAMA
0a25ee385f Merged r12138, r12149, r12156 and r12157 from trunk to 2.3-stable (#14931)
scm: fix annotate error with non ASCII author on Ruby 1.9 and Ruby 2.0.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12160 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-19 03:53:31 +00:00
Toshi MARUYAMA
79f90dfba5 Merged r12143 from trunk to 2.3-stable (#14931)
scm: git: use "--encoding=UTF-8" for blame.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12159 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-19 03:25:38 +00:00
Toshi MARUYAMA
2b53422d1d Merged r12155 from trunk to 2.3-stable (#14931)
scm: bazaar: update test repository for non ASCII author.

* run "bzr branch --no-tree branch00 author_non_ascii"
* add revision to this branch

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12158 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-18 23:16:20 +00:00
Toshi MARUYAMA
77ad962132 Merged r12153 from trunk to 2.3-stable (#14931)
scm: git: fix indents of non ASCII path annotate test.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12154 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-18 13:26:32 +00:00
Toshi MARUYAMA
7bfb4759e7 Merged r12150 from trunk to 2.3-stable (#14931)
use assert_select instead of assert_tag in Git non ASCII path annotate test.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12152 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-18 13:03:49 +00:00
Toshi MARUYAMA
9d3377c92c Merged r12146, r12147 and r12148 from trunk to 2.3-stable (#14931)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12151 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-18 11:15:08 +00:00
Toshi MARUYAMA
55a1869b86 Merged r12142 from trunk to 2.3-stable (#14931)
scm: git: change non ASCII user name variable to instance variable.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12145 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-18 08:10:10 +00:00
Toshi MARUYAMA
bcae879091 Merged r12139, r12140 and r12141 from trunk to 2.3-stable (#14931)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12144 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-18 08:09:59 +00:00
Jean-Philippe Lang
2c44829509 Updates for 2.3.3
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12136 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-14 06:47:11 +00:00
Jean-Philippe Lang
d259dd2dd5 Merged r12131 and r12132 (#14798).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12134 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-13 17:53:35 +00:00
Jean-Philippe Lang
ddc016d81d Merged r12126 from trunk (#13008).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12127 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-10 17:40:34 +00:00
Jean-Philippe Lang
e7c82e3934 Backported r12079 from trunk (#14584).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12125 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-10 17:08:53 +00:00
Jean-Philippe Lang
e503f41f6f Reverts r12123 (#14584).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12124 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-10 16:52:25 +00:00
Jean-Philippe Lang
cd67243de5 Merged r12079 from trunk (#14584).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12123 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-10 16:43:54 +00:00
Toshi MARUYAMA
b0c3b7a574 Merged r12120 from trunk to 2.3-stable (#14501)
fix Russian "description_date_range_interval" translation misprint.

Contributed by Artem Kondratyev.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12122 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-09-05 11:15:41 +00:00
Toshi MARUYAMA
9a67caf248 Merged r12118 from trunk to 2.3-stable (#14697)
fix wrong Russian translation in close project message.

Contributed by Artur Gadelshin.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12119 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-08-15 14:41:26 +00:00
Toshi MARUYAMA
67ee8653bd Merged r12115 from trunk to 2.3-stable (#14682, #14686)
Portuguese translation for 2.3-stable updated by Lije Also.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12117 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-08-14 06:55:19 +00:00
Jean-Philippe Lang
36978279c3 Merged r12076 from trunk (#14607).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12078 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-08-04 10:33:03 +00:00
Toshi MARUYAMA
d155392b3c Merged r12070 from trunk to 2.3-stable
not use assert_not_nil in Errors#[].

r7593 etc. replaced Rails2 Errors#on.
Rails3 Errors#[] always return array.
So, Rails3 Errors#[] is always not nil.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12071 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-30 09:38:00 +00:00
Jean-Philippe Lang
dc98cec17f Merged r12060 from trunk (#14369).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12066 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 20:49:41 +00:00
Jean-Philippe Lang
e1e006f09e Merged r12017 and r12027 from trunk (#14422).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12065 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 20:48:52 +00:00
Jean-Philippe Lang
e8757fec2b Merged r12056 from trunk (#14447).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12064 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 20:46:53 +00:00
Jean-Philippe Lang
591922c365 Merged r12057 from trunk (#14415).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12063 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 20:46:04 +00:00
Jean-Philippe Lang
5eeca35317 Merged r12058 from trunk (#14401).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12062 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 20:45:16 +00:00
Jean-Philippe Lang
2de51892ee Merged r12059 from trunk (#14340).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12061 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 20:44:18 +00:00
Toshi MARUYAMA
3fe5e3bb6f 2.3-stable: svn propset svn:eol-style native test fixtures (#14562)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12055 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 12:57:16 +00:00
Toshi MARUYAMA
bbf3ffe0aa Merged r12046 from trunk to 2.3-stable (#14562)
fix diff of CJK (Chinese/Japanese/Korean) is broken on Ruby 1.8.

Contributed by Jun NAITOH.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12054 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 12:53:51 +00:00
Jean-Philippe Lang
b724eb4fec Merged r12052 from trunk (#14511).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12053 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 12:09:47 +00:00
Jean-Philippe Lang
493119e795 Merged r12042 from trunk (#14366).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12043 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-28 10:00:35 +00:00
Toshi MARUYAMA
f1b6b4ef33 Merged r12038 from trunk to 2.3-stable (#14531, #14521)
Spanish translations for 2.3.x updated by Jorge López.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12040 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-24 11:28:35 +00:00
Toshi MARUYAMA
ce002ee3df Merged r12034 from trunk to 2.3-stable (#14502, #14501)
Russian translation for 2.3-stable updated by Alex Stein.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12037 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-19 16:12:18 +00:00
Toshi MARUYAMA
eb7862445c Merged r12033 from trunk to 2.3-stable.
update ruby-openid version to 2.2.3.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12036 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-19 16:12:06 +00:00
Toshi MARUYAMA
b31b5328e4 Merged r12028 from trunk to 2.3-stable (#14485, #14458)
Traditional Chinese translation for 2.3-stable updated by ChunChang Lo.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12032 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-18 10:13:38 +00:00
Jean-Philippe Lang
8efcf60319 Updates for 2.3.2 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12023 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-14 14:50:07 +00:00
Jean-Philippe Lang
e07bc81c5e Add more info about the ruby version (#14419).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12002 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 18:43:48 +00:00
Jean-Philippe Lang
5c6349a7ca Merged r11905 from trunk (#14103).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12001 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 18:37:47 +00:00
Jean-Philippe Lang
37fbdb1457 Merged r11906 from trunk (#14101).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@12000 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 18:37:00 +00:00
Jean-Philippe Lang
a13acb7851 Merged r11869 from trunk (#12888).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11999 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 18:36:02 +00:00
Jean-Philippe Lang
01887f1e67 Merged r11915 from trunk (#14186).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11998 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 18:33:54 +00:00
Jean-Philippe Lang
3d9f274140 Merged r11839 from trunk (#14020).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11997 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 18:33:07 +00:00
Jean-Philippe Lang
7375dff6d6 Merged r11827 to r11833 from trunk (#14015).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11996 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 18:28:54 +00:00
Jean-Philippe Lang
9874a61ec3 Merged r11854 from trunk (#13783).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11995 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-07-11 17:51:19 +00:00
Toshi MARUYAMA
b5998b59ab Merged r11982 from trunk to 2.3-stable (#14346)
fix Latvian "button_log_time" translation by Arnis Juraga.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11984 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-26 11:49:38 +00:00
Toshi MARUYAMA
c590cded4b Merged r11980 from trunk to 2.3-stable (#9996)
replace "email.yml" to "configuration.yml" in pl.yml.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11981 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-15 12:55:48 +00:00
Toshi MARUYAMA
5b8af329e2 2.3-stable: pin nokogiri version < 1.6.0 (#14245)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11953 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-10 08:24:46 +00:00
Toshi MARUYAMA
0badc79162 Merged r11942 from trunk to 2.3-stable (#14242)
fix that project auto generation fails when projects created in the same time.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11945 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-08 11:39:56 +00:00
Toshi MARUYAMA
5e57cbfdc4 Merged r11932 from trunk to 2.3-stable (#14221)
translate x_hours in many languages.

Contributed by Filou Centrinov.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11935 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-06 06:13:53 +00:00
Toshi MARUYAMA
489527ada7 Merged r11925 from trunk to 2.3-stable (#13692)
prevent coderay "warning: already initialized constant" on Ruby 1.8.7.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11929 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-05 04:06:47 +00:00
Toshi MARUYAMA
6ce685a63c Merged r11920 and r11921 from trunk to 2.3-stable (#14178)
pdf: restore "col_id_width" parameter of issues_to_pdf_draw_borders.

Contributed by Massimo Rossello.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11924 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-04 12:42:29 +00:00
Toshi MARUYAMA
8045385990 Merged r11919 from trunk to 2.3-stable (#14196)
Italian translation for 2.3-stable by Riccardo Rocca.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11922 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-06-04 11:40:41 +00:00
Toshi MARUYAMA
3a4c46089f Merged r11911 from trunk to 2.3-stable (#14182, #14180)
pt-BR translation for 2.3-stable updated by Marcela Oliveira.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11914 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-31 11:05:39 +00:00
Toshi MARUYAMA
53d45273a9 Merged r11901 from trunk to 2.3-stable (#14145)
German translation of x_hours updated by Filou Centrinov.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11903 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-25 06:04:36 +00:00
Jean-Philippe Lang
cc23ab9652 Merged r11850 from trunk (#14051).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11872 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-18 19:35:26 +00:00
Jean-Philippe Lang
ea33a66c6b Merged r11851 from trunk (#14023).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11871 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-18 19:34:19 +00:00
Jean-Philippe Lang
a8c27df9fe Merged r11843 from trunk (#13910).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11870 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-18 19:33:27 +00:00
Jean-Philippe Lang
af632568e3 Merged r11760 from trunk (#13850).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11837 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-12 09:45:52 +00:00
Jean-Philippe Lang
2c408ca6a5 Merged r11761 from trunk (#13821).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11836 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-12 09:44:52 +00:00
Jean-Philippe Lang
2a6dadf787 Merged r11762 and r11763 from trunk (#13783).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11835 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-12 09:43:59 +00:00
Toshi MARUYAMA
958f1accec Merged r11798 from trunk to 2.3-stable (#14003, #14005)
Swedish Translation for 2.3-stable updated by Nicklas Holm.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11801 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-08 01:36:46 +00:00
Toshi MARUYAMA
77a2cbfa6a Merged r11791 from trunk to 2.3-stable (#13950)
remove duplicate Lithuanian "error_attachment_too_big" translation keys.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11792 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-05 10:38:05 +00:00
Toshi MARUYAMA
73b4b614ee Merged r11724 from trunk to 2.3-stable.
Add TODO comment about gantt issues sort (#7335).

Sorting by date was dropped by r4581 (#7128).

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.3-stable@11769 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-05-02 22:44:54 +00:00
114 changed files with 1135 additions and 388 deletions

View File

@@ -3,7 +3,7 @@ source 'https://rubygems.org'
gem "rails", "3.2.13"
gem "jquery-rails", "~> 2.0.2"
gem "i18n", "~> 0.6.0"
gem "coderay", "~> 1.0.6"
gem "coderay", "~> 1.0.9"
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
gem "builder", "3.0.0"
@@ -14,7 +14,7 @@ end
# Optional gem for OpenID authentication
group :openid do
gem "ruby-openid", "~> 2.1.4", :require => "openid"
gem "ruby-openid", "~> 2.3.0", :require => "openid"
gem "rack-openid"
end
@@ -31,7 +31,7 @@ end
platforms :jruby do
# jruby-openssl is bundled with JRuby 1.7.0
gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
gem "activerecord-jdbc-adapter", "1.2.5"
gem "activerecord-jdbc-adapter", "~> 1.2.6"
end
# Include database gems for the adapters found in the database
@@ -80,6 +80,8 @@ group :test do
gem "shoulda", "~> 3.3.2"
gem "mocha", "~> 0.13.3"
gem 'capybara', '~> 2.0.0'
gem 'nokogiri', '< 1.6.0'
gem 'selenium-webdriver', '2.35.1'
end
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")

View File

@@ -70,14 +70,12 @@ class EnumerationsController < ApplicationController
@enumeration.destroy
redirect_to enumerations_path
return
elsif params[:reassign_to_id]
if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id])
@enumeration.destroy(reassign_to)
redirect_to enumerations_path
return
end
elsif params[:reassign_to_id].present? && (reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id].to_i))
@enumeration.destroy(reassign_to)
redirect_to enumerations_path
return
end
@enumerations = @enumeration.class.all - [@enumeration]
@enumerations = @enumeration.class.system.all - [@enumeration]
end
private

View File

@@ -53,7 +53,6 @@ class MyController < ApplicationController
if request.post?
@user.safe_attributes = params[:user]
@user.pref.attributes = params[:pref]
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
if @user.save
@user.pref.save
@user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])

View File

@@ -43,10 +43,10 @@ class TimelogController < ApplicationController
def index
@query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
scope = time_entry_scope
sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
sort_update(@query.sortable_columns)
scope = time_entry_scope(:order => sort_clause)
respond_to do |format|
format.html {
@@ -55,7 +55,6 @@ class TimelogController < ApplicationController
@entry_pages = Paginator.new @entry_count, per_page_option, params['page']
@entries = scope.all(
:include => [:project, :activity, :user, {:issue => :tracker}],
:order => sort_clause,
:limit => @entry_pages.per_page,
:offset => @entry_pages.offset
)
@@ -68,15 +67,13 @@ class TimelogController < ApplicationController
@offset, @limit = api_offset_and_limit
@entries = scope.all(
:include => [:project, :activity, :user, {:issue => :tracker}],
:order => sort_clause,
:limit => @limit,
:offset => @offset
)
}
format.atom {
entries = scope.all(
entries = scope.reorder("#{TimeEntry.table_name}.created_on DESC").all(
:include => [:project, :activity, :user, {:issue => :tracker}],
:order => "#{TimeEntry.table_name}.created_on DESC",
:limit => Setting.feeds_limit.to_i
)
render_feed(entries, :title => l(:label_spent_time))
@@ -84,8 +81,7 @@ class TimelogController < ApplicationController
format.csv {
# Export all entries
@entries = scope.all(
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
:order => sort_clause
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}]
)
send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
}
@@ -295,12 +291,10 @@ private
end
# Returns the TimeEntry scope for index and report actions
def time_entry_scope
scope = TimeEntry.visible.where(@query.statement)
def time_entry_scope(options={})
scope = @query.results_scope(options)
if @issue
scope = scope.on_issue(@issue)
elsif @project
scope = scope.on_project(@project, Setting.display_subprojects_issues?)
end
scope
end

View File

@@ -92,7 +92,6 @@ class UsersController < ApplicationController
if @user.save
@user.pref.attributes = params[:pref]
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
@user.pref.save
@user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
@@ -137,7 +136,6 @@ class UsersController < ApplicationController
was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE])
# TODO: Similar to My#account
@user.pref.attributes = params[:pref]
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
if @user.save
@user.pref.save

View File

@@ -214,6 +214,28 @@ module IssuesHelper
out
end
def email_issue_attributes(issue)
items = []
%w(author status priority assigned_to category fixed_version).each do |attribute|
unless issue.disabled_core_fields.include?(attribute+"_id")
items << "#{l("field_#{attribute}")}: #{issue.send attribute}"
end
end
issue.custom_field_values.each do |value|
items << "#{value.custom_field.name}: #{show_value(value)}"
end
items
end
def render_email_issue_attributes(issue, html=false)
items = email_issue_attributes(issue)
if html
content_tag('ul', items.map{|s| content_tag('li', s)}.join("\n").html_safe)
else
items.map{|s| "* #{s}"}.join("\n")
end
end
# Returns the textual representation of a journal details
# as an array of strings
def details_to_strings(details, no_html=false, options={})

View File

@@ -24,7 +24,7 @@ module ReportsHelper
data.each { |row|
match = 1
criteria.each { |k, v|
match = 0 unless (row[k].to_s == v.to_s) || (k == 'closed' && row[k] == (v == 0 ? "f" : "t"))
match = 0 unless (row[k].to_s == v.to_s) || (k == 'closed' && (v == 0 ? ['f', false] : ['t', true]).include?(row[k]))
} unless criteria.nil?
a = a + row["total"].to_i if match == 1
} unless data.nil?

View File

@@ -102,7 +102,7 @@ class Attachment < ActiveRecord::Base
if @temp_file && (@temp_file.size > 0)
self.disk_directory = target_directory
self.disk_filename = Attachment.disk_filename(filename, disk_directory)
logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)")
logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)") if logger
path = File.dirname(diskfile)
unless File.directory?(path)
FileUtils.mkdir_p(path)

View File

@@ -38,6 +38,7 @@ class Enumeration < ActiveRecord::Base
scope :shared, lambda { where(:project_id => nil) }
scope :sorted, lambda { order("#{table_name}.position ASC") }
scope :active, lambda { where(:active => true) }
scope :system, lambda { where(:project_id => nil) }
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
def self.default

View File

@@ -106,10 +106,10 @@ class Issue < ActiveRecord::Base
when 'all'
nil
when 'default'
user_ids = [user.id] + user.groups.map(&:id)
user_ids = [user.id] + user.groups.map(&:id).compact
"(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))"
when 'own'
user_ids = [user.id] + user.groups.map(&:id)
user_ids = [user.id] + user.groups.map(&:id).compact
"(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))"
else
'1=0'
@@ -744,12 +744,16 @@ class Issue < ActiveRecord::Base
initial_status = IssueStatus.find_by_id(status_id_was)
end
initial_status ||= status
initial_assigned_to_id = assigned_to_id_changed? ? assigned_to_id_was : assigned_to_id
assignee_transitions_allowed = initial_assigned_to_id.present? &&
(user.id == initial_assigned_to_id || user.group_ids.include?(initial_assigned_to_id))
statuses = initial_status.find_new_statuses_allowed_to(
user.admin ? Role.all : user.roles_for_project(project),
tracker,
author == user,
assigned_to_id_changed? ? assigned_to_id_was == user.id : assigned_to_id == user.id
assignee_transitions_allowed
)
statuses << initial_status unless statuses.empty?
statuses << IssueStatus.default if include_default
@@ -854,18 +858,99 @@ class Issue < ActiveRecord::Base
end
# Returns all the other issues that depend on the issue
# The algorithm is a modified breadth first search (bfs)
def all_dependent_issues(except=[])
except << self
# The found dependencies
dependencies = []
dependencies += relations_from.map(&:issue_to)
dependencies += children unless leaf?
dependencies.compact!
# The visited flag for every node (issue) used by the breadth first search
eNOT_DISCOVERED = 0 # The issue is "new" to the algorithm, it has not seen it before.
ePROCESS_ALL = 1 # The issue is added to the queue. Process both children and relations of
# the issue when it is processed.
ePROCESS_RELATIONS_ONLY = 2 # The issue was added to the queue and will be output as dependent issue,
# but its children will not be added to the queue when it is processed.
eRELATIONS_PROCESSED = 3 # The related issues, the parent issue and the issue itself have been added to
# the queue, but its children have not been added.
ePROCESS_CHILDREN_ONLY = 4 # The relations and the parent of the issue have been added to the queue, but
# the children still need to be processed.
eALL_PROCESSED = 5 # The issue and all its children, its parent and its related issues have been
# added as dependent issues. It needs no further processing.
issue_status = Hash.new(eNOT_DISCOVERED)
# The queue
queue = []
# Initialize the bfs, add start node (self) to the queue
queue << self
issue_status[self] = ePROCESS_ALL
while (!queue.empty?) do
current_issue = queue.shift
current_issue_status = issue_status[current_issue]
dependencies << current_issue
# Add parent to queue, if not already in it.
parent = current_issue.parent
parent_status = issue_status[parent]
if parent && (parent_status == eNOT_DISCOVERED) && !except.include?(parent)
queue << parent
issue_status[parent] = ePROCESS_RELATIONS_ONLY
end
# Add children to queue, but only if they are not already in it and
# the children of the current node need to be processed.
if (current_issue_status == ePROCESS_CHILDREN_ONLY || current_issue_status == ePROCESS_ALL)
current_issue.children.each do |child|
next if except.include?(child)
if (issue_status[child] == eNOT_DISCOVERED)
queue << child
issue_status[child] = ePROCESS_ALL
elsif (issue_status[child] == eRELATIONS_PROCESSED)
queue << child
issue_status[child] = ePROCESS_CHILDREN_ONLY
elsif (issue_status[child] == ePROCESS_RELATIONS_ONLY)
queue << child
issue_status[child] = ePROCESS_ALL
end
end
end
# Add related issues to the queue, if they are not already in it.
current_issue.relations_from.map(&:issue_to).each do |related_issue|
next if except.include?(related_issue)
if (issue_status[related_issue] == eNOT_DISCOVERED)
queue << related_issue
issue_status[related_issue] = ePROCESS_ALL
elsif (issue_status[related_issue] == eRELATIONS_PROCESSED)
queue << related_issue
issue_status[related_issue] = ePROCESS_CHILDREN_ONLY
elsif (issue_status[related_issue] == ePROCESS_RELATIONS_ONLY)
queue << related_issue
issue_status[related_issue] = ePROCESS_ALL
end
end
# Set new status for current issue
if (current_issue_status == ePROCESS_ALL) || (current_issue_status == ePROCESS_CHILDREN_ONLY)
issue_status[current_issue] = eALL_PROCESSED
elsif (current_issue_status == ePROCESS_RELATIONS_ONLY)
issue_status[current_issue] = eRELATIONS_PROCESSED
end
end # while
# Remove the issues from the "except" parameter from the result array
dependencies -= except
dependencies += dependencies.map {|issue| issue.all_dependent_issues(except)}.flatten
if parent
dependencies << parent
dependencies += parent.all_dependent_issues(except + parent.descendants)
end
dependencies.delete(self)
dependencies
end
@@ -1252,7 +1337,8 @@ class Issue < ActiveRecord::Base
if average == 0
average = 1
end
done = p.leaves.sum("COALESCE(estimated_hours, #{average}) * (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)", :joins => :status).to_f
done = p.leaves.sum("COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END, #{average}) " +
"* (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)", :joins => :status).to_f
progress = done / (average * leaves_count)
p.done_ratio = progress.round
end

View File

@@ -393,10 +393,9 @@ class IssueQuery < Query
if relation_options[:sym] == field && !options[:reverse]
sqls = [sql, sql_for_relations(field, operator, value, :reverse => true)]
sqls.join(["!", "!*", "!p"].include?(operator) ? " AND " : " OR ")
else
sql
sql = sqls.join(["!", "!*", "!p"].include?(operator) ? " AND " : " OR ")
end
"(#{sql})"
end
IssueRelation::TYPES.keys.each do |relation_type|

View File

@@ -390,7 +390,7 @@ class Mailer < ActionMailer::Base
# Removes the author from the recipients and cc
# if he doesn't want to receive notifications about what he does
if @author && @author.logged? && @author.pref[:no_self_notified]
if @author && @author.logged? && @author.pref.no_self_notified
headers[:to].delete(@author.mail) if headers[:to].is_a?(Array)
headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array)
end

View File

@@ -673,7 +673,7 @@ class Project < ActiveRecord::Base
# Returns an auto-generated project identifier based on the last identifier used
def self.next_identifier
p = Project.order('created_on DESC').first
p = Project.order('id DESC').first
p.nil? ? nil : p.identifier.to_s.succ
end
@@ -840,6 +840,9 @@ class Project < ActiveRecord::Base
new_issue = Issue.new
new_issue.copy_from(issue, :subtasks => false, :link => false)
new_issue.project = self
# Changing project resets the custom field values
# TODO: handle this in Issue#project=
new_issue.custom_field_values = issue.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
# Reassign fixed_versions by name, since names are unique per project
if issue.fixed_version && issue.fixed_version.project == project
new_issue.fixed_version = self.versions.detect {|v| v.name == issue.fixed_version.name}

View File

@@ -577,8 +577,11 @@ class Query < ActiveRecord::Base
customized_class = queried_class.reflect_on_association(assoc.to_sym).klass.base_class rescue nil
raise "Unknown #{queried_class.name} association #{assoc}" unless customized_class
end
"#{queried_table_name}.#{customized_key} #{not_in} IN (SELECT #{customized_class.table_name}.id FROM #{customized_class.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='#{customized_class}' AND #{db_table}.customized_id=#{customized_class.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id} WHERE " +
sql_for_field(field, operator, value, db_table, db_field, true) + ')'
where = sql_for_field(field, operator, value, db_table, db_field, true)
if operator =~ /[<>]/
where = "(#{where}) AND #{db_table}.#{db_field} <> ''"
end
"#{queried_table_name}.#{customized_key} #{not_in} IN (SELECT #{customized_class.table_name}.id FROM #{customized_class.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='#{customized_class}' AND #{db_table}.customized_id=#{customized_class.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id} WHERE #{where})"
end
# Helper method to generate the WHERE sql for a +field+, +operator+ and a +value+

View File

@@ -24,11 +24,15 @@ class TimeEntryActivity < Enumeration
OptionName
end
def objects
TimeEntry.where(:activity_id => self_and_descendants(1).map(&:id))
end
def objects_count
time_entries.count
objects.count
end
def transfer_relations(to)
time_entries.update_all("activity_id = #{to.id}")
objects.update_all(:activity_id => to.id)
end
end

View File

@@ -100,6 +100,15 @@ class TimeEntryQuery < Query
@default_columns_names ||= [:project, :spent_on, :user, :activity, :issue, :comments, :hours]
end
def results_scope(options={})
order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
TimeEntry.visible.
where(statement).
order(order_option).
joins(joins_for_order_statement(order_option.join(',')))
end
# Accepts :from/:to params as shortcut filters
def build_from_params(params)
super

View File

@@ -33,7 +33,7 @@ class UserPreference < ActiveRecord::Base
end
def [](attr_name)
if attribute_present? attr_name
if has_attribute? attr_name
super
else
others ? others[attr_name] : nil
@@ -41,7 +41,7 @@ class UserPreference < ActiveRecord::Base
end
def []=(attr_name, value)
if attribute_present? attr_name
if has_attribute? attr_name
super
else
h = (read_attribute(:others) || {}).dup
@@ -56,4 +56,7 @@ class UserPreference < ActiveRecord::Base
def warn_on_leaving_unsaved; self[:warn_on_leaving_unsaved] || '1'; end
def warn_on_leaving_unsaved=(value); self[:warn_on_leaving_unsaved]=value; end
def no_self_notified; (self[:no_self_notified] == true || self[:no_self_notified] == '1'); end
def no_self_notified=(value); self[:no_self_notified]=value; end
end

View File

@@ -47,7 +47,8 @@ class Version < ActiveRecord::Base
'wiki_page_title',
'status',
'sharing',
'custom_field_values'
'custom_field_values',
'custom_fields'
# Returns true if +user+ or current user is allowed to view the version
def visible?(user=User.current)

View File

@@ -12,7 +12,7 @@
<p><em><%=h @document.category.name %><br />
<%= format_date @document.created_on %></em></p>
<div class="wiki">
<%= textilizable @document.description, :attachments => @document.attachments %>
<%= textilizable @document, :description, :attachments => @document.attachments %>
</div>
<h3><%= l(:label_attachment_plural) %></h3>

View File

@@ -4,7 +4,7 @@
<div class="box">
<p><strong><%= l(:text_enumeration_destroy_question, @enumeration.objects_count) %></strong></p>
<p><label for='reassign_to_id'><%= l(:text_enumeration_category_reassign_to) %></label>
<%= select_tag 'reassign_to_id', (content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---") + options_from_collection_for_select(@enumerations, 'id', 'name')) %></p>
<%= select_tag 'reassign_to_id', (content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---", :value => '') + options_from_collection_for_select(@enumerations, 'id', 'name')) %></p>
</div>
<%= submit_tag l(:button_apply) %>

View File

@@ -1,15 +1,5 @@
<h1><%= link_to(h("#{issue.tracker.name} ##{issue.id}: #{issue.subject}"), issue_url) %></h1>
<ul>
<li><%=l(:field_author)%>: <%=h issue.author %></li>
<li><%=l(:field_status)%>: <%=h issue.status %></li>
<li><%=l(:field_priority)%>: <%=h issue.priority %></li>
<li><%=l(:field_assigned_to)%>: <%=h issue.assigned_to %></li>
<li><%=l(:field_category)%>: <%=h issue.category %></li>
<li><%=l(:field_fixed_version)%>: <%=h issue.fixed_version %></li>
<% issue.custom_field_values.each do |c| %>
<li><%=h c.custom_field.name %>: <%=h show_value(c) %></li>
<% end %>
</ul>
<%= render_email_issue_attributes(issue, true) %>
<%= textilizable(issue, :description, :only_path => false) %>

View File

@@ -1,13 +1,6 @@
<%= "#{issue.tracker.name} ##{issue.id}: #{issue.subject}" %>
<%= issue_url %>
* <%=l(:field_author)%>: <%= issue.author %>
* <%=l(:field_status)%>: <%= issue.status %>
* <%=l(:field_priority)%>: <%= issue.priority %>
* <%=l(:field_assigned_to)%>: <%= issue.assigned_to %>
* <%=l(:field_category)%>: <%= issue.category %>
* <%=l(:field_fixed_version)%>: <%= issue.fixed_version %>
<% issue.custom_field_values.each do |c| %>* <%= c.custom_field.name %>: <%= show_value(c) %>
<% end -%>
<%= render_email_issue_attributes(issue) %>
----------------------------------------
<%= issue.description %>

View File

@@ -1,3 +1,6 @@
<% if @journal.private_notes? %>
(<%= l(:field_private_notes) %>)
<% end %>
<%= l(:text_issue_updated, :id => "##{@issue.id}", :author => h(@journal.user)) %>
<ul>

View File

@@ -1,4 +1,4 @@
<%= l(:text_issue_updated, :id => "##{@issue.id}", :author => @journal.user) %>
<%= "(#{l(:field_private_notes)}) " if @journal.private_notes? -%><%= l(:text_issue_updated, :id => "##{@issue.id}", :author => @journal.user) %>
<% details_to_strings(@journal.details, true).each do |string| -%>
<%= string %>

View File

@@ -3,7 +3,7 @@ var operatorLabels = <%= raw_json Query.operators_labels %>;
var operatorByType = <%= raw_json Query.operators_by_filter_type %>;
var availableFilters = <%= raw_json query.available_filters_as_json %>;
var labelDayPlural = <%= raw_json l(:label_day_plural) %>;
var allProjects = <%= raw query.all_projects_values.to_json %>;
var allProjects = <%= raw_json query.all_projects_values %>;
$(document).ready(function(){
initFilters();
<% query.filters.each do |field, options| %>

View File

@@ -19,8 +19,18 @@
<tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
<th class="line-num" id="L<%= line_num %>"><a href="#L<%= line_num %>"><%= line_num %></a></th>
<td class="revision">
<%= (revision.identifier ? link_to_revision(revision, @repository) : format_revision(revision)) if revision && revision != previous_revision %></td>
<td class="author"><%= h(revision.author.to_s.split('<').first) if revision && revision != previous_revision %></td>
<% if revision && revision != previous_revision %>
<%= revision.identifier ?
link_to_revision(revision, @repository) : format_revision(revision) %>
<% end %>
</td>
<td class="author">
<% if revision && revision != previous_revision %>
<% author = Redmine::CodesetUtil.to_utf8(revision.author.to_s,
@repository.repo_log_encoding) %>
<%= author.split('<').first %>
<% end %>
</td>
<td class="line-code"><pre><%= line.html_safe %></pre></td>
</tr>
<% line_num += 1; previous_revision = revision %>

View File

@@ -19,9 +19,10 @@
end %>
<p><em class="info"><%= l(:text_user_mail_option) %></em></p>
<% end %>
<%= fields_for :pref, @user.pref do |pref_fields| %>
<p>
<label>
<%= l(:label_user_mail_no_self_notified) %>
<%= check_box_tag 'no_self_notified', 1, @user.pref[:no_self_notified] %>
</label>
<%= pref_fields.check_box :no_self_notified %>
<label for="pref_no_self_notified"><%= l(:label_user_mail_no_self_notified) %></label>
</p>
<% end %>

View File

@@ -50,8 +50,8 @@ ar:
one: "حوالي ساعة"
other: "ساعات %{count}حوالي "
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "%{count} ساعة"
other: "%{count} ساعات"
x_days:
one: "يوم"
other: "%{count} أيام"

View File

@@ -109,8 +109,8 @@ az:
many: "təxminən %{count} saat"
other: "təxminən %{count} saat"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 saat"
other: "%{count} saat"
x_days:
one: "%{count} gün"
few: "%{count} gün"

View File

@@ -51,8 +51,8 @@ bg:
one: "около 1 час"
other: "около %{count} часа"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 час"
other: "%{count} часа"
x_days:
one: "1 ден"
other: "%{count} дена"

View File

@@ -49,8 +49,8 @@ bs:
one: "oko 1 sahat"
other: "oko %{count} sahata"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 sahat"
other: "%{count} sahata"
x_days:
one: "1 dan"
other: "%{count} dana"

View File

@@ -53,8 +53,8 @@ ca:
one: "aproximadament 1 hora"
other: "aproximadament %{count} hores"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 hora"
other: "%{count} hores"
x_days:
one: "1 dia"
other: "%{count} dies"

View File

@@ -55,8 +55,8 @@ cs:
one: "asi 1 hodina"
other: "asi %{count} hodin"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 hodina"
other: "%{count} hodin"
x_days:
one: "1 den"
other: "%{count} dnů"

View File

@@ -52,8 +52,8 @@ da:
one: "cirka en time"
other: "cirka %{count} timer"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 time"
other: "%{count} timer"
x_days:
one: "en dag"
other: "%{count} dage"

View File

@@ -53,8 +53,8 @@ de:
one: 'etwa 1 Stunde'
other: 'etwa %{count} Stunden'
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 Stunde"
other: "%{count} Stunden"
x_days:
one: '1 Tag'
other: '%{count} Tagen'

View File

@@ -52,8 +52,8 @@ el:
one: "περίπου 1 ώρα"
other: "περίπου %{count} ώρες"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 ώρα"
other: "%{count} ώρες"
x_days:
one: "1 ημέρα"
other: "%{count} ημέρες"

View File

@@ -80,8 +80,8 @@ es:
one: "alrededor de 1 hora"
other: "alrededor de %{count} horas"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 hora"
other: "%{count} horas"
x_days:
one: "1 día"
other: "%{count} días"
@@ -1118,8 +1118,8 @@ es:
permission_edit_documents: Editar documentos
permission_delete_documents: Borrar documentos
label_gantt_progress_line: Línea de progreso
setting_jsonp_enabled: Enable JSONP support
field_inherit_members: Inherit members
field_closed_on: Closed
setting_default_projects_tracker_ids: Default trackers for new projects
setting_jsonp_enabled: Habilitar soporte de JSONP
field_inherit_members: Heredar miembros
field_closed_on: Cerrada
setting_default_projects_tracker_ids: Tipos de petición habilitados por defecto
label_total_time: Total

View File

@@ -67,8 +67,8 @@ et:
one: "umbes tund"
other: "umbes %{count} tundi"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 tund"
other: "%{count} tundi"
x_days:
one: "1 päev"
other: "%{count} päeva"

View File

@@ -53,8 +53,8 @@ eu:
one: "ordu 1 inguru"
other: "%{count} ordu inguru"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "ordu 1"
other: "%{count} ordu"
x_days:
one: "egun 1"
other: "%{count} egun"

View File

@@ -50,8 +50,8 @@ fa:
one: "نزدیک 1 ساعت"
other: "نزدیک %{count} ساعت"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 ساعت"
other: "%{count} ساعت"
x_days:
one: "1 روز"
other: "%{count} روز"

View File

@@ -95,8 +95,8 @@ fi:
one: "noin tunti"
other: "noin %{count} tuntia"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 tunti"
other: "%{count} tuntia"
x_days:
one: "päivä"
other: "%{count} päivää"

View File

@@ -91,8 +91,8 @@ gl:
one: 'aproximadamente unha hora'
other: '%{count} horas'
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 hora"
other: "%{count} horas"
x_days:
one: '1 día'
other: '%{count} días'

View File

@@ -56,8 +56,8 @@ he:
one: 'בערך שעה אחת'
other: 'בערך %{count} שעות'
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 שעה"
other: "%{count} שעות"
x_days:
one: 'יום אחד'
other: '%{count} ימים'

View File

@@ -49,8 +49,8 @@ hr:
one: "oko sat vremena"
other: "oko %{count} sati"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 sata"
other: "%{count} sati"
x_days:
one: "1 dan"
other: "%{count} dana"

View File

@@ -51,8 +51,8 @@
one: 'csaknem 1 órája'
other: 'csaknem %{count} órája'
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 óra"
other: "%{count} óra"
x_days:
one: '1 napja'
other: '%{count} napja'

View File

@@ -47,8 +47,8 @@ id:
one: "sekitar sejam"
other: "sekitar %{count} jam"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 jam"
other: "%{count} jam"
x_days:
one: "sehari"
other: "%{count} hari"

View File

@@ -55,8 +55,8 @@ it:
one: "circa un'ora"
other: "circa %{count} ore"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 ora"
other: "%{count} ore"
x_days:
one: "1 giorno"
other: "%{count} giorni"
@@ -1001,90 +1001,87 @@ it:
button_export: Esporta
label_export_options: "%{export_format} opzioni per l'export"
error_attachment_too_big: Questo file non può essere caricato in quanto la sua dimensione supera la massima consentita (%{max_size})
notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
notice_failed_to_save_time_entries: "Non ho potuto salvare %{count} registrazioni di tempo impiegato su %{total} selezionate: %{ids}."
label_x_issues:
zero: 0 segnalazione
one: 1 segnalazione
other: "%{count} segnalazioni"
label_repository_new: New repository
field_repository_is_default: Main repository
label_copy_attachments: Copy attachments
label_repository_new: Nuovo repository
field_repository_is_default: Repository principale
label_copy_attachments: Copia allegati
label_item_position: "%{position}/%{count}"
label_completed_versions: Completed versions
text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
field_multiple: Multiple values
text_project_identifier_info: Consentiti solo lettere minuscole (a-z), numeri, trattini e trattini bassi.<br />Una volta salvato, l'identificatore non può essere modificato.
field_multiple: Valori multipli
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
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)
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}
permission_manage_related_issues: Manage related issues
field_auth_source_ldap_filter: LDAP filter
label_search_for_watchers: Search for watchers to add
notice_account_deleted: Your account has been permanently deleted.
setting_unsubscribe: Allow users to delete their own account
button_delete_my_account: Delete my account
text_account_destroy_confirmation: |-
Are you sure you want to proceed?
Your account will be permanently deleted, with no way to reactivate it.
error_session_expired: Your session has expired. Please login again.
text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
setting_session_lifetime: Session maximum lifetime
setting_session_timeout: Session inactivity timeout
label_session_expiration: Session expiration
permission_close_project: Close / reopen the project
label_show_closed_projects: View closed projects
button_close: Close
button_reopen: Reopen
project_status_active: active
project_status_closed: closed
project_status_archived: archived
text_project_closed: This project is closed and read-only.
notice_user_successful_create: User %{id} created.
field_core_fields: Standard fields
field_timeout: Timeout (in seconds)
setting_thumbnails_enabled: Display attachment thumbnails
setting_thumbnails_size: Thumbnails size (in pixels)
label_status_transitions: Status transitions
label_fields_permissions: Fields permissions
label_readonly: Read-only
label_required: Required
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_issue_conflict_resolution_add_notes: Aggiunge le mie note e non salvare le mie ulteriori modifiche
text_issue_conflict_resolution_overwrite: Applica comunque le mie modifiche (le note precedenti verranno mantenute ma alcuni cambiamenti potrebbero essere sovrascritti)
notice_issue_update_conflict: La segnalazione è stata aggiornata da un altro utente mentre la stavi editando.
text_issue_conflict_resolution_cancel: Cancella ogni modifica e rivisualizza %{link}
permission_manage_related_issues: Gestisci relative segnalazioni
field_auth_source_ldap_filter: Filtro LDAP
label_search_for_watchers: Cerca osservatori da aggiungere
notice_account_deleted: Il tuo account sarà definitivamente rimosso.
setting_unsubscribe: Consentire agli utenti di cancellare il proprio account
button_delete_my_account: Cancella il mio account
text_account_destroy_confirmation: "Sei sicuro di voler procedere?\nIl tuo account sarà definitivamente cancellato, senza alcuna possibilità di ripristino."
error_session_expired: "La tua sessione è scaduta. Effettua nuovamente il login."
text_session_expiration_settings: "Attenzione: la modifica di queste impostazioni può far scadere le sessioni correnti, compresa la tua."
setting_session_lifetime: Massima durata di una sessione
setting_session_timeout: Timeout di inattività di una sessione
label_session_expiration: Scadenza sessione
permission_close_project: Chiusura / riapertura progetto
label_show_closed_projects: Vedi progetti chiusi
button_close: Chiudi
button_reopen: Riapri
project_status_active: attivo
project_status_closed: chiuso
project_status_archived: archiviato
text_project_closed: Questo progetto è chiuso e in sola lettura.
notice_user_successful_create: Creato utente %{id}.
field_core_fields: Campi standard
field_timeout: Timeout (in secondi)
setting_thumbnails_enabled: Mostra miniature degli allegati
setting_thumbnails_size: Dimensioni delle miniature (in pixels)
label_status_transitions: Transizioni di stato
label_fields_permissions: Permessi sui campi
label_readonly: Sola lettura
label_required: Richiesto
text_repository_identifier_info: Consentiti solo lettere minuscole (a-z), numeri, trattini e trattini bassi.<br />Una volta salvato, ll'identificatore non può essere modificato.
field_board_parent: Parent forum
label_attribute_of_project: Project's %{name}
label_attribute_of_author: Author's %{name}
label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_assigned_to: Assegnatari %{name}
label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: Copy subtasks
label_copied_to: copied to
label_copied_from: copied from
label_any_issues_in_project: any issues in project
label_any_issues_not_in_project: any issues not in project
field_private_notes: Private notes
permission_view_private_notes: View private notes
permission_set_notes_private: Set notes as private
label_no_issues_in_project: no issues in project
label_copy_subtasks: Copia sottoattività
label_copied_to: copia a
label_copied_from: copia da
label_any_issues_in_project: ogni segnalazione del progetto
label_any_issues_not_in_project: ogni segnalazione non nel progetto
field_private_notes: Note private
permission_view_private_notes: Visualizza note private
permission_set_notes_private: Imposta note come private
label_no_issues_in_project: progetto privo di segnalazioni
label_any: tutti
label_last_n_weeks: last %{count} weeks
setting_cross_project_subtasks: Allow cross-project subtasks
label_last_n_weeks: ultime %{count} settimane
setting_cross_project_subtasks: Consenti sottoattività cross-project
label_cross_project_descendants: Con sottoprogetti
label_cross_project_tree: Con progetto padre
label_cross_project_hierarchy: Con gerarchia progetto
label_cross_project_system: Con tutti i progetti
button_hide: Hide
setting_non_working_week_days: Non-working days
label_in_the_next_days: in the next
label_in_the_past_days: in the past
label_attribute_of_user: User's %{name}
text_turning_multiple_off: If you disable multiple values, multiple values will be
removed in order to preserve only one value per item.
label_attribute_of_issue: Issue's %{name}
permission_add_documents: Add documents
permission_edit_documents: Edit documents
permission_delete_documents: Delete documents
button_hide: Nascondi
setting_non_working_week_days: Giorni non lavorativi
label_in_the_next_days: nei prossimi
label_in_the_past_days: nei passati
label_attribute_of_user: Utente %{name}
text_turning_multiple_off: Disabilitando valori multipli, i valori multipli verranno rimossi, in modo da mantenere un solo valore per item.
label_attribute_of_issue: Segnalazione %{name}
permission_add_documents: Aggiungi documenti
permission_edit_documents: Edita documenti
permission_delete_documents: Cancella documenti
label_gantt_progress_line: Progress line
setting_jsonp_enabled: Enable JSONP support
field_inherit_members: Inherit members
field_closed_on: Closed
setting_default_projects_tracker_ids: Default trackers for new projects
setting_jsonp_enabled: Abilita supporto a JSONP
field_inherit_members: Eredita membri
field_closed_on: Chiuso
setting_default_projects_tracker_ids: Trackers di default per nuovi progetti
label_total_time: Totale

View File

@@ -50,8 +50,8 @@ ko:
one: "약 한시간"
other: "약 %{count}시간"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 시간"
other: "%{count} 시간"
x_days:
one: "하루"
other: "%{count}일"

View File

@@ -253,7 +253,6 @@ lt:
error_unable_delete_issue_status: 'Negalima ištrinti darbo statuso'
error_unable_to_connect: Negalima prisijungti (%{value})
error_attachment_too_big: "Ši byla negali būti įkelta, nes viršija maksimalią (%{max_size}) leistiną bylos apimtį"
error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
warning_attachments_not_saved: "%{count} byla(ų) negali būti išsaugota."
mail_subject_lost_password: "Jūsų %{value} slaptažodis"

View File

@@ -46,8 +46,8 @@ lv:
one: "aptuveni 1 stunda"
other: "aptuveni %{count} stundas"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 stunda"
other: "%{count} stundas"
x_days:
one: "1 diena"
other: "%{count} dienas"
@@ -775,7 +775,7 @@ lv:
button_cancel: Atcelt
button_activate: Aktivizēt
button_sort: Kārtot
button_log_time: Ilgs laiks
button_log_time: Reģistrēt laiku
button_rollback: Atjaunot uz šo versiju
button_watch: Vērot
button_unwatch: Nevērot

View File

@@ -50,8 +50,8 @@ mk:
one: "околу 1 час"
other: "околу %{count} часа"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 час"
other: "%{count} часа"
x_days:
one: "1 ден"
other: "%{count} дена"

View File

@@ -51,8 +51,8 @@ mn:
one: "1 цаг орчим"
other: "ойролцоогоор %{count} цаг"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 цаг"
other: "%{count} цаг"
x_days:
one: "1 өдөр"
other: "%{count} өдөр"

View File

@@ -50,7 +50,7 @@ nl:
other: "ongeveer %{count} uren"
x_hours:
one: "1 uur"
other: "%{count} hours"
other: "%{count} uren"
x_days:
one: "1 dag"
other: "%{count} dagen"

View File

@@ -44,8 +44,8 @@
one: "rundt 1 time"
other: "rundt %{count} timer"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 time"
other: "%{count} timer"
x_days:
one: "1 dag"
other: "%{count} dager"
@@ -1045,8 +1045,8 @@
label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: Copy subtasks
label_copied_to: copied to
label_copied_from: copied from
label_copied_to: kopiert til
label_copied_from: kopiert fra
label_any_issues_in_project: any issues in project
label_any_issues_not_in_project: any issues not in project
field_private_notes: Private notes

View File

@@ -82,8 +82,8 @@ pl:
one: "około godziny"
other: "około %{count} godzin"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 godzina"
other: "%{count} godzin"
x_days:
one: "1 dzień"
other: "%{count} dni"
@@ -772,7 +772,7 @@ pl:
text_default_administrator_account_changed: Zmieniono domyślne hasło administratora
text_destroy_time_entries: Usuń wpisy dziennika
text_destroy_time_entries_question: Przepracowano %{hours} godzin przy zagadnieniu, które chcesz usunąć. Co chcesz zrobić?
text_email_delivery_not_configured: "Dostarczanie poczty elektronicznej nie zostało skonfigurowane, więc powiadamianie jest nieaktywne.\nSkonfiguruj serwer SMTP w config/email.yml a następnie zrestartuj aplikację i uaktywnij to."
text_email_delivery_not_configured: "Dostarczanie poczty elektronicznej nie zostało skonfigurowane, więc powiadamianie jest nieaktywne.\nSkonfiguruj serwer SMTP w config/configuration.yml a następnie zrestartuj aplikację i uaktywnij to."
text_enumeration_category_reassign_to: 'Zmień przypisanie na tą wartość:'
text_enumeration_destroy_question: "%{count} obiektów jest przypisanych do tej wartości."
text_file_repository_writable: Zapisywalne repozytorium plików

View File

@@ -1105,5 +1105,5 @@ pt-BR:
setting_jsonp_enabled: Ativar suporte JSONP
field_inherit_members: Herdar membros
field_closed_on: Fechado
setting_default_projects_tracker_ids: Default trackers for new projects
setting_default_projects_tracker_ids: Tipos padrões para novos projeto
label_total_time: Total

View File

@@ -1091,5 +1091,5 @@ pt:
setting_jsonp_enabled: Activar suporte JSONP
field_inherit_members: Herdar membros
field_closed_on: Fechado
setting_default_projects_tracker_ids: Default trackers for new projects
setting_default_projects_tracker_ids: Tipo de tarefa padrão para novos projectos
label_total_time: Total

View File

@@ -45,8 +45,8 @@ ro:
one: "aproximativ o oră"
other: "aproximativ %{count} ore"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 oră"
other: "%{count} ore"
x_days:
one: "o zi"
other: "%{count} zile"

View File

@@ -1080,17 +1080,17 @@ ru:
label_between: между
setting_issue_group_assignment: Разрешить назначение задач группам пользователей
label_diff: Разница(diff)
text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
text_git_repository_note: Хранилище пустое и локальное (т.е. /gitrepo, c:\gitrepo)
description_query_sort_criteria_direction: Порядок сортировки
description_project_scope: Search scope
description_project_scope: Область поиска
description_filter: Фильтр
description_user_mail_notification: Mail notification settings
description_date_from: Enter start date
description_message_content: Message content
description_available_columns: Available Columns
description_date_range_interval: Choose range by selecting start and end date
description_issue_category_reassign: Choose issue category
description_search: Searchfield
description_user_mail_notification: Настройки почтовых оповещений
description_date_from: Введите дату начала
description_message_content: Содержание сообщения
description_available_columns: Доступные столбцы
description_date_range_interval: Выберите диапазон, установив дату начала и дату окончания
description_issue_category_reassign: Выберите категорию задачи
description_search: Поле поиска
description_notes: Примечания
description_date_range_list: Выберите диапазон из списка
description_choose_project: Проекты
@@ -1145,7 +1145,7 @@ ru:
project_status_active: открытые
project_status_closed: закрытые
project_status_archived: архивированные
text_project_closed: Проект закрыт и находиться в режиме только для чтения.
text_project_closed: Проект закрыт и находится в режиме только для чтения.
notice_user_successful_create: Пользователь %{id} создан.
field_core_fields: Стандартные поля
field_timeout: Таймаут (в секундах)

View File

@@ -46,8 +46,8 @@ sk:
one: "okolo 1 hodiny"
other: "okolo %{count} hodín"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 hodina"
other: "%{count} hodín"
x_days:
one: "1 deň"
other: "%{count} dní"

View File

@@ -50,8 +50,8 @@ sl:
one: "okrog 1. ure"
other: "okrog %{count} ur"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 ura"
other: "%{count} ur"
x_days:
one: "1 dan"
other: "%{count} dni"

View File

@@ -50,8 +50,8 @@ sq:
one: "about 1 hour"
other: "about %{count} hours"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 ore"
other: "%{count} ore"
x_days:
one: "1 day"
other: "%{count} days"

View File

@@ -53,8 +53,8 @@ sr-YU:
one: "približno jedan sat"
other: "približno %{count} sati"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 sat"
other: "%{count} sati"
x_days:
one: "jedan dan"
other: "%{count} dana"

View File

@@ -51,8 +51,8 @@ sr:
one: "приближно један сат"
other: "приближно %{count} сати"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 сат"
other: "%{count} сати"
x_days:
one: "један дан"
other: "%{count} дана"

View File

@@ -272,6 +272,7 @@ sv:
field_author: Författare
field_created_on: Skapad
field_updated_on: Uppdaterad
field_closed_on: Stängd
field_field_format: Format
field_is_for_all: För alla projekt
field_possible_values: Möjliga värden
@@ -372,6 +373,7 @@ sv:
field_timeout: "Timeout (i sekunder)"
field_board_parent: Förälderforum
field_private_notes: Privata anteckningar
field_inherit_members: Ärv medlemmar
setting_app_title: Applikationsrubrik
setting_app_subtitle: Applikationsunderrubrik
@@ -440,6 +442,8 @@ sv:
setting_thumbnails_enabled: Visa miniatyrbilder av bilagor
setting_thumbnails_size: Storlek på miniatyrbilder (i pixlar)
setting_non_working_week_days: Lediga dagar
setting_jsonp_enabled: Aktivera JSONP-stöd
setting_default_projects_tracker_ids: Standardärendetyper för nya projekt
permission_add_project: Skapa projekt
permission_add_subprojects: Skapa underprojekt
@@ -657,6 +661,7 @@ sv:
one: 1 ärende
other: "%{count} ärenden"
label_total: Total
label_total_time: Total tid
label_permissions: Behörigheter
label_current_status: Nuvarande status
label_new_statuses_allowed: Nya tillåtna statusvärden
@@ -1120,8 +1125,3 @@ sv:
description_date_from: Ange startdatum
description_date_to: Ange slutdatum
text_repository_identifier_info: 'Endast gemener (a-z), siffror, streck och understreck är tillåtna.<br />När identifieraren sparats kan den inte ändras.'
setting_jsonp_enabled: Enable JSONP support
field_inherit_members: Inherit members
field_closed_on: Closed
setting_default_projects_tracker_ids: Default trackers for new projects
label_total_time: Total

View File

@@ -56,8 +56,8 @@ tr:
one: 'yaklaşık 1 saat'
other: 'yaklaşık %{count} saat'
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 saat"
other: "%{count} saat"
x_days:
one: '1 gün'
other: '%{count} gün'

View File

@@ -123,8 +123,8 @@
one: "約 1 小時"
other: "約 %{count} 小時"
x_hours:
one: "1 hour"
other: "%{count} hours"
one: "1 小時"
other: "%{count} 小時"
x_days:
one: "1 天"
other: "%{count} 天"
@@ -712,7 +712,7 @@
label_nobody: 無名
label_next: 下一頁
label_previous: 上一頁
label_used_by: Used by
label_used_by: 已使用專案
label_details: 明細
label_add_note: 加入一個新筆記
label_per_page: 每頁

View File

@@ -1075,19 +1075,18 @@ zh:
label_cross_project_hierarchy: 与项目继承层次共享
label_cross_project_system: 与所有项目共享
button_hide: 隐藏
setting_non_working_week_days: Non-working days
label_in_the_next_days: in the next
label_in_the_past_days: in the past
label_attribute_of_user: User's %{name}
text_turning_multiple_off: If you disable multiple values, multiple values will be
removed in order to preserve only one value per item.
label_attribute_of_issue: Issue's %{name}
permission_add_documents: Add documents
permission_edit_documents: Edit documents
permission_delete_documents: Delete documents
label_gantt_progress_line: Progress line
setting_jsonp_enabled: Enable JSONP support
field_inherit_members: Inherit members
field_closed_on: Closed
setting_default_projects_tracker_ids: Default trackers for new projects
setting_non_working_week_days: 非工作日
label_in_the_next_days: 在未来几天之内
label_in_the_past_days: 在过去几天之内
label_attribute_of_user: 用户是 %{name}
text_turning_multiple_off: 如果您停用多重值设定,重复的值将被移除,以使每个项目仅保留一个值
label_attribute_of_issue: 问题是 %{name}
permission_add_documents: 添加文档
permission_edit_documents: 编辑文档
permission_delete_documents: 删除文档
label_gantt_progress_line: 进度线
setting_jsonp_enabled: 启用JSONP支持
field_inherit_members: 继承父项目成员
field_closed_on: 结束日期
setting_default_projects_tracker_ids: 新建项目默认跟踪标签
label_total_time: 合计

View File

@@ -99,9 +99,11 @@ RedmineApp::Application.routes.draw do
match 'copy', :via => [:get, :post]
end
resources :memberships, :shallow => true, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do
collection do
get 'autocomplete'
shallow do
resources :memberships, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do
collection do
get 'autocomplete'
end
end
end
@@ -134,15 +136,19 @@ RedmineApp::Application.routes.draw do
get 'report', :on => :collection
end
resources :queries, :only => [:new, :create]
resources :issue_categories, :shallow => true
shallow do
resources :issue_categories
end
resources :documents, :except => [:show, :edit, :update, :destroy]
resources :boards
resources :repositories, :shallow => true, :except => [:index, :show] do
member do
match 'committers', :via => [:get, :post]
shallow do
resources :repositories, :except => [:index, :show] do
member do
match 'committers', :via => [:get, :post]
end
end
end
match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get
resources :wiki, :except => [:index, :new, :create], :as => 'wiki_page' do
member do
@@ -176,7 +182,9 @@ RedmineApp::Application.routes.draw do
get 'report'
end
end
resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
shallow do
resources :relations, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
end
end
match '/issues', :controller => 'issues', :action => 'destroy', :via => :delete

View File

@@ -4,6 +4,55 @@ Redmine - project management software
Copyright (C) 2006-2013 Jean-Philippe Lang
http://www.redmine.org/
== 2013-09-14 v2.3.3
* Defect #13008: Usage of attribute_present? in UserPreference
* Defect #14340: Autocomplete fields rendering issue with alternate theme
* Defect #14366: Spent Time report sorting on custom fields causes error
* Defect #14369: Open/closed issue counts on issues summary are not displayed with SQLServer
* Defect #14401: Filtering issues on "related to" may ignore other filters
* Defect #14415: Spent time details and report should ignore 'Setting.display_subprojects_issues?' when 'Subproject' filter is enabled.
* Defect #14422: CVS root_url not recognized when connection string does not include port
* Defect #14447: Additional status transitions for assignees do not work if assigned to a group
* Defect #14511: warning: class variable access from toplevel on Ruby 2.0
* Defect #14562: diff of CJK (Chinese/Japanese/Korean) is broken on Ruby 1.8
* Defect #14584: Standard fields disabled for certain trackers still appear in email notifications
* Defect #14607: rake redmine:load_default_data Error
* Defect #14697: Wrong Russian translation in close project message
* Defect #14798: Wrong done_ratio calculation for parent with subtask having estimated_hours=0
* Patch #14485: Traditional Chinese translation for 2.3-stable
* Patch #14502: Russian translation for 2.3-stable
* Patch #14531: Spanish translations for 2.3.x
* Patch #14686: Portuguese translation for 2.3-stable
== 2013-07-14 v2.3.2
* Defect #9996: configuration.yml in documentation , but redmine ask me to create email.yml
* Defect #13692: warning: already initialized constant on Ruby 1.8.7
* Defect #13783: Internal error on time tracking activity enumeration deletion
* Defect #13821: "obj" parameter is not defined for macros used in description of documents
* Defect #13850: Unable to set custom fields for versions using the REST API
* Defect #13910: Values of custom fields are not kept in issues when copying a project
* Defect #13950: Duplicate Lithuanian "error_attachment_too_big" translation keys
* Defect #14015: Ruby hangs when adding a subtask
* Defect #14020: Locking and unlocking a user resets the email notification checkbox
* Defect #14023: Can't delete relation when Redmine runs in a subpath
* Defect #14051: Filtering issues with custom field in date format with NULL(empty) value
* Defect #14178: PDF API broken in version 2.3.1
* Defect #14186: Project name is not properly escaped in issue filters JSON
* Defect #14242: Project auto generation fails when projects created in the same time
* Defect #14245: Gem::InstallError: nokogiri requires Ruby version >= 1.9.2.
* Defect #14346: Latvian translation for "Log time"
* Feature #12888: Adding markings to emails generated by Private comments
* Feature #14419: Include RUBY_PATCHLEVEL and RUBY_RELEASE_DATE in info.rb
* Patch #14005: Swedish Translation for 2.3-stable
* Patch #14101: Receive IMAP by uid's
* Patch #14103: Disconnect and logout from IMAP after mail receive
* Patch #14145: German translation of x_hours
* Patch #14182: pt-BR translation for 2.3-stable
* Patch #14196: Italian translation for 2.3-stable
* Patch #14221: Translation of x_hours for many languages
== 2013-05-01 v2.3.1
* Defect #12650: Lost text after selection in issue list with IE

View File

@@ -1,8 +1,7 @@
begin
require 'zlib'
@@__have_zlib = true
rescue
@@__have_zlib = false
# Zlib not available
end
require 'rexml/document'
@@ -211,7 +210,7 @@ module SVG
@doc.write( data, 0 )
if @config[:compress]
if @@__have_zlib
if Object.const_defined?(:Zlib)
inp, out = IO.pipe
gz = Zlib::GzipWriter.new( out )
gz.write data

View File

@@ -2431,7 +2431,7 @@ class TCPDF
out('1 0 obj');
out('<</Type /Pages');
kids='/Kids [';
0.upto(nb) do |i|
0.upto(nb - 1) do |i|
kids<<(3+2*i).to_s + ' 0 R ';
end
out(kids + ']');
@@ -3103,7 +3103,7 @@ class TCPDF
# is a stream object that contains the definition of the CMap
# (PDF Reference 1.3 chap. 5.9)
newobj();
out('<</Length 383>>');
out('<</Length 345>>')
out('stream');
out('/CIDInit /ProcSet findresource begin');
out('12 dict begin');

View File

@@ -394,7 +394,7 @@ module Redmine
# write the cells on page
issues_to_pdf_write_cells(pdf, query.inline_columns, col_width, row_height, true)
issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_width)
issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
pdf.SetY(base_y + max_height);
# rows
@@ -474,7 +474,7 @@ module Redmine
# write the cells on page
issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_width)
issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
pdf.SetY(base_y + max_height);
if query.has_column?(:description) && issue.description?
@@ -511,7 +511,10 @@ module Redmine
end
# Draw lines to close the row (MultiCell border drawing in not uniform)
def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y, col_widths)
#
# parameter "col_id_width" is not used. it is kept for compatibility.
def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y,
col_id_width, col_widths)
col_x = top_x
pdf.Line(col_x, top_y, col_x, lower_y) # id right border
col_widths.each do |width|

View File

@@ -675,7 +675,7 @@ module Redmine
start_date + (end_date - start_date + 1) * (progress / 100.0)
end
# Sorts a collection of issues by start_date, due_date, id for gantt rendering
# TODO: Sorts a collection of issues by start_date, due_date, id for gantt rendering
def sort_issues!(issues)
issues.sort! { |a, b| gantt_issue_compare(a, b) }
end

View File

@@ -29,25 +29,27 @@ module Redmine
imap = Net::IMAP.new(host, port, ssl)
imap.login(imap_options[:username], imap_options[:password]) unless imap_options[:username].nil?
imap.select(folder)
imap.search(['NOT', 'SEEN']).each do |message_id|
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
logger.debug "Receiving message #{message_id}" if logger && logger.debug?
imap.uid_search(['NOT', 'SEEN']).each do |uid|
msg = imap.uid_fetch(uid,'RFC822')[0].attr['RFC822']
logger.debug "Receiving message #{uid}" if logger && logger.debug?
if MailHandler.receive(msg, options)
logger.debug "Message #{message_id} successfully received" if logger && logger.debug?
logger.debug "Message #{uid} successfully received" if logger && logger.debug?
if imap_options[:move_on_success]
imap.copy(message_id, imap_options[:move_on_success])
imap.uid_copy(uid, imap_options[:move_on_success])
end
imap.store(message_id, "+FLAGS", [:Seen, :Deleted])
imap.uid_store(uid, "+FLAGS", [:Seen, :Deleted])
else
logger.debug "Message #{message_id} can not be processed" if logger && logger.debug?
imap.store(message_id, "+FLAGS", [:Seen])
logger.debug "Message #{uid} can not be processed" if logger && logger.debug?
imap.uid_store(uid, "+FLAGS", [:Seen])
if imap_options[:move_on_failure]
imap.copy(message_id, imap_options[:move_on_failure])
imap.store(message_id, "+FLAGS", [:Deleted])
imap.uid_copy(uid, imap_options[:move_on_failure])
imap.uid_store(uid, "+FLAGS", [:Deleted])
end
end
end
imap.expunge
imap.logout
imap.disconnect
end
private

View File

@@ -10,16 +10,16 @@ module Redmine
s = "Environment:\n"
s << [
["Redmine version", Redmine::VERSION],
["Ruby version", "#{RUBY_VERSION} (#{RUBY_PLATFORM})"],
["Ruby version", "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"],
["Rails version", Rails::VERSION::STRING],
["Environment", Rails.env],
["Database adapter", ActiveRecord::Base.connection.adapter_name]
].map {|info| " %-40s %s" % info}.join("\n")
].map {|info| " %-30s %s" % info}.join("\n")
s << "\nRedmine plugins:\n"
plugins = Redmine::Plugin.all
if plugins.any?
s << plugins.map {|plugin| " %-40s %s" % [plugin.id.to_s, plugin.version.to_s]}.join("\n")
s << plugins.map {|plugin| " %-30s %s" % [plugin.id.to_s, plugin.version.to_s]}.join("\n")
else
s << " no plugin installed"
end

View File

@@ -335,7 +335,7 @@ module Redmine
# :pserver:anonymous@foo.bar:/path => /path
# :ext:cvsservername:/path => /path
def root_url_path
root_url.to_s.gsub(/^:.+:\d*/, '')
root_url.to_s.gsub(%r{^:.+?(?=/)}, '')
end
# convert a date/time into the CVS-format

View File

@@ -333,7 +333,7 @@ module Redmine
def annotate(path, identifier=nil)
identifier = 'HEAD' if identifier.blank?
cmd_args = %w|blame|
cmd_args = %w|blame --encoding=UTF-8|
cmd_args << "-p" << identifier << "--" << scm_iconv(@path_encoding, 'UTF-8', path)
blame = Annotate.new
content = nil

View File

@@ -33,7 +33,6 @@ module Redmine
module CodeRay
require 'coderay'
require 'coderay/helpers/file_type'
class << self
# Highlights +text+ as the content of +filename+

View File

@@ -205,12 +205,20 @@ module Redmine
end
end
ending = -1
while ending >= -(max - starting) && line_left[ending] == line_right[ending]
while ending >= -(max - starting) && (line_left[ending] == line_right[ending])
ending -= 1
end
if (! "".respond_to?(:force_encoding)) && ending > (-1 * line_left.size)
while line_left[ending].ord.between?(128, 191) && ending > -1
ending -= 1
while line_left[ending].ord.between?(128, 255) && ending < -1
if line_left[ending].ord.between?(128, 191)
if line_left[ending + 1].ord.between?(128, 191)
ending += 1
else
break
end
else
ending += 1
end
end
end
unless starting == 0 && ending == -1

View File

@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
TINY = 1
TINY = 3
# Branch values:
# * official release: nil

View File

@@ -2,6 +2,7 @@ desc 'Load Redmine default configuration data. Language is chosen interactively
namespace :redmine do
task :load_default_data => :environment do
require 'custom_field'
include Redmine::I18n
set_language_if_valid('en')

View File

@@ -503,10 +503,20 @@ task :migrate_from_mantis => :environment do
# Make sure bugs can refer bugs in other projects
Setting.cross_project_issue_relations = 1 if Setting.respond_to? 'cross_project_issue_relations'
# Turn off email notifications
Setting.notified_events = []
old_notified_events = Setting.notified_events
old_password_min_length = Setting.password_min_length
begin
# Turn off email notifications temporarily
Setting.notified_events = []
Setting.password_min_length = 4
# Run the migration
MantisMigrate.establish_connection db_params
MantisMigrate.migrate
ensure
# Restore previous settings
Setting.notified_events = old_notified_events
Setting.password_min_length = old_password_min_length
end
MantisMigrate.establish_connection db_params
MantisMigrate.migrate
end
end

View File

@@ -245,8 +245,8 @@ namespace :redmine do
if name_attr = TracSessionAttribute.find_by_sid_and_name(username, 'name')
name = name_attr.value
end
name =~ (/(.*)(\s+\w+)?/)
fn = $1.strip
name =~ (/(\w+)(\s+\w+)?/)
fn = ($1 || "-").strip
ln = ($2 || '-').strip
u = User.new :mail => mail.gsub(/[^-@a-z0-9\.]/i, '-'),
@@ -762,10 +762,19 @@ namespace :redmine do
prompt('Target project identifier') {|identifier| TracMigrate.target_project_identifier identifier}
puts
# Turn off email notifications
Setting.notified_events = []
TracMigrate.migrate
old_notified_events = Setting.notified_events
old_password_min_length = Setting.password_min_length
begin
# Turn off email notifications temporarily
Setting.notified_events = []
Setting.password_min_length = 4
# Run the migration
TracMigrate.migrate
ensure
# Restore previous settings
Setting.notified_events = old_notified_events
Setting.password_min_length = old_password_min_length
end
end
end

View File

@@ -575,7 +575,7 @@ table.members td.group { padding-left: 20px; background: url(../images/group.png
input#principal_search, input#user_search {width:90%}
input.autocomplete {
background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px;
background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px !important;
border:1px solid #9EB1C2; border-radius:2px; height:1.5em;
}
input.autocomplete.ajax-loading {

View File

@@ -0,0 +1,7 @@
--- a.txt 2013-07-27 06:03:49.133257759 +0900
+++ b.txt 2013-07-27 06:03:58.791221118 +0900
@@ -1,3 +1,3 @@
aaaa
-日本記
+日本娘
bbbb

View File

@@ -0,0 +1,7 @@
--- a.txt 2013-07-27 04:20:45.973229414 +0900
+++ b.txt 2013-07-27 04:20:52.366228105 +0900
@@ -1,3 +1,3 @@
aaaa
-日本記
+日本誘
bbbb

View File

@@ -0,0 +1,7 @@
--- a.txt 2013-07-27 05:52:11.415223830 +0900
+++ b.txt 2013-07-27 05:52:18.249190358 +0900
@@ -1,3 +1,3 @@
aaaa
-日本記ok
+日本誘ok
bbbb

View File

@@ -83,7 +83,7 @@ class AdminControllerTest < ActionController::TestCase
def test_test_email
user = User.find(1)
user.pref[:no_self_notified] = '1'
user.pref.no_self_notified = '1'
user.pref.save!
ActionMailer::Base.deliveries.clear

View File

@@ -126,4 +126,11 @@ class EnumerationsControllerTest < ActionController::TestCase
# check that the issue was reassign
assert_equal 6, issue.reload.priority_id
end
def test_destroy_enumeration_in_use_with_blank_reassignment
assert_no_difference 'IssuePriority.count' do
delete :destroy, :id => 4, :reassign_to_id => ''
end
assert_response :success
end
end

View File

@@ -209,7 +209,7 @@ class ProjectsControllerTest < ActionController::TestCase
assert_response :success
project = assigns(:project)
assert_kind_of Project, project
assert_not_nil project.errors[:parent_id]
assert_not_equal [], project.errors[:parent_id]
end
test "#create by non-admin user with add_subprojects permission should create a project with a parent_id" do
@@ -244,7 +244,7 @@ class ProjectsControllerTest < ActionController::TestCase
assert_response :success
project = assigns(:project)
assert_kind_of Project, project
assert_not_nil project.errors[:parent_id]
assert_not_equal [], project.errors[:parent_id]
end
test "#create by non-admin user with add_subprojects permission should fail with unauthorized parent_id" do
@@ -265,7 +265,7 @@ class ProjectsControllerTest < ActionController::TestCase
assert_response :success
project = assigns(:project)
assert_kind_of Project, project
assert_not_nil project.errors[:parent_id]
assert_not_equal [], project.errors[:parent_id]
end
def test_create_subproject_with_inherit_members_should_inherit_members

View File

@@ -54,6 +54,24 @@ class ReportsControllerTest < ActionController::TestCase
end
end
def test_get_issue_report_details_by_tracker_should_show_issue_count
Issue.delete_all
Issue.generate!(:tracker_id => 1)
Issue.generate!(:tracker_id => 1)
Issue.generate!(:tracker_id => 1, :status_id => 5)
Issue.generate!(:tracker_id => 2)
get :issue_report_details, :id => 1, :detail => 'tracker'
assert_select 'table.list tbody :nth-child(1)' do
assert_select 'td', :text => 'Bug'
assert_select ':nth-child(2)', :text => '2' # status:1
assert_select ':nth-child(3)', :text => '-' # status:2
assert_select ':nth-child(8)', :text => '2' # open
assert_select ':nth-child(9)', :text => '1' # closed
assert_select ':nth-child(10)', :text => '3' # total
end
end
def test_get_issue_report_details_by_priority
get :issue_report_details, :id => 1, :detail => 'priority'
assert_equal IssuePriority.all.reverse, assigns(:rows)

View File

@@ -23,17 +23,23 @@ class RepositoriesBazaarControllerTest < ActionController::TestCase
fixtures :projects, :users, :roles, :members, :member_roles,
:repositories, :enabled_modules
REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository/trunk').to_s
REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s
REPOSITORY_PATH_TRUNK = File.join(REPOSITORY_PATH, "trunk")
PRJ_ID = 3
CHAR_1_UTF8_HEX = "\xc3\x9c"
def setup
User.current = nil
@project = Project.find(PRJ_ID)
@repository = Repository::Bazaar.create(
:project => @project,
:url => REPOSITORY_PATH,
:url => REPOSITORY_PATH_TRUNK,
:log_encoding => 'UTF-8')
assert @repository
@char_1_utf8 = CHAR_1_UTF8_HEX.dup
if @char_1_utf8.respond_to?(:force_encoding)
@char_1_utf8.force_encoding('UTF-8')
end
end
if File.directory?(REPOSITORY_PATH)
@@ -137,26 +143,68 @@ class RepositoriesBazaarControllerTest < ActionController::TestCase
:path => repository_path_hash(['doc-mkdir.txt'])[:param]
assert_response :success
assert_template 'annotate'
assert_tag :tag => 'th', :content => '2',
:sibling => {
:tag => 'td',
:child => {
:tag => 'a',
:content => '3'
}
}
assert_tag :tag => 'th', :content => '2',
:sibling => { :tag => 'td', :content => /jsmith/ }
assert_tag :tag => 'th', :content => '2',
:sibling => {
:tag => 'td',
:child => {
:tag => 'a',
:content => '3'
}
}
assert_tag :tag => 'th', :content => '2',
:sibling => { :tag => 'td', :content => /Main purpose/ }
assert_select "th.line-num", :text => '2' do
assert_select "+ td.revision" do
assert_select "a", :text => '3'
assert_select "+ td.author", :text => "jsmith@" do
assert_select "+ td",
:text => "Main purpose:"
end
end
end
end
def test_annotate_author_escaping
repository = Repository::Bazaar.create(
:project => @project,
:url => File.join(REPOSITORY_PATH, "author_escaping"),
:identifier => 'author_escaping',
:log_encoding => 'UTF-8')
assert repository
get :annotate, :id => PRJ_ID, :repository_id => 'author_escaping',
:path => repository_path_hash(['author-escaping-test.txt'])[:param]
assert_response :success
assert_template 'annotate'
assert_select "th.line-num", :text => '1' do
assert_select "+ td.revision" do
assert_select "a", :text => '2'
assert_select "+ td.author", :text => "test &amp;" do
assert_select "+ td",
:text => "author escaping test"
end
end
end
end
if REPOSITORY_PATH.respond_to?(:force_encoding)
def test_annotate_author_non_ascii
log_encoding = nil
if Encoding.locale_charmap == "UTF-8" ||
Encoding.locale_charmap == "ISO-8859-1"
log_encoding = Encoding.locale_charmap
end
unless log_encoding.nil?
repository = Repository::Bazaar.create(
:project => @project,
:url => File.join(REPOSITORY_PATH, "author_non_ascii"),
:identifier => 'author_non_ascii',
:log_encoding => log_encoding)
assert repository
get :annotate, :id => PRJ_ID, :repository_id => 'author_non_ascii',
:path => repository_path_hash(['author-non-ascii-test.txt'])[:param]
assert_response :success
assert_template 'annotate'
assert_select "th.line-num", :text => '1' do
assert_select "+ td.revision" do
assert_select "a", :text => '2'
assert_select "+ td.author", :text => "test #{@char_1_utf8}" do
assert_select "+ td",
:text => "author non ASCII test"
end
end
end
end
end
end
def test_destroy_valid_repository

View File

@@ -27,6 +27,7 @@ class RepositoriesGitControllerTest < ActionController::TestCase
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
PRJ_ID = 3
CHAR_1_HEX = "\xc3\x9c"
FELIX_HEX = "Felix Sch\xC3\xA4fer"
NUM_REV = 28
## Git, Mercurial and CVS path encodings are binary.
@@ -50,8 +51,10 @@ class RepositoriesGitControllerTest < ActionController::TestCase
)
assert @repository
@char_1 = CHAR_1_HEX.dup
@felix_utf8 = FELIX_HEX.dup
if @char_1.respond_to?(:force_encoding)
@char_1.force_encoding('UTF-8')
@felix_utf8.force_encoding('UTF-8')
end
end
@@ -532,11 +535,32 @@ class RepositoriesGitControllerTest < ActionController::TestCase
get :annotate, :id => PRJ_ID,
:path => repository_path_hash(['latin-1-dir', "test-#{@char_1}.txt"])[:param],
:rev => r1
assert_tag :tag => 'th',
:content => '1',
:attributes => { :class => 'line-num' },
:sibling => { :tag => 'td',
:content => /test-#{@char_1}.txt/ }
assert_select "th.line-num", :text => '1' do
assert_select "+ td.revision" do
assert_select "a", :text => '57ca437c'
assert_select "+ td.author", :text => "jsmith" do
assert_select "+ td",
:text => "test-#{@char_1}.txt"
end
end
end
end
end
end
end
def test_annotate_latin_1_author
['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', '83ca5fd546063a'].each do |r1|
get :annotate, :id => PRJ_ID,
:path => repository_path_hash([" filename with a leading space.txt "])[:param],
:rev => r1
assert_select "th.line-num", :text => '1' do
assert_select "+ td.revision" do
assert_select "a", :text => '83ca5fd5'
assert_select "+ td.author", :text => @felix_utf8 do
assert_select "+ td",
:text => "And this is a file with a leading and trailing space..."
end
end
end
end

View File

@@ -432,30 +432,15 @@ class RepositoriesMercurialControllerTest < ActionController::TestCase
:rev => r1
assert_response :success
assert_template 'annotate'
assert_tag :tag => 'th',
:content => '1',
:attributes => { :class => 'line-num' },
:sibling =>
{
:tag => 'td',
:attributes => { :class => 'revision' },
:child => { :tag => 'a', :content => '20:709858aafd1b' }
}
assert_tag :tag => 'th',
:content => '1',
:attributes => { :class => 'line-num' },
:sibling =>
{
:tag => 'td' ,
:content => 'jsmith' ,
:attributes => { :class => 'author' },
}
assert_tag :tag => 'th',
:content => '1',
:attributes => { :class => 'line-num' },
:sibling => { :tag => 'td',
:content => /Mercurial is a distributed version control system/ }
assert_select "th.line-num", :text => '1' do
assert_select "+ td.revision" do
assert_select "a", :text => '20:709858aafd1b'
assert_select "+ td.author", :text => "jsmith" do
assert_select "+ td",
:text => "Mercurial is a distributed version control system."
end
end
end
end
end

View File

@@ -443,6 +443,28 @@ class TimelogControllerTest < ActionController::TestCase
:attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
end
def test_index_with_display_subprojects_issues_to_false_should_not_include_subproject_entries
entry = TimeEntry.generate!(:project => Project.find(3))
with_settings :display_subprojects_issues => '0' do
get :index, :project_id => 'ecookbook'
assert_response :success
assert_template 'index'
assert_not_include entry, assigns(:entries)
end
end
def test_index_with_display_subprojects_issues_to_false_and_subproject_filter_should_include_subproject_entries
entry = TimeEntry.generate!(:project => Project.find(3))
with_settings :display_subprojects_issues => '0' do
get :index, :project_id => 'ecookbook', :subproject_id => 3
assert_response :success
assert_template 'index'
assert_include entry, assigns(:entries)
end
end
def test_index_at_project_level_with_date_range
get :index, :project_id => 'ecookbook',
:f => ['spent_on'],
@@ -540,6 +562,24 @@ class TimelogControllerTest < ActionController::TestCase
assert_select 'td.issue_cf_2', :text => 'filter_on_issue_custom_field'
end
def test_index_with_time_entry_custom_field_sorting
field = TimeEntryCustomField.generate!(:field_format => 'string', :name => 'String Field')
TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 1'})
TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 3'})
TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 2'})
field_name = "cf_#{field.id}"
get :index, :c => ["hours", field_name], :sort => field_name
assert_response :success
assert_include field_name.to_sym, assigns(:query).column_names
assert_select "th a.sort", :text => 'String Field'
# Make sure that values are properly sorted
values = assigns(:entries).map {|e| e.custom_field_value(field)}.compact
assert_equal 3, values.size
assert_equal values.sort, values
end
def test_index_atom_feed
get :index, :project_id => 1, :format => 'atom'
assert_response :success

View File

@@ -325,6 +325,18 @@ class UsersControllerTest < ActionController::TestCase
assert_equal [1, 2], u.notified_projects_ids.sort
end
def test_update_status_should_not_update_attributes
user = User.find(2)
user.pref[:no_self_notified] = '1'
user.pref.save
put :update, :id => 2, :user => {:status => 3}
assert_response 302
user = User.find(2)
assert_equal 3, user.status
assert_equal '1', user.pref[:no_self_notified]
end
def test_destroy
assert_difference 'User.count', -1 do
delete :destroy, :id => 2

View File

@@ -82,6 +82,29 @@ class Redmine::ApiTest::VersionsTest < Redmine::ApiTest::Base
assert_tag 'version', :child => {:tag => 'id', :content => version.id.to_s}
end
should "create the version with custom fields" do
field = VersionCustomField.generate!
assert_difference 'Version.count' do
post '/projects/1/versions.xml', {
:version => {
:name => 'API test',
:custom_fields => [
{'id' => field.id.to_s, 'value' => 'Some value'}
]
}
}, credentials('jsmith')
end
version = Version.first(:order => 'id DESC')
assert_equal 'API test', version.name
assert_equal 'Some value', version.custom_field_value(field)
assert_response :created
assert_equal 'application/xml', @response.content_type
assert_select 'version>custom_fields>custom_field[id=?]>value', field.id.to_s, 'Some value'
end
context "with failure" do
should "return the errors" do
assert_no_difference('Version.count') do

View File

@@ -107,10 +107,11 @@ module ObjectHelpers
def TimeEntry.generate!(attributes={})
entry = TimeEntry.new(attributes)
entry.user ||= User.find(2)
entry.issue ||= Issue.find(1)
entry.issue ||= Issue.find(1) unless entry.project
entry.project ||= entry.issue.project
entry.activity ||= TimeEntryActivity.first
entry.spent_on ||= Date.today
entry.hours ||= 1.0
entry.save!
entry
end
@@ -147,4 +148,15 @@ module ObjectHelpers
attachment.save!
attachment
end
def CustomField.generate!(attributes={})
@generated_custom_field_name ||= 'Custom field 0'
@generated_custom_field_name.succ!
field = new(attributes)
field.name = @generated_custom_field_name.dup if field.name.blank?
field.field_format = 'string' if field.field_format.blank?
yield field if block_given?
field.save!
field
end
end

Some files were not shown because too many files have changed in this diff Show More