Compare commits

..

1604 Commits
0.4.2 ... 0.8.2

Author SHA1 Message Date
Jean-Philippe Lang
908dcc4eb4 tagged version 0.8.2
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/tags/0.8.2@2570 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-03-08 14:33:29 +00:00
Jean-Philippe Lang
20bdba13cf Updates for 0.8.2 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2560 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-03-07 12:07:06 +00:00
Jean-Philippe Lang
46c0d72782 Merged r2259 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2559 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-03-07 12:02:08 +00:00
Jean-Philippe Lang
36b5d4f6af Backported r2429, r2430, r248 to r2491 and r2522 from trunk (request and controller objects added to the hooks by default.).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2558 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-03-07 11:43:38 +00:00
Jean-Philippe Lang
b366375e7e Merged r2553 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2557 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-03-07 11:22:56 +00:00
Jean-Philippe Lang
629c106a46 Merged r2515, r2516, r2527, r2534, r2555 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2556 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-03-07 11:17:23 +00:00
Eric Davis
f19ae06a72 Merged r2428 from trunk
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2548 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-03-04 00:03:06 +00:00
Jean-Philippe Lang
69b99aa518 Merged r2520 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2521 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-23 17:36:32 +00:00
Jean-Philippe Lang
cb5d0c469d Merged r2487, r2488 and r2507 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2514 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-22 10:00:25 +00:00
Jean-Philippe Lang
57d10ed893 Merged r2262, r2341 and r2486 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2513 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-21 19:29:33 +00:00
Jean-Philippe Lang
28e4ff8957 Merged r2426 and r2484 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2512 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-21 19:22:31 +00:00
Jean-Philippe Lang
3d1bd79ffb Set version to 0.8.1
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2470 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-15 09:08:26 +00:00
Jean-Philippe Lang
7f957653ad Merged r2463, r2465, r2467, r2468 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2469 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-15 09:04:24 +00:00
Jean-Philippe Lang
9a9141041e Merged r2461 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2462 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-13 17:32:27 +00:00
Jean-Philippe Lang
bc4249e3d3 Merged r2270, r2344, r2359, r2360, r2362, r2363, r2415, r2423, r2424 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2425 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-02-09 18:46:00 +00:00
Jean-Philippe Lang
fae04f3ae1 Merged r2246 and r2248 from trunk (#2456).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2310 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-24 13:01:31 +00:00
Jean-Philippe Lang
b13ef64794 Merged r2265 from trunk (#2523).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2309 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-24 12:27:56 +00:00
Jean-Philippe Lang
683e1c5d73 Merged r2266 from trunk (#2522).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2308 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-24 12:13:16 +00:00
Jean-Philippe Lang
1c1755d278 Merged r2280 from trunk (#2506).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2307 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-24 12:11:52 +00:00
Jean-Philippe Lang
5e6ff86f47 Merged r2302 from trunk (#2466).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2306 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-24 12:10:24 +00:00
Jean-Philippe Lang
764393aa6a Merged r2250 and r2251 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2252 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-10 10:51:59 +00:00
Jean-Philippe Lang
3155b8ccad Merged r2226 and r2233 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2245 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-05 18:16:14 +00:00
Jean-Philippe Lang
567c8ed9b0 Fixed: Darcs adapter works on Win32 only (wrong quotes in commands #2402).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2231 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-04 13:24:56 +00:00
Jean-Philippe Lang
49b6f9e4dd Merged r2218 to r2225 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2230 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-04 13:10:16 +00:00
Jean-Philippe Lang
c9d4d3a2be Merged r2209 to r2211 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2229 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-01-04 13:03:34 +00:00
Jean-Philippe Lang
31178553f3 Merged r2116, r2117 and r2187 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2217 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-31 11:40:03 +00:00
Jean-Philippe Lang
dea10c54f9 Merged r2164 to r2167, r2188 and r2189 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2216 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-31 11:31:02 +00:00
Jean-Philippe Lang
6abd32be9e Merged r2212 to r2214 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2215 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-31 10:47:19 +00:00
Jean-Philippe Lang
56318aab53 Merged r2202 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2205 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-30 10:01:34 +00:00
Jean-Philippe Lang
babb14dd94 Doc updates for 0.8.0 final release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2204 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-30 09:52:49 +00:00
Jean-Philippe Lang
3b90141543 Translation updates.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2200 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-29 15:50:08 +00:00
Jean-Philippe Lang
bce764d9bc Merged r2191 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2198 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-29 15:27:29 +00:00
Jean-Philippe Lang
b65d546245 Merged r2195 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2197 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-29 15:26:17 +00:00
Jean-Philippe Lang
9f12151ac0 Merged r2192 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2193 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-28 13:41:03 +00:00
Jean-Philippe Lang
78cac6f02b Merged r2183 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2184 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-27 14:07:00 +00:00
Jean-Philippe Lang
16b85bda32 Merged r2178 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2179 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-24 13:32:59 +00:00
Jean-Philippe Lang
733987fbb6 Merged r2168 to r2171 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2172 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-24 11:23:17 +00:00
Jean-Philippe Lang
7389b4bed0 Merged r2109, r2118, r2130, r2131, r2134, r2135, r2136 and r2139 to r2145 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2146 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-19 11:45:33 +00:00
Jean-Philippe Lang
4570fcb7a2 Merged r2137 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2138 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-15 20:20:56 +00:00
Jean-Philippe Lang
0a709660d2 Merged r2119 to r2127 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2133 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-14 15:32:11 +00:00
Jean-Philippe Lang
633e026e44 Merged r2110 to r2112 (diff limit) from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2132 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-12 19:49:22 +00:00
Jean-Philippe Lang
618ab6004e Merged r2114 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2115 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-08 18:30:00 +00:00
Jean-Philippe Lang
644f03b834 Set version to stable.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2107 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-07 10:01:10 +00:00
Jean-Philippe Lang
1154141ee7 Merge from trunk up to r2105.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2106 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-07 10:00:40 +00:00
Jean-Philippe Lang
bf42d9b706 0.8 branch added
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/0.8-stable@2099 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-06 22:41:47 +00:00
Jean-Philippe Lang
e2050d61fd Translations updates.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2098 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-06 22:40:50 +00:00
Jean-Philippe Lang
1dfe63093b Slight change to css so that gravatar is vertically centered on user's page.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2097 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-06 18:01:20 +00:00
Jean-Philippe Lang
472ec31662 Fixed: CVS connexion string may not contain @.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2096 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-06 17:40:54 +00:00
Jean-Philippe Lang
e66945cbd8 Fixes Darcs#cat with Postgresql.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2095 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-06 17:20:37 +00:00
Jean-Philippe Lang
8a0a25fceb Changes issue history headings.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2094 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-06 11:21:10 +00:00
Eric Davis
cf77c93cb4 Added several useful hooks to the Issue sidebar
* :view_issues_sidebar_issues_bottom
* :view_issues_sidebar_planning_bottom
* :view_issues_sidebar_queries_bottom


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2093 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-06 00:51:03 +00:00
Eric Davis
956437b7fe Final refactoring on Query#sql_for_field to rename v to value
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2092 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-05 22:56:13 +00:00
Eric Davis
a464d26e73 Bit more refactoring on Query#sql_for_field to remove multiple returns
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2091 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-05 22:56:08 +00:00
Eric Davis
ea77929d62 Refactor: Extracted new method Query#sql_for_field from Query#statement in
order to clean up Query#statement.


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2090 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-05 22:56:03 +00:00
Eric Davis
996b2a5c1d Added :view_issues_history_journal_bottom hook
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2089 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-05 21:03:55 +00:00
Jean-Philippe Lang
50794b08a9 Cross-project gantt and calendar (#1157).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2088 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-05 15:41:32 +00:00
Eric Davis
1b4f0c38ce Added :view_issues_edit_notes_bottom hook
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2087 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-03 23:18:12 +00:00
Eric Davis
5f9b1b0e0b Added :controller_issues_edit_before_save hook
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2086 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-03 23:18:07 +00:00
Jean-Philippe Lang
93c04f2666 Fixed: wrong digest for text files under Windows (#2264).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2085 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-02 17:57:13 +00:00
Jean-Philippe Lang
218e1bb267 Use style attribute for setting width of table cells in progress bars (#2267).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2084 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-02 17:29:52 +00:00
Jean-Philippe Lang
1ce2ed065a Fixed: activity broken by r2066 with postgresql (#2266).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2083 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-02 17:16:06 +00:00
Jean-Philippe Lang
d3386a5af7 Fixed: 404 when "Apply" clicked on activity page (#2251).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2082 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-01 17:27:44 +00:00
winterheart
5330ca9b8c ru.yml update
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2081 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-01 16:11:05 +00:00
winterheart
84247e7272 Translation updates (#2249, #2250, #2252, #2254)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2080 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-12-01 16:00:54 +00:00
Jean-Philippe Lang
e7b6a56a97 Replaces User.find_active with a named scope.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2079 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 16:57:56 +00:00
Jean-Philippe Lang
9572699301 Changes Portuguese decimal separator (#1372).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2078 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 16:34:39 +00:00
Jean-Philippe Lang
84e70634fb Adds To and Cc as watchers when submitting an issue by email (#2245).
Only works if the sender has the 'Add issue watchers' permission.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2077 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 16:00:45 +00:00
Jean-Philippe Lang
94899e0339 Adds --status option to rdm-mailhandler.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2076 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 15:51:44 +00:00
Jean-Philippe Lang
abacc2754e Adds status option to email integration rake tasks.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2075 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 14:57:46 +00:00
Jean-Philippe Lang
2fa8030afc Mail handler: check workflow for status set/change.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2074 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 14:55:45 +00:00
Jean-Philippe Lang
0b2299c7d1 Adds link to user's account on issue history.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2073 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 14:31:01 +00:00
Jean-Philippe Lang
5f3f2e756b Obfuscates email address on user's account page using javascript.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2072 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 14:23:57 +00:00
Jean-Philippe Lang
dfc7a94578 Slight changes to profile on account page and last connexion date added.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2071 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 13:42:15 +00:00
Jean-Philippe Lang
0399b85ab6 Adds links between account and user's activity pages.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2070 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 13:38:07 +00:00
Jean-Philippe Lang
9e5edfb728 Adds atom feed on user's account page.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2069 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 12:18:59 +00:00
Jean-Philippe Lang
b8b473244c Fixes activity atom link params (when not on first page).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2068 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 12:14:12 +00:00
Jean-Philippe Lang
6e777b7453 Makes activity view accept a user_id param to show user's activity (#1002).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2067 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 12:12:06 +00:00
Jean-Philippe Lang
fce4615f10 Display latest user's activity on account/show view.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2066 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-30 11:18:22 +00:00
winterheart
b5fcea9e74 Italian update (#2239)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2063 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-28 15:44:59 +00:00
Jean-Philippe Lang
5014b23c2a Fixed: inappropriate redirection to login or register page may occur (#2206). Eg. user clicks login link twice before logging in.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2062 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-27 20:15:45 +00:00
Jean-Philippe Lang
a6b6dc60f4 Typo in gloc:update task description (#2243).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2061 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-27 18:43:18 +00:00
Jean-Philippe Lang
9b1efcfaab Typo in lang files (#2241).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2060 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-27 18:41:40 +00:00
Jean-Philippe Lang
546b98a118 Adds a css class on menu items in order to apply item specific styles (eg. icons).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2059 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-27 18:04:48 +00:00
winterheart
7a441c1bc4 rake gloc:update, update for Serbian (#2232)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2057 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-26 17:32:56 +00:00
Jean-Philippe Lang
c54f15e35f Do not request blank LDAP attributes.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2056 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-25 19:33:41 +00:00
Jean-Philippe Lang
db37e578f2 Slight tests fixes.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2055 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-25 17:37:41 +00:00
Jean-Philippe Lang
9e1192a54d Fixed date filters accuracy with SQLite (#2221).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2054 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-23 16:40:35 +00:00
Jean-Philippe Lang
06266c8fec Extends child_pages macro to display child pages based on page parameter (#1975).
It can also be called from anywhere now (not only from wiki pages).

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2053 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-22 11:44:07 +00:00
winterheart
af7e586b06 removing BOM, sorting, #2169
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2052 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-21 16:40:11 +00:00
winterheart
0b94f4afa9 fix for Polish, #2215
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2051 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-21 16:35:00 +00:00
Jean-Philippe Lang
5a51412e6a Remove eclipse files
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2048 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-19 19:38:19 +00:00
winterheart
752d574b49 Typo in sv, #2213
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2047 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-19 15:52:09 +00:00
Jean-Philippe Lang
a303b5e2d5 Fixed: Printing long roadmap doesn't split across pages (#2203).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2046 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-18 21:11:25 +00:00
Jean-Philippe Lang
e61916ea91 SubversionAdapter#entries performance improvement.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2045 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-18 18:36:47 +00:00
Jean-Philippe Lang
86504acb4c Vietnamese language updated (#2125).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2044 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-18 17:22:28 +00:00
Jean-Philippe Lang
3fdc273252 Do not query multiple times git for branch (#1435).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2043 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-17 17:27:08 +00:00
Jean-Philippe Lang
9882217847 Adds Plugin#requires_redmine method so that plugin compatibility can be checked against current Redmine version (#2162).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2042 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-16 20:00:20 +00:00
Jean-Philippe Lang
5362a85f2b Adds url and author_url plugin attributes (#2162).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2041 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-16 17:12:02 +00:00
Jean-Philippe Lang
f9ce4ff559 Adds a few Plugin tests.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2040 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-16 16:08:25 +00:00
Jean-Philippe Lang
fefc6e6bec Adds .find and .all Plugin class methods.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2039 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-16 15:38:37 +00:00
Jean-Philippe Lang
97252c26ee Adds plugin id attribute.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2038 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-16 15:22:48 +00:00
Jean-Philippe Lang
94b5bbcb5d Moves plugin list to its own administration menu item.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2037 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-16 11:58:41 +00:00
Jean-Philippe Lang
9c09fd20fb Changes version naming rule (#2162).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2036 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-16 11:49:37 +00:00
winterheart
79b1347ba5 Translation updates (#2189, #2193)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2035 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-15 08:35:17 +00:00
winterheart
0cef17ce44 Polish update, #2188
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2034 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-14 15:33:27 +00:00
winterheart
d1b1f5977a Translation updates (#2168, #2172, #2176, #2178)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2033 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-14 15:18:13 +00:00
winterheart
33274b8d48 Missed %s in label, thank Martin Bächtold for reporting (#2186)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2032 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-14 15:00:23 +00:00
Jean-Philippe Lang
7c1d8ac00b Fixes #2170: user display format in application settings broken by r2010.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2031 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-13 16:43:39 +00:00
Jean-Philippe Lang
243027e63a Fixes #2171: issue pdf export broken by r2006.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2030 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-13 16:39:50 +00:00
Eric Davis
9d810f0059 Changed the CSS clear on journals so they will wrap around the revisions. #2165
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2029 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-13 01:07:58 +00:00
winterheart
eaedf9ed52 update for ru
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2028 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-12 15:34:11 +00:00
winterheart
c894f74c5e Populating new strings for sk.yml
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2027 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-12 15:23:52 +00:00
winterheart
8d8315d8f6 New file for sk (#2126)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2026 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-12 15:22:57 +00:00
winterheart
7f63f9a931 Populating new strings for zh.yml
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2025 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-12 15:18:55 +00:00
winterheart
27af58ef1a update for zh (#2151)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2024 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-12 15:17:47 +00:00
winterheart
fb4bab748f update for pt-br (#2164)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2023 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-12 15:13:49 +00:00
Jean-Philippe Lang
d771847078 Pluggable admin menu (patch #2031 by Yuki Sonoda with slight changes).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2022 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 18:10:21 +00:00
Jean-Philippe Lang
3f4defe482 Hungarian language file updated.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2021 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 16:49:20 +00:00
Jean-Philippe Lang
737bbb3d3d Less agressive Redcloth lang attribute parsing (#2091).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2020 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 16:26:05 +00:00
Jean-Philippe Lang
7a05f8ed66 Adds permissions to let users edit and/or delete their messages (#854, patch by Markus Knittig with slight changes).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2019 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 15:07:55 +00:00
Jean-Philippe Lang
cbacc71dff Turn ftps and sftp proto into links (#1514).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2018 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 14:24:06 +00:00
Jean-Philippe Lang
ad97165f1b Changes ruby bang path to #!/usr/bin/env ruby (#1876).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2017 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 13:54:10 +00:00
Jean-Philippe Lang
8be1597ad0 Updated pt-br and zh-tw lang files.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2016 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 13:49:07 +00:00
Jean-Philippe Lang
1169ff05af Documents Wiki page anchors (#1647).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2015 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 13:37:10 +00:00
Jean-Philippe Lang
876a9b6ffb Fixed: Trac milestone links not correctly converted (#2052).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2014 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 13:32:22 +00:00
Jean-Philippe Lang
d545ca7360 Fixed: Trac migration of ticket:123 or [ticket:34] do not work (#2053).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2013 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 13:28:48 +00:00
Jean-Philippe Lang
1802fa9348 Fixed: Trac migration of ticket:123 or [ticket:34] do not work (#2053).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2012 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 13:28:13 +00:00
Jean-Philippe Lang
29bad1dc95 Trac importer improvements (patch #2050 by Karl Heinz Marbaise).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2011 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 13:22:05 +00:00
Jean-Philippe Lang
6a8be88ad6 Sort users by their display names so that user dropdown lists are sorted alphabetically (#2015).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2010 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 12:59:28 +00:00
Jean-Philippe Lang
e8d0c26e43 Eager-load users.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2009 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 12:50:11 +00:00
Jean-Philippe Lang
4ed95ffff6 Fixes a typo in en.yml.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2008 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-11 12:07:03 +00:00
Jean-Philippe Lang
6f68a36679 Eager-load users.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2007 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-10 19:09:00 +00:00
Jean-Philippe Lang
79c33bbc83 Maps repository users to Redmine users (#1383).
Users with same username or email are automatically mapped. Mapping can be manually adjusted in repository settings. Multiple usernames can be mapped to the same Redmine user.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2006 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-10 18:59:06 +00:00
Jean-Philippe Lang
f6b2be81b9 Include GLoc in hook listener base class (#2112).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2005 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-10 12:23:54 +00:00
Jean-Philippe Lang
486ecc6661 Fixed: non-ASCII subversion path can't be displayed (patch #1993 by Chaoqun Zou).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2004 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-10 11:33:04 +00:00
Jean-Philippe Lang
5166213fd3 Hide Redmine version in atom feeds and pdf properties (#794).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2003 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-09 20:39:49 +00:00
Jean-Philippe Lang
57a4ee318a Link to activity view when displaying dates.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2002 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-09 17:56:20 +00:00
Jean-Philippe Lang
d63746ab3e Fixes activity date param.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2001 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-09 17:53:30 +00:00
Jean-Philippe Lang
7619c286cc Changes ApplicationHelper#gravatar_for_mail to #avatar that takes a User or a String (less code in views).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2000 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-09 14:52:16 +00:00
Jean-Philippe Lang
6157d20ec0 Git adapter: use commit time instead of author time (#2108).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1999 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-09 12:07:35 +00:00
winterheart
858eba2f1c populating new string, updates for ru.yml and sv.yml (#2126)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1998 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-09 00:29:20 +00:00
winterheart
365d92ebf4 #2126, initial support of Slovak, thank to Stanislav Pach for translation
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1997 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-08 22:34:41 +00:00
Jean-Philippe Lang
11b9ceb054 git path reverted.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1996 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-08 17:15:18 +00:00
Jean-Philippe Lang
9352bb527b Tells git to output dates in ISO format.
Fixes: Git Adapter date parsing ignores timezone (#2149).

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1995 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-08 15:50:51 +00:00
Jean-Philippe Lang
47475acdaf Fixed Bazaar shared repository browsing (#2101, patch #1685 by Dmitry Shaposhnik).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1994 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-08 15:28:00 +00:00
Jean-Philippe Lang
9ae6e60c26 Fixes syntax highlighting broken by r1930 (#2143).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1993 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-08 15:18:02 +00:00
Jean-Philippe Lang
077723c90a Do not use @:skip_relative_url_root@ to generate urls in Mailer (#2122).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1992 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-08 13:25:45 +00:00
Eric Davis
81eee10d5b Removing the custom Redmine hook in routes in favor of Engine's hook.
* Plugins' routes.rb are now added automatically to Redmine's routing,
  including the ability to override Redmine's default routing.

  Thank you to Jean-Baptiste Barth for the suggestion.  #2142


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1991 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-08 00:12:43 +00:00
Jean-Philippe Lang
63c72fe87f Fixed: broken subject when submitting issue via email written in japanese (Patch #2059 by Go MAEDA).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1990 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 17:27:56 +00:00
Jean-Philippe Lang
006337fb0e Host setting should contain the path prefix (Redmine base URL) to properly generate links in emails that are sent offline (#2122).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1989 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 15:37:17 +00:00
Jean-Philippe Lang
4581baa5c0 Email address should be lowercased for gravatar (#2145).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1988 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 14:35:18 +00:00
Jean-Philippe Lang
203cf6333e French translation update.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1987 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 13:08:01 +00:00
winterheart
b7c1a5c0d5 Update for pl.yml, #1299
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1986 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 11:28:29 +00:00
winterheart
0ecca9d8f1 D'oh...
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1985 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 11:22:26 +00:00
winterheart
c58298835d refreshing vn.yml (#2125)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1984 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 11:20:25 +00:00
winterheart
42452a535f Intial support Vietnamese language (#2125), thanks to Kỳ Anh Huỳnh for work (now - really)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1983 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 11:12:12 +00:00
winterheart
d32b9b92cf Ooops, wrong.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1982 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 11:07:25 +00:00
winterheart
de31cd9ef6 Intial support Vietnamese language (#2125), thanks to Kỳ Anh Huỳnh for work
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1981 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 10:53:09 +00:00
winterheart
a9295a7740 #2127, #2129, #2130, #2135, translation updates. Thanks to all participants :)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1980 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-07 10:41:10 +00:00
Eric Davis
8b3a8ac1b4 Included Redmine::Hook::Helper to ActionController::Base so call_hook
is available in all controllers. #2111


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1979 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-06 05:37:29 +00:00
Eric Davis
b1cb9cd3bd Added :view_projects_form plugin hook
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1978 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-04 18:27:13 +00:00
winterheart
76d33e1fb7 #2121, pt-br update
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1977 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-11-01 16:42:49 +00:00
winterheart
0dc6a41832 update ru.yml
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1976 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-31 14:58:05 +00:00
winterheart
34b86628a0 Update zh-tw, #2116
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1975 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-31 14:49:33 +00:00
winterheart
66b9a76c7e Update pt-rb, #2105
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1974 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-31 14:48:07 +00:00
winterheart
bbc43e71ee Populating new string with rake gloc:update
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1973 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-31 14:38:09 +00:00
Eric Davis
ba20a67873 Added an option to turn user Gravatars on or off
* Option can be found in Administration > General, called
  "Use Gravatar user icons"
* Defaulting Gravatars to off
* Added a helper gravatar_for_mail to check the setting before rendering
  the Gravatar.

  #1776


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1972 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-31 00:41:28 +00:00
Eric Davis
048fa5bd77 Tighened up the gravator CSS in the issue div
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1971 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-31 00:19:48 +00:00
Eric Davis
3bc2a5cf2f Tweaking of the CSS for the gravatars. #1776
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1970 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-31 00:09:36 +00:00
Eric Davis
41dba2db86 Link the version name to VersionsController#show in the issue list.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1969 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 03:49:04 +00:00
Eric Davis
e85a9f8609 Fixed typo in an English string, 'View calender'
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1968 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 03:29:30 +00:00
Eric Davis
b84dd8ec83 Added gravatar image to the user's public account page
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1967 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 02:58:34 +00:00
Eric Davis
01fd8e685b Fixed a bug with using gravatar on a nil value.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1966 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 02:58:28 +00:00
Eric Davis
1a6595aa17 Reduced the size of the gravatar on the issue history
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1965 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 02:58:23 +00:00
Eric Davis
9373f429d0 styling tweaks for gravatars
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1964 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 02:58:16 +00:00
Eric Davis
b3442a7d39 styling tweaks for gravatars
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1963 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 02:58:10 +00:00
Eric Davis
ed314caf7d Gravatar support for issue detai, user grid, and activity stream
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1962 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-30 02:58:04 +00:00
winterheart
1399f3dd12 Update for ru.yml
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1961 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-28 23:31:14 +00:00
Eric Davis
7c99f8ad11 Added :view_timelog_edit_form_bottom hook to the timelog/edit form.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1960 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-28 20:29:38 +00:00
winterheart
67159c12c5 #2080, #2097, #2100 - ja, zh-tw, zh updates
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1959 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-28 16:08:19 +00:00
Jean-Philippe Lang
0f1787ea0d Fixed: Inline images don't work if file name has upper case letters or if image is in BMP format (#2102).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1958 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-28 10:43:34 +00:00
Jean-Philippe Lang
6cd4f0c07e Makes GLoc language global.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1957 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-27 12:34:01 +00:00
Jean-Philippe Lang
d143019dbb Adds back textile acronyms support (#2077).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1956 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-27 11:50:23 +00:00
Jean-Philippe Lang
a3b9a5aa5f Makes wiki text formatter pluggable.
Original patch #2025 by Yuki Sonoda slightly edited.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1955 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-27 11:08:29 +00:00
Jean-Philippe Lang
9b624fd1d6 Slight change to english string (#2088).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1954 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-26 15:17:26 +00:00
Jean-Philippe Lang
8236563d6b Check that git changeset is not in the database before creating it (#1419).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1953 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-25 10:23:29 +00:00
Jean-Philippe Lang
5f9f6ea2e1 Adds #delete_menu_item to the plugin API (#2087).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1952 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-25 09:55:31 +00:00
Jean-Philippe Lang
738fc579f0 Renames template ruby files to erb.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1951 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-25 09:35:51 +00:00
Eric Davis
0316fde06b Added the board's description below the board's name.
Thanks to Go MAEDA for the patch.  #2079


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1950 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-25 04:46:21 +00:00
Eric Davis
bcde2f4dce Renamed the .rb files in the plugin_generator to end in .erb. The .rb was
causing rdoc to try to document them and fail.

* Updated the generator's manifest to use the new files
* Renamed template README to README.rdoc

  #2011


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1949 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-25 04:37:31 +00:00
Eric Davis
48ae6f38e1 Added hook :view_repositories_show_contextual to allow adding items to the
repository's contextual menu.

  #2073


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1948 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-25 04:21:57 +00:00
Jean-Philippe Lang
16eda4c5c9 Adds the ability to search for a project name or identifier on the administration projects list.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1947 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-24 17:12:39 +00:00
Jean-Philippe Lang
b4101c8b65 Adds functional test for user search.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1946 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-24 17:01:42 +00:00
Jean-Philippe Lang
d967507dcb Adds the ability to search for a user on the administration users list.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1945 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-24 16:59:15 +00:00
Jean-Philippe Lang
d1b5bc1e82 AuthSource list: display associated users count and disable 'Delete' buton if any (#2041).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1944 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-24 15:39:40 +00:00
Jean-Philippe Lang
6c54b0ba3b Makes permission screens localized (#2070).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1943 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-24 15:24:35 +00:00
winterheart
bdbc7b337f #1928 it.yml update
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1942 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-23 15:24:16 +00:00
Jean-Philippe Lang
ff449b197f Fixed: textile footnotes no longer work after r1113 (#974).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1941 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-18 11:25:27 +00:00
Jean-Philippe Lang
a0c29d8f99 link_to project homepage instead of auto_link (#1937).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1940 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-18 10:42:29 +00:00
Jean-Philippe Lang
58fbf5e66f Show the most recent file when displaying an inline image.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1939 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-18 10:18:21 +00:00
Jean-Philippe Lang
ccbe48d779 Adds 'Delete wiki pages attachments' permission.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1938 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-18 10:07:49 +00:00
winterheart
64e67f754d #2043, #2044, #2046, translation updates
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1937 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-18 10:03:50 +00:00
Eric Davis
6810972762 Added a plugin hook :routes that plugins can use to add and even override routes
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1936 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-17 23:30:37 +00:00
winterheart
e160a3eec1 Update for ru.yml
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1935 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-16 20:51:27 +00:00
winterheart
f16aae74dc #2036 update for hu.yml
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1934 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-16 20:50:50 +00:00
Jean-Philippe Lang
bc77cc2c5c Makes email address case-insensitive in MailHandler (#2032).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1933 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-16 19:13:43 +00:00
Nicolas Chuche
a4b07a36ed add plain text option for mail #2029
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1932 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-15 23:50:33 +00:00
Nicolas Chuche
1894bef48a bugfix to two failed tests
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1931 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-15 22:30:57 +00:00
Jean-Philippe Lang
2ed9aa13f3 Remove pre tag attributes.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1930 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-12 19:13:36 +00:00
winterheart
52e422da61 Patch #2005, nl.yml update
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1929 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-11 11:32:30 +00:00
winterheart
8b0016d71b Patch #2001, update for Polish language
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1928 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-07 17:41:16 +00:00
winterheart
df761e01fa #1992 update pt.yml, thanks to Pedro Araújo
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1927 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-06 15:00:56 +00:00
winterheart
07962e2840 Patch #1987, ca.yml update, thanks to Joan Duran for file
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1926 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-05 20:40:25 +00:00
winterheart
7fe7677cde #1988, update for ko.yml
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1925 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-05 19:30:58 +00:00
Jean-Philippe Lang
c4419e268f Escape image filename regexp (#1971).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1924 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-04 17:38:31 +00:00
Eric Davis
cf1ad65cd2 Added tests to cover IssueStatus.destroy and IssueStatus.check_integrity
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1923 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-02 03:23:35 +00:00
Eric Davis
193ed689fb Fixed a failing assertion in test_post_edit_with_attachment_only that would
occur when running the full test suite but not the functional test suite.


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1922 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-10-02 02:40:29 +00:00
Eric Davis
f2f54a711d Adds :view_layouts_base_body_bottom hook
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1921 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-30 05:18:50 +00:00
Eric Davis
0092a54e3b Slight non-code change to test git sync
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1920 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-30 00:02:46 +00:00
Eric Davis
1ffa468240 Reverting slight non-code change
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1919 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-29 23:56:35 +00:00
Eric Davis
ae0ed7fd05 Slight non-code change
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1918 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-29 23:55:11 +00:00
Jean-Philippe Lang
b0e62e37ae Fixes Workflow.count_by_tracker_and_role.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1917 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 13:10:00 +00:00
Jean-Philippe Lang
3544d6398a Slight changes to the workflow setup screen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1916 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 12:36:30 +00:00
Jean-Philippe Lang
5083e92772 Fixes workflow setup link on trackers list (follows r1914).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1915 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 12:20:47 +00:00
Jean-Philippe Lang
a37af7a226 Adds a workflow overview screen.
Workflow setup moved to a dedicated controller.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1914 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 12:03:17 +00:00
Jean-Philippe Lang
85711f1d54 Fixed: Status list on bulk edit form does not follow normal sequence (#1956).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1913 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 08:41:17 +00:00
Jean-Philippe Lang
050d0d046a Wrap 'Assigned to' column on the issue list (#1960).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1912 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 08:19:25 +00:00
Jean-Philippe Lang
925ef8f4f0 Fixed: the default status is lost when reordering issue statuses (#1955).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1911 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 08:05:55 +00:00
Jean-Philippe Lang
ad06bec6b6 Fixed: Latest news appear on the homepage for projects with the News module disabled (#1941).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1910 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-28 07:54:41 +00:00
winterheart
433f2a043e Fixed #1961, pt-br update
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1909 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-27 19:06:48 +00:00
Jean-Philippe Lang
394fc9c109 Fixed: cross-project issue list should not show issues of projects for which the issue tracking module was disabled.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1907 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-25 18:51:03 +00:00
Jean-Philippe Lang
21979cf68a Fixes back_url in login filter (#1900).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1905 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-24 17:33:02 +00:00
Jean-Philippe Lang
0177f732a2 Reverts r1903.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1904 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-24 17:32:49 +00:00
Jean-Philippe Lang
a3cf5dcded Fixes back_url in login filter (#1900).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1903 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-24 17:30:36 +00:00
winterheart
8bc89b6e73 Patch #1938, update for nl.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1902 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-24 14:45:20 +00:00
Jean-Philippe Lang
2e7e26fbb4 Fixes html escaping.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1901 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-23 17:03:51 +00:00
Jean-Philippe Lang
9131cdf6b9 Truncate comments on changeset list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1900 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-22 19:50:10 +00:00
winterheart
fbf2646426 #1921, pt translation
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1897 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-22 14:49:18 +00:00
Jean-Philippe Lang
edf6757a75 Typo in migration 97 name (#1929).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1896 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 20:38:36 +00:00
Jean-Philippe Lang
8cb75be0db Switch order of current and previous revisions in side-by-side diff (#1903).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1895 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 18:45:30 +00:00
Jean-Philippe Lang
b09a18972d Strip LDAP attribute names before saving (#1890).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1894 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 13:28:12 +00:00
Jean-Philippe Lang
8a356baf3e Unescape back_url param before calling redirect_to.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1893 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 12:45:22 +00:00
winterheart
e1c4659752 #1928, update for Italian language
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1892 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 12:32:16 +00:00
winterheart
72c9884dfc de.yml from #1745, thank to Sven Schuchmann and Thomas Löber for contribution
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1891 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 12:31:34 +00:00
Jean-Philippe Lang
7afdb01f00 Fixed: login filter providing incorrect back_url for Redmine installed in sub-directory (#1900).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1890 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 12:07:44 +00:00
Jean-Philippe Lang
1d542a5113 Fixes VersionTest class.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1889 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 08:54:50 +00:00
Jean-Philippe Lang
199428804f Fixed: invalid effective date (eg. 99999-01-01) causes an error on version edition screen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1888 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-21 08:54:02 +00:00
Jean-Philippe Lang
6854827f1a Fixed: Roadmap crashes when a version has a due date > 2037.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1887 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-20 14:07:52 +00:00
winterheart
5452fd2f5a #1925, patch for lt.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1885 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 16:33:08 +00:00
winterheart
701e00d865 #1924, update for da.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1884 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 16:30:39 +00:00
winterheart
4e36bd2ce1 #1923, updated zh.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1883 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 16:26:19 +00:00
winterheart
124ea898d5 patch #1922, update for nl.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1882 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 16:23:04 +00:00
winterheart
07b69fd7fc fixed #1920, patch for Hungarian language
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1881 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 16:20:45 +00:00
winterheart
952ff4184e #1918, translation for zh-tw
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1880 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 16:17:35 +00:00
winterheart
5c449f844e update of ru.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1879 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 16:15:49 +00:00
Jean-Philippe Lang
16e09bfd77 Adds watch/unwatch functionality at forum topic level (#1912).
Users who create/reply a topic are automatically added as watchers but are now able to unwatch the topic.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1878 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-19 15:32:52 +00:00
Jean-Philippe Lang
9e7bce6a94 Make --command option usable on Windows.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1877 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 19:47:36 +00:00
Jean-Philippe Lang
710ac5344d Slight change on git repository creation command.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1876 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 19:38:20 +00:00
Jean-Philippe Lang
36aeeb99d9 reposman: change #log arguments.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1875 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 19:18:31 +00:00
Jean-Philippe Lang
713ce06e40 Fixed custom query sidebar links broken by r1797 (#1899).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1873 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 17:23:08 +00:00
Jean-Philippe Lang
fcbd2b5228 Removes unused image references in stylesheets (#1914).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1872 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 17:18:05 +00:00
Jean-Philippe Lang
14b4afeec9 Fixed: http links containing parentheses fail to reder correctly (#1591). Patch by Paul Rivier.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1871 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 16:48:04 +00:00
Jean-Philippe Lang
3520961eae Render the commit changes list as a tree (#1896).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1870 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 16:39:23 +00:00
winterheart
0961cdab31 Patch #1909, updates for ru.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1869 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-17 15:31:35 +00:00
Jean-Philippe Lang
a987649b1a mailhandler: fixes exit status and adds an explicit message if response code is 403.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1868 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-16 21:56:02 +00:00
Jean-Philippe Lang
9afaf26d66 Use RDoc.usage
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1867 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-16 21:54:53 +00:00
Nicolas Chuche
a07a6d4aa4 * reposman can create git repository with "--scm git" option
* light refactoring

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1866 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-15 19:37:43 +00:00
winterheart
25ed19cb35 Catalan translation (#1822), thanks to Joan Duran for contribuition. Some strings has wrong quoting, I fixed that.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1865 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-15 16:07:30 +00:00
winterheart
1f862dbadb Minor typo, fixed #1897, thank Denis Tomashenko for reporting.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1864 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-15 15:22:53 +00:00
winterheart
3ef92341fd fixed #1905, patch for Hungarian language
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1863 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-15 15:19:51 +00:00
winterheart
225b6f4dc9 #1907, translation for zh
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1862 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-15 15:16:53 +00:00
winterheart
094520ab20 #1902, translation for zh-tw
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1861 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-15 15:14:34 +00:00
Nicolas Chuche
90dc93b81c bugfix
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1860 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-14 19:03:46 +00:00
winterheart
323a26030b sorting new string...
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1830 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-14 13:08:02 +00:00
winterheart
653d2aacbb fixed #1216, thank Antti Perkiömäki for reporting
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1829 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-14 12:59:12 +00:00
Jean-Philippe Lang
f6b05ea3fb Functional tests fail when run on their own (#1895).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1828 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-14 12:41:24 +00:00
Jean-Philippe Lang
3041041a62 Adds :view_wiki_edits permission to default roles.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1827 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-14 10:54:19 +00:00
winterheart
691b09fd72 Fixed #1810, one string left
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1826 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 19:43:27 +00:00
winterheart
f30a369d35 fixed #1839, #1814, #1747 and #1698
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1825 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 19:12:50 +00:00
winterheart
487ba400fc fixed #1597, thank to Alexandre da Silva for patience :)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1824 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 19:05:14 +00:00
winterheart
2e0cd9f196 oops, we have newest #1849, sorry
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1823 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 18:55:54 +00:00
winterheart
59c961425e fixed #1832
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1822 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 18:52:27 +00:00
Jean-Philippe Lang
570d7e494e Fixed: unable to revert to a previous wiki page version.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1821 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 18:45:56 +00:00
Jean-Philippe Lang
1f1fd9e034 Expand RAILS_ROOT path on startup (#1892).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1820 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 18:32:37 +00:00
winterheart
35bb9307dc fixed #1818, some strings untranslated
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1819 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 18:12:19 +00:00
winterheart
47679629f4 patch #1639, some new strings untranslated
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1818 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 17:54:55 +00:00
Jean-Philippe Lang
06f4b371ee Adds Turkish translation by Ismail Sezen (#1866).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1817 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 17:25:01 +00:00
winterheart
c3040104ff fixed #1632, patch from Станислав Герман-Евтушенко
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1816 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 17:06:37 +00:00
Jean-Philippe Lang
455abea320 Adds a permission 'view wiki edits' so that wiki history can be hidden to certain users (#1154).
A migration automatically adds this permission to roles that were allowed to view wiki pages.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1815 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 16:45:01 +00:00
Jean-Philippe Lang
cc643ce932 Merged nbc branch @ r1812 (commit access permission and reposman improvements).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1814 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 16:31:11 +00:00
winterheart
6ef6459630 fixed #1635, merged changes to trunk, sorting all strings
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1813 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 16:30:03 +00:00
Jean-Philippe Lang
827e14eafe Mailer compatibility with Rails 2.1.1.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1811 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 15:33:46 +00:00
Jean-Philippe Lang
8fac9233de Engines compatibility with Rails 2.1.1 (#1886).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1810 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 15:33:12 +00:00
Jean-Philippe Lang
7385722441 Removes double quotes in commit link syntax (#1872).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1803 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-13 09:45:07 +00:00
Jean-Philippe Lang
b73141a153 Adds links to changesets atom feed on repository browser (#1873).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1802 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-12 17:17:25 +00:00
Jean-Philippe Lang
8d6b32645c Template error when user's timezone isn't set and UTC timestamps are used (#1889).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1801 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-11 17:45:21 +00:00
Jean-Philippe Lang
a592d6c40d Renames bundled RedCloth to RedCloth3 to avoid RedCloth 4 to be loaded instead (#1754).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1800 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-11 17:19:26 +00:00
Jean-Philippe Lang
fb151463eb Changes versions retrieval on gantt chart.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1799 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-11 17:08:00 +00:00
Jean-Philippe Lang
586f4e3831 Adds support for free ticket filtering and custom queries on Calendar.
ProjectsController#calendar moved to IssuesController.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1798 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-11 17:03:26 +00:00
Jean-Philippe Lang
2986afc05e Adds support for free ticket filtering and custom queries on Gantt chart.
ProjectsController#gantt moved to IssuesController.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1797 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-10 18:26:13 +00:00
Eric Davis
a8e3ddf382 Added context fields to the :view_projects_settings_members_table hooks
* :view_projects_settings_members_table_header now has :project
* :view_projects_settings_members_table_row now has :project
* :view_projects_settings_members_table_row has a fixed :member field


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1796 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-10 01:49:51 +00:00
Eric Davis
de7d367820 Reverting commit r1748 again. r1786 pulled in in again
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1795 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-10 00:14:38 +00:00
Jean-Philippe Lang
f7acdd1afd Merged hooks branch @ r1785 into trunk.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1786 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-05 10:31:06 +00:00
Jean-Philippe Lang
4b9df2eac7 Fixes Repository#clear_changesets.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1783 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-09-04 19:35:08 +00:00
Jean-Philippe Lang
696d21f8c8 Adds cross-project time reports support (#994).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1778 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-31 16:34:54 +00:00
Jean-Philippe Lang
dbad26c87d Adds an option to generate sequential project identifiers.
Disabled by default, it can be enabled on the 'Projects' tab in application settings.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1777 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-31 12:59:57 +00:00
Nicolas Chuche
25b4139028 bug in read only access handling
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1776 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-31 12:11:49 +00:00
Jean-Philippe Lang
ed349ca942 Sligth changes to issue comments quoting links.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1773 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-28 19:04:04 +00:00
Jean-Philippe Lang
bfd0fb067a Adds posts quoting functionality (#1825).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1772 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-28 18:56:47 +00:00
Eric Davis
8f3a04ce69 Reverting commit r1748. Some environments are not allowing the cached file to
write to public, causing all JavaScript to fail.

Javascripts are now cached into a single file for downloads in production mode.

  #1186


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1771 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-28 16:32:14 +00:00
Jean-Philippe Lang
6ad989f828 Adds checkboxes toggle links on permissions report.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1770 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-26 16:05:02 +00:00
Jean-Philippe Lang
5c6bee7f85 Simplified Chinese lang file update (#1809 by Chaoqun Zou).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1769 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-26 15:19:28 +00:00
Jean-Philippe Lang
d611339baa Fixes error with CVS+Postgresql and non-UTF8 commit logs (#917, #1659).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1768 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-26 12:28:15 +00:00
Jean-Philippe Lang
0cf15476a3 Adds support for commit logs reencoding to UTF-8 before insertion in the database (#834, #917, #1663).
Source encoding of commit logs can be selected in Application settings -> Repositories.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1767 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-26 12:13:15 +00:00
Jean-Philippe Lang
09eba46ec1 Fixed: document listing shows on "my page" when viewing documents is disabled for the role (#1772).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1766 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-26 11:08:45 +00:00
Jean-Philippe Lang
ea627ca98d One-click bulk edition using the issue list context menu within the same project (#1770).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1765 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-26 10:34:26 +00:00
Jean-Philippe Lang
999d47f986 Use example.net as domain in default configuration (#1762).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1764 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 16:35:20 +00:00
Jean-Philippe Lang
66a079f430 Changes help message about project identifiers (#1478).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1763 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 16:14:07 +00:00
Jean-Philippe Lang
e395d3e46d Fixes context menu with Opera (#1655).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1762 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 15:24:23 +00:00
Jean-Philippe Lang
954bddbadf Make the issue list context menu work under Mac OSX Leopard (#1485). Tested with FF3.0.1 and Safari 3.0.4 under OSX 10.5.2.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1761 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 15:09:31 +00:00
Jean-Philippe Lang
2042e3bbd9 Dots allowed in custom field name (#1723).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1760 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 14:37:44 +00:00
Jean-Philippe Lang
d93f96765b Adds support for file viewing with Darcs 2.0+ (patch #1799 by Ralph Lange slightly edited).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1759 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 14:33:30 +00:00
Jean-Philippe Lang
e339d0bcc0 Fixed: Issue updated_on is not updated when a user adds a note with no edit privilege.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1758 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 12:51:29 +00:00
Jean-Philippe Lang
dbf4438dda More detailed error message in log when scm command fails (#1682).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1757 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 12:31:53 +00:00
Jean-Philippe Lang
0d55652552 Fixes method name in AbstractAdapter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1756 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 12:27:15 +00:00
Jean-Philippe Lang
6fc62d393c Fixed: invalid SQL query on User#destroy (#1781).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1755 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 11:55:40 +00:00
Jean-Philippe Lang
5ef0af6710 Fixed: Estimated time in issue's journal should be rounded to two decimals (#1793).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1754 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 11:43:48 +00:00
Jean-Philippe Lang
116091a1d2 Fixes platform determination under JRuby (#1804).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1753 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-25 11:01:37 +00:00
Eric Davis
2f3f2d8b12 Added the "Status:" keyword to the MailHandler for setting and changing an Issue status via email.
#1669


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1751 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-20 06:21:06 +00:00
Eric Davis
6db8fa8ef7 Messages on a Board can now be sorted by the number of replies.
#1761


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1750 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-20 06:14:44 +00:00
Eric Davis
af6b01f55d Hiding the View Differences button when a wiki page's history only has one version.
Patch contributed by Chaoqun Zou (#1743)


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1749 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-20 05:09:13 +00:00
Eric Davis
a899904f63 Javascripts are now cached into a single file for downloads in production mode.
Thanks to Philippe Lafoucrière for the patch.  (#1186)


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1748 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-20 04:26:46 +00:00
Jean-Philippe Lang
53078ca949 No warning about rcov each time a rake task is ran.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1747 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-15 18:44:46 +00:00
Eric Davis
910988133d Extracted rcov options and removed gems from the rcov report.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1745 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-13 04:20:23 +00:00
Eric Davis
fab5c1fdef Added rake tasks to generate rcov code coverage reports. rake -T test:coverage to see them all
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1744 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-13 04:20:16 +00:00
Eric Davis
ca2449d9cf Added missing documentation for setting up the Darcs test repository.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1743 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-13 03:54:54 +00:00
Jean-Philippe Lang
41d44c5285 Adds user count in status drop down on admin user list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1735 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-11 21:10:24 +00:00
Jean-Philippe Lang
d47400aa8d Adds Lock/Unlock/Activate link on user edit screen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1734 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-11 21:02:36 +00:00
Jean-Philippe Lang
988f8d65fa Adds 'Edit' link on account/show for admin users.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1733 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-11 20:55:17 +00:00
Eric Davis
a3e729a263 Added doc/README_FOR_APP so RDoc can be built. (#1769)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1732 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-11 20:49:52 +00:00
Jean-Philippe Lang
237a3f52a2 Fixes custom fields display order at several places (#1768).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1731 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-11 18:24:39 +00:00
Jean-Philippe Lang
1631019026 Allow same name for custom fields on different object types.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1730 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-11 18:09:54 +00:00
Jean-Philippe Lang
1650920339 Adds links to forum messages using message#id syntax (#1756).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1729 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-10 22:18:23 +00:00
Jean-Philippe Lang
ab4873b83d Quote ids for attachment association since Trac's attachment.id is varchar (#1759).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1728 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-10 21:35:03 +00:00
Jean-Philippe Lang
2fdf4426cd Moves @layout 'base'@ to ApplicationController.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1727 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-10 15:22:54 +00:00
Jean-Philippe Lang
361138e16d Slight change to engines to let plugins override views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1723 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-07 19:59:02 +00:00
Jean-Philippe Lang
2e4e9b88d2 Fixes rdm-mailhandler SSL support (#1724).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1715 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-03 11:07:16 +00:00
Jean-Philippe Lang
91a5fa32d7 Fixes non-matching html tag (#1734).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1714 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-03 09:30:56 +00:00
Jean-Philippe Lang
d1a504f768 Fixed: logtime entry duplicated when edited from parent project (#1728).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1713 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-03 09:27:27 +00:00
Jean-Philippe Lang
a332e0a4fe Adds permissions for viewing the watcher list and adding new watchers on the issue detail view (#398).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1712 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-08-03 09:14:43 +00:00
Jean-Philippe Lang
6034067d86 Fixed: activity atom feed broken by r1701 (#1703).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1711 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-30 18:33:35 +00:00
Jean-Philippe Lang
3197814c62 Fixed: RedCloth#block_markdown_rule freezes when parsing many hyphen marks (#1704).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1710 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-30 18:28:01 +00:00
Jean-Philippe Lang
b91bdf8798 Fixed: tokens not escaped in highlight_tokens regexp (#1702).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1709 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-28 21:11:49 +00:00
Jean-Philippe Lang
b26e4932a2 Smaller font in context menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1708 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-28 18:01:05 +00:00
Jean-Philippe Lang
c3f9575eaf Adds category to the issue context menu (#1684).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1707 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-28 18:00:30 +00:00
Jean-Philippe Lang
198a8c602d Adds support for wiki links with anchor (#1647).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1706 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-28 17:20:31 +00:00
Jean-Philippe Lang
2dbc3d2943 Adds Trac-Like anchors on wiki headings (#1647).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1705 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-28 17:08:16 +00:00
Jean-Philippe Lang
b20281f151 Follows r1703.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1704 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-27 19:18:35 +00:00
Jean-Philippe Lang
3a4855d070 Activity provider example in sample plugin.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1703 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-27 19:10:56 +00:00
Jean-Philippe Lang
d05bcda2ba Adds #activity_provider shortcut method to the plugin API.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1702 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-27 18:38:31 +00:00
Jean-Philippe Lang
a774c5c48b Activity refactoring.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1701 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-27 17:54:09 +00:00
Jean-Philippe Lang
1721376542 Fixes tests (r1693).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1700 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-27 10:23:07 +00:00
Jean-Philippe Lang
ec7d135930 Adds child_pages macro for wiki pages (#528).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1699 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-26 12:54:54 +00:00
Jean-Philippe Lang
60d066f943 Wiki page hierarchy (#528). Parent page can be assigned on Rename screen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1698 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-26 11:46:24 +00:00
Jean-Philippe Lang
b68fd4c04b When moving an issue to another project, reassign it to the category with same name if any (#1653).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1697 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-26 09:27:07 +00:00
Jean-Philippe Lang
6ddea3396b Adds estimated hours to issue filters (#1678).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1696 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-26 09:05:26 +00:00
Jean-Philippe Lang
9f92554319 Redirect user to the previous page after logging in (#1679).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1695 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-26 08:46:33 +00:00
Jean-Philippe Lang
5564dfbbd5 TOC rendered as an unordered list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1693 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 19:40:47 +00:00
Jean-Philippe Lang
a17b62b455 Fixes hard-coded table names in queries.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1692 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 19:07:43 +00:00
Jean-Philippe Lang
d84d38983a Adds boolean and list custom fields for time entries as criteria on timelog report.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1691 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 19:06:13 +00:00
Jean-Philippe Lang
f54c2d812d Adds custom fields to the time entries csv export.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1690 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 19:02:40 +00:00
Jean-Philippe Lang
898fac293b Adds custom fields on time entries (#772).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1689 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 18:52:00 +00:00
Jean-Philippe Lang
590a829a06 Removed unused exception definition (r1678).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1688 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 18:24:40 +00:00
Jean-Philippe Lang
a9932e3dbd Adds mailto link on the user administration list (#1670).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1687 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 17:59:45 +00:00
Jean-Philippe Lang
9b579de9e2 Appends the filename to the attachment url so that clients that ignore content-disposition http header get the real filename (#1649).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1686 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 17:55:19 +00:00
Jean-Philippe Lang
8a7bfc72b2 Move VersionsController#download to AttachmentsController.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1685 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-22 17:20:02 +00:00
Jean-Philippe Lang
aaca2c50e5 Fixed: 'search titles only' box ignored after one search is done on titles only.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1684 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-21 19:19:06 +00:00
Jean-Philippe Lang
9d3dfea1ac Adds username to the password reminder email (#1668).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1683 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-21 19:13:46 +00:00
Jean-Philippe Lang
c39161a6fc Fixed: searchable model can't be loaded if table is not yet created (#1421).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1682 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-20 17:31:11 +00:00
Jean-Philippe Lang
be2b8a62f4 Search engine: display total results count (#906) and count by result type.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1681 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-20 17:26:07 +00:00
Jean-Philippe Lang
83baccb71a Strikethru closed issue links (#1127).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1680 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-20 09:50:33 +00:00
Jean-Philippe Lang
1ddd9bb55b Fixed: dependency on ruby 1.8.7 introduced in r1660 (#1643).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1679 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-20 09:25:30 +00:00
Jean-Philippe Lang
eb1d969237 Improved on-the-fly account creation. If some attributes are missing (eg. not present in the LDAP) or are invalid, the registration form is displayed so that the user is able to fill or fix these attributes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1678 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-19 10:47:19 +00:00
Jean-Philippe Lang
93201e7386 Fixed: Wiki Linking Fails on News Item Preview (#1661).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1677 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-19 07:29:05 +00:00
Jean-Philippe Lang
324495643b Small fix to gloc error messages translation.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1676 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-19 07:19:55 +00:00
Jean-Philippe Lang
1701e0bd79 Fixed: default configuration can not be loaded for :it, :pt and :ro languages (#1660).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1675 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-17 16:27:29 +00:00
Jean-Philippe Lang
795220a1e6 Adds links to the user page on various views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1674 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-16 19:33:15 +00:00
Jean-Philippe Lang
aef25a5e32 Fixes r1672.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1673 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-16 19:22:09 +00:00
Jean-Philippe Lang
83385cbca8 Adds timelog link to the issue context menu (#1645).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1672 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-16 19:10:29 +00:00
Jean-Philippe Lang
7c6f191cf5 Fixed: Context menu overwritten by calendar on My Page (#1644).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1671 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-16 18:48:50 +00:00
Jean-Philippe Lang
025581bb28 Fixes boolean custom fields tags (broken by r1592) (#1640).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1668 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-14 17:29:06 +00:00
Jean-Philippe Lang
6d3c0dab01 Javascript fix (#1636).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1667 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-14 15:46:02 +00:00
Jean-Philippe Lang
fc07ba2a99 Clear changesets and changes with raw sql when deleting a repository (#1627).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1666 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-13 21:55:13 +00:00
Jean-Philippe Lang
0eba42423a Set order on wiki pages association.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1665 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-13 21:44:38 +00:00
Jean-Philippe Lang
9ba4075c88 Fixes search tests for Postgresql.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1664 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-13 21:01:38 +00:00
Jean-Philippe Lang
937cee7269 Prevent blank menu caption.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1663 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-13 13:25:37 +00:00
Jean-Philippe Lang
ad497bdcba Admin and Help links at the end of top menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1661 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-13 12:25:01 +00:00
Jean-Philippe Lang
7b8a4fc28b Menu mapper: add support for :before, :after and :last options to #push method and add #delete method.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1660 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-13 12:12:58 +00:00
Jean-Philippe Lang
c4eef6314e Menu item caption can be a Proc.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1659 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-13 11:02:42 +00:00
Jean-Philippe Lang
591407c5c8 Adds auto links tests.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1658 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-12 11:12:33 +00:00
Jean-Philippe Lang
4e7336dac9 Fixes engines assets mirroring.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1657 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-12 11:04:41 +00:00
Jean-Philippe Lang
a01a562261 Fixed: Plugin's setting page is broken after upgrading to rails 2.1.0 (#1620).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1656 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-12 10:31:41 +00:00
Jean-Philippe Lang
0b1343834d Translations updates.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1655 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-12 10:28:09 +00:00
Jean-Philippe Lang
c28cbd5790 Adds engines 2.1.0 plugin.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1654 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-12 10:17:14 +00:00
Jean-Philippe Lang
b5444b5fcd Fixed: no :author method error on projects atom feed (#1623).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1653 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-12 09:42:18 +00:00
Jean-Philippe Lang
622b6121f4 Fixes nil error when svn binary version is unknown (#1607).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1652 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-12 09:06:19 +00:00
Jean-Philippe Lang
9ff53f97ee Do not use partial in PDF templates (not supported when using rfpdf with Rails 2.1) (#1619).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1651 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-10 16:23:42 +00:00
Jean-Philippe Lang
d7eb689c74 Fixed: trailing period should not be included in redmine links of type class:id (#1612).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1650 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-10 13:36:28 +00:00
Jean-Philippe Lang
be4cc2f99e Fixed: search engine may reveal private projects (#1613).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1649 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-10 12:31:49 +00:00
Jean-Philippe Lang
de3d5a88e4 Fixes links to entries on the revision view (Rails 2.1 compatibility) (#1600).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1648 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-09 17:25:19 +00:00
Jean-Philippe Lang
bb76561ca6 Fixes Gantt chart with ruby 1.8.7 (#1606).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1647 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-09 17:16:37 +00:00
Jean-Philippe Lang
40efaae6d5 Mail handler: more control over issue attributes (#1110).
Tracker, category and priority attributes can be specified in command line arguments and/or individually specified as overridable by email body keywords.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1643 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 16:26:25 +00:00
Jean-Philippe Lang
bfba84d526 Better naming of activity feed if only one kind of event is displayed (#1323).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1642 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 13:57:10 +00:00
Jean-Philippe Lang
d4f55a86fd Adds project name to issues feed title (#1323).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1641 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 13:47:59 +00:00
Jean-Philippe Lang
8c6c3eab5c Fixes "source:" links URLs (r1617).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1640 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 12:43:51 +00:00
Jean-Philippe Lang
bc9a8494d2 Merged CHANGELOG from 0.7 stable.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1639 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-06 12:24:14 +00:00
Jean-Philippe Lang
29fb8db936 Adds MercurialAdapter.client_version and prevent @hg --version@ to be called on each request.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1628 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-05 09:39:00 +00:00
Jean-Philippe Lang
12fbd06c02 Display svn properties in the browser, svn >= 1.5.0 only (#1581).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1627 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-05 08:59:04 +00:00
Jean-Philippe Lang
1e6b8a482a Removes calls to TimeZone#adjust (#1584).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1626 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-05 07:39:07 +00:00
Jean-Philippe Lang
fc42dd2cef Email delivery configuration moved to an unversioned YAML file (config/email.yml, see the sample file) (#1412).
Email delivery is disabled. It's automatically turned on when configuration is found.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1625 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-04 18:55:45 +00:00
Jean-Philippe Lang
5d0b53544c Updated INSTALL doc.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1624 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-04 18:03:43 +00:00
Jean-Philippe Lang
7cdd88a6ce Merged Rails 2.1 compatibility branch.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1623 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-04 17:58:14 +00:00
Jean-Philippe Lang
22558f7709 Fixes test broken by r1610.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1616 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-03 16:22:51 +00:00
Jean-Philippe Lang
9703f576d9 Escapes HTML tags.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1612 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-07-02 17:27:16 +00:00
Jean-Philippe Lang
be57c20cd8 Fixes quick jump to a revision.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1611 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-30 21:52:29 +00:00
Jean-Philippe Lang
72076d391e Fixed: issues always created with default tracker (#1553).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1610 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-30 17:57:53 +00:00
Jean-Philippe Lang
87a16f395a Fixes relative paths to images in wiki_syntax.html (#1218).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1609 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-30 17:35:40 +00:00
Jean-Philippe Lang
ee608f24f4 Fixed: Comment too long message when updating issue (#1550).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1608 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-30 17:31:50 +00:00
Jean-Philippe Lang
b29b39290a Redirects back after clicking watch/unwatch links without javascript (#1337).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1607 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 19:56:20 +00:00
Jean-Philippe Lang
0f5a34b7ab Removes no longer needed helper method (r1605).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1606 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 19:51:14 +00:00
Jean-Philippe Lang
47064c02f1 Makes issue update link work without javascript (#1337).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1605 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 19:50:07 +00:00
Jean-Philippe Lang
5d6e9494ad Translations updates:
* Traditional Chinese (ChunChang Luo)
* Finnish (Jani Tiainen)
* Lithuanian (Sergej Jegorov)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1604 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 12:23:07 +00:00
Jean-Philippe Lang
32fa1a4e90 Do not silently ignore timelog validation failure on issue edit.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1603 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 12:16:58 +00:00
Jean-Philippe Lang
1424b0f215 Addq "please select" to activity select box if no activity is set as default (#937).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1602 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 12:01:20 +00:00
Jean-Philippe Lang
94cf4f258f Wider SVG graphs in repository stats.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1601 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 11:13:10 +00:00
Jean-Philippe Lang
a0f707e54b Fixed: Entourage (and some old client) fails to correctly render notification styles (#1425).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1600 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 09:50:42 +00:00
Jean-Philippe Lang
00593f2f34 Reduces memory usage when importing large git repositories (#1482).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1599 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 09:41:42 +00:00
Jean-Philippe Lang
a40add57de Adds HTML titles to forums related views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1598 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 09:08:58 +00:00
Jean-Philippe Lang
0344719482 Makes importer work with Trac 0.8.x (#1540).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1597 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 09:03:03 +00:00
Jean-Philippe Lang
22c9a43899 Fixed: associated revisions are displayed in wrong order on issue view (#1546).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1596 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 08:55:37 +00:00
Jean-Philippe Lang
fa88a592fd Fixed #1545: migration on fresh install fails (broken by r1592).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1595 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-29 08:14:13 +00:00
Jean-Philippe Lang
75a5dbd01d Upgraded to Prototype 1.6.0.1.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1594 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-28 11:34:53 +00:00
Jean-Philippe Lang
bd3191f80d New rake task name in comments for creating sessions migration (#1520).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1593 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-27 20:18:23 +00:00
Jean-Philippe Lang
ce6cf66f6c Custom fields refactoring: most of code moved from controllers to models (using new module ActsAsCustomizable).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1592 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-27 20:13:56 +00:00
Jean-Philippe Lang
a4a8b6381e Adds a key in lang files (general_csv_decimal_separator) to set the decimal separator (point or comma) in csv exports (#1372).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1591 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-26 19:46:57 +00:00
Jean-Philippe Lang
864ac367e8 Translations updates:
* Simplified Chinese (chaoqun zou)
* Hungarian (Gábor Takács)
* Russian (Denis Tomashenko)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1590 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-26 19:29:05 +00:00
Jean-Philippe Lang
f79f19f84c Fixed: timelog redirects inappropriately when :back_url is blank (#1524).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1589 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-26 19:11:07 +00:00
Jean-Philippe Lang
0fd9b102be Adds anchor to atom feed messages links.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1588 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-26 19:04:58 +00:00
Jean-Philippe Lang
b3939fb134 Link to view specific file on revision view fails with Subversion repository subdirectory (#1525).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1587 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-26 17:02:09 +00:00
Jean-Philippe Lang
ad7816cea4 Tests: create tmp/test if it doesn't exist.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1586 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-26 14:59:03 +00:00
Jean-Philippe Lang
31e3d180c0 Add project name to cross-project Atom feeds (#1527).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1585 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-26 14:54:45 +00:00
Jean-Philippe Lang
25bba80c9e Adds a simple API and a standalone script that can be used to forward emails from a local or remote email server to Redmine (#1110).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1584 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-25 19:25:28 +00:00
Jean-Philippe Lang
4d6f50d3fe Encoding set to utf8 in example database.yml (#1506).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1583 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-24 18:39:49 +00:00
Jean-Philippe Lang
c97a5efde9 Fixed: private method 'gsub' called for nil:NilClass on activity (#1519).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1582 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-24 16:52:41 +00:00
Jean-Philippe Lang
8474d05e99 Fixes test broken by r1578.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1581 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-24 16:49:51 +00:00
Jean-Philippe Lang
3121e0b5d0 Smaller font size for activity events and search results descriptions.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1580 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-23 17:12:12 +00:00
Jean-Philippe Lang
810ec643f8 Strip pre/code tags content from activity view events.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1579 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-23 17:06:58 +00:00
Jean-Philippe Lang
dc57b06b6c Adds a class ('me') to events of the activity view created by current user.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1578 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-23 17:01:21 +00:00
Jean-Philippe Lang
28c094f50e Turn ftp urls into links (#1514).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1577 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-23 16:51:13 +00:00
Jean-Philippe Lang
0d5b03bab7 Add filters on cross-project issue list for custom fields marked as 'For all projects'.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1576 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 15:35:11 +00:00
Jean-Philippe Lang
b025b63111 Hide 'Target version' filter if no version is defined.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1575 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 15:20:59 +00:00
Jean-Philippe Lang
b14aa23c8c Revision view: do not display links for deleted files.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1574 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 14:40:45 +00:00
Jean-Philippe Lang
c107fee54e Use new image instead of expand.png
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1573 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 14:35:56 +00:00
Jean-Philippe Lang
8b6dd3fdcd IMAP: fetch unseen messages only.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1572 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 13:14:45 +00:00
Jean-Philippe Lang
8b33565b3e IMAP: Mark emails as Seen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1571 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 12:56:10 +00:00
Jean-Philippe Lang
268165a013 Fixes reply attachments handling.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1570 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 12:37:24 +00:00
Jean-Philippe Lang
3d8d4fa0d6 Adds a rake task (redmine:email:receive_imap) to read emails from an IMAP server (#1110).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1569 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 12:27:00 +00:00
Jean-Philippe Lang
a01f976b4c Adds basic support for issue creation via email (#1110).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1568 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-22 10:45:03 +00:00
Jean-Philippe Lang
bb1edda6e8 Display issue notes in the activity view (#1509).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1567 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-21 12:32:47 +00:00
Jean-Philippe Lang
ba8a36a39b Removes spaces before colons on issue detail view (#1512).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1566 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-21 10:15:07 +00:00
Jean-Philippe Lang
9cfa233001 Track project and tracker changes in issue history.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1565 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-19 18:52:20 +00:00
Jean-Philippe Lang
0870f6267f Add target version to the issue list context menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1564 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-18 20:15:51 +00:00
Jean-Philippe Lang
fda7bcdfb6 Mercurial adapter tests fix (#1469).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1563 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-18 17:02:39 +00:00
Jean-Philippe Lang
af734b1b38 Enable syntax highlight on issues, messages and news (#1473, #1466).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1562 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-18 16:49:40 +00:00
Jean-Philippe Lang
7d143bc3f7 Allow dot in firstnames and lastnames (closes #1426).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1561 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-17 20:14:31 +00:00
Jean-Philippe Lang
062a2d6f5d Adds atom feed on time entries details (#1479).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1560 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-17 20:01:15 +00:00
Jean-Philippe Lang
d991e46f12 Fixed: urls containing @ are parsed as email adress by the wiki formatter (#1456).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1559 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-17 19:27:03 +00:00
Jean-Philippe Lang
3c95f761e6 Ability to remove enumerations (activities, priorities, document categories) that are in use. Associated objects can be reassigned to another value (#1467).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1558 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-17 19:10:54 +00:00
Jean-Philippe Lang
f4e0c77c83 Prevent unwanted textile link parsing at end of line.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1557 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-16 19:37:09 +00:00
Jean-Philippe Lang
0223b87612 RepositoriesController cleanup with rescue_from.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1555 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 16:11:07 +00:00
Jean-Philippe Lang
9737beecc4 Adds a field on the repository view to browse at specific revision (#1443).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1554 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 15:56:47 +00:00
Jean-Philippe Lang
ca6e69ec24 Fixed: view file at given revision with CVS.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1553 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 15:47:28 +00:00
Jean-Philippe Lang
93b3dba926 Makes changes link to entries on the revision view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1552 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 14:40:05 +00:00
Jean-Philippe Lang
7c1c2e1ba2 Fixes test broken by r1549.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1551 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 14:39:52 +00:00
Jean-Philippe Lang
8a54c455b8 Fixes test broken by r1549.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1550 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 14:34:23 +00:00
Jean-Philippe Lang
5051566e51 Prettier url for changesets (#1443).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1549 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 14:19:06 +00:00
Jean-Philippe Lang
576130f363 Doc update for 0.7.2 release.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1546 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 12:25:48 +00:00
Jean-Philippe Lang
597c1e6c09 Adds links to repository directories in the browser (#1094).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1544 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 11:40:13 +00:00
Jean-Philippe Lang
11e9891425 Fixed: TOC does not remove colorization markups (#1423).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1542 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 11:00:40 +00:00
Jean-Philippe Lang
8b2105e20a Translation updates.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1540 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 09:49:16 +00:00
Jean-Philippe Lang
622798a5ed Close statement handler in Redmine.pm (#1433).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1539 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 09:43:53 +00:00
Jean-Philippe Lang
2b3009d91d Hungarian translation update (closes #1408).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1538 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-15 09:38:02 +00:00
Jean-Philippe Lang
b1a8790a36 File size display with Bazaar repositories (#1149).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1537 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-14 15:44:36 +00:00
Jean-Philippe Lang
34bcd5b80b Fixed: Logtime info lost when there's an error updating an issue (#1400).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1535 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-14 14:10:47 +00:00
Jean-Philippe Lang
846045fd05 Fixed: time entries created with the default activity even if a different one is specified (#1302).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1533 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-14 12:31:32 +00:00
Jean-Philippe Lang
40a9bbe946 CVS: add support for modules names with spaces (#1434).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1527 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-14 11:42:50 +00:00
Jean-Philippe Lang
d2ad4edc86 Fixed: page has no title when adding a project (#1436).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1526 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-14 11:15:57 +00:00
Jean-Philippe Lang
b42b697ffb Fixed: unexpected nil when viewing differences on CVS (#1444).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1525 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-14 10:51:15 +00:00
Jean-Philippe Lang
cc9b8f7878 Fixed: SVG::Graph raises an error when using external stylesheet (#1402).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1524 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-09 20:05:32 +00:00
Jean-Philippe Lang
53b5703981 Slight changes to diff view and style.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1523 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-09 19:15:40 +00:00
Jean-Philippe Lang
efe790a8d3 Removed inconsistent revision numbers on diff view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1522 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-09 19:02:22 +00:00
Jean-Philippe Lang
19cb6f96f4 Log the user in after registration if account activation is not needed.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1521 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-09 18:59:15 +00:00
Jean-Philippe Lang
80a7486f95 File viewer for attached text files.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1520 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-09 18:40:59 +00:00
Jean-Philippe Lang
aa0beecad0 Move the file viewer to a partial.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1519 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-09 17:02:55 +00:00
Jean-Philippe Lang
e46b56d7fc "New Project" link on Projects page for admin users (#1082).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1518 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 22:45:22 +00:00
Jean-Philippe Lang
0389c60129 Fixed: notextile tag has no effect.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1517 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 20:31:36 +00:00
Jean-Philippe Lang
d77c1d2829 Unified diff viewer for attached files with .patch or .diff extension (#1403).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1516 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 18:26:39 +00:00
Jean-Philippe Lang
e833cab30e Move diff viewer to a partial.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1515 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 18:10:49 +00:00
Jean-Philippe Lang
b78b62df8d SCM browser: ability to download raw unified diffs.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1514 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 16:48:21 +00:00
Jean-Philippe Lang
ec0525d497 Move unified diff parser out of the scm abstract adapter so it can be reused for viewing attached diffs (#1403).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1513 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 16:28:42 +00:00
Jean-Philippe Lang
731d15fe9b Don't search for the changeset if revision identifier is nil.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1512 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 15:47:55 +00:00
Jean-Philippe Lang
0aba4255f5 Don't display the table headers if there is no changeset to display.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1511 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 15:46:15 +00:00
Jean-Philippe Lang
a0d1414606 Filesystem adapter: read files in binary mode.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1510 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 15:44:23 +00:00
Jean-Philippe Lang
5dea200774 Filesystem adapter: negative size is displayed for large files under win32.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1509 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 15:43:32 +00:00
Jean-Philippe Lang
e69b4647f2 Adds Filesystem adapter (patch #1393 by Paul R).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1508 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 15:40:24 +00:00
Jean-Philippe Lang
dfe62d7f51 Ability to disable unused SCM adapters in application settings.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1507 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 14:59:26 +00:00
Jean-Philippe Lang
05cd95987f Fixes tabulation with Firefox 2 on tabular forms.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1506 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-08 10:10:54 +00:00
Jean-Philippe Lang
2e8b2d5e13 Display status change before subject of issue on the activity view otherwise it may be truncated.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1505 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 20:06:44 +00:00
Jean-Philippe Lang
383da1e6d6 Fixes functional tests broken by r1501.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1504 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 15:14:42 +00:00
Jean-Philippe Lang
d446469f5d Removes constraint on enumerations name (#1384).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1503 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 15:08:59 +00:00
Jean-Philippe Lang
042da97f54 Trac importer: read session_attribute table to find user's email and real name (#1340).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1502 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 14:55:32 +00:00
Jean-Philippe Lang
956ad0a3f9 Fixed: Reply/Quote Function Newline Issue in Internet Explorer (#1362).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1501 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 11:42:37 +00:00
Jean-Philippe Lang
6d5db302ee Subversion adapter: ignore directories with no commit date (#1370).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1500 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 10:08:11 +00:00
Jean-Philippe Lang
aa9d04a4a7 Mercurial adapter improvements (patch #1199 by Pierre Paysant-Le Roux).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1499 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 09:19:50 +00:00
Jean-Philippe Lang
a6da479a63 Translations updates.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1498 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 09:03:20 +00:00
Jean-Philippe Lang
f4aa04b96e Fixes Chinese pdf export when the issue description is too long (#1170).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1497 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-07 08:39:06 +00:00
Jean-Philippe Lang
9f901a0ba2 Fixed: Atom link on saved query does not include query_id (#1390).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1496 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-06 15:20:08 +00:00
Jean-Philippe Lang
a0f83e42e4 Hides the "Replies" heading below a message if there is no reply (#1350).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1495 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-06 15:14:09 +00:00
Jean-Philippe Lang
8aa57058cf Trac importer: improves wiki link conversion (#1287).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1494 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-06 15:02:47 +00:00
Jean-Philippe Lang
a5ee8f8986 Fixed: SVN errors lead to svn username/password being displayed to end users (#1368).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1493 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-06 14:37:49 +00:00
Jean-Philippe Lang
cd824c6ecf Redmine links regexp fix (#1369, url hash turned into a ticket link).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1492 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-04 21:30:12 +00:00
Jean-Philippe Lang
4db45b8ced Fixed: changesets titles should not be multiline in atom feeds (#1356).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1491 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-04 18:13:14 +00:00
Jean-Philippe Lang
735db3dae5 Allow empty cells in wiki tables.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1490 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-04 17:12:59 +00:00
Jean-Philippe Lang
a77fb3b591 Missing strings (r1488).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1489 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-03 18:41:36 +00:00
Jean-Philippe Lang
7042879811 Make the 'duplicates of' relation asymmetric:
* closing a issue will close its duplicates
* closing a duplicate won't close the main issue

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1488 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-03 18:30:29 +00:00
Jean-Philippe Lang
891a71ad47 Fixed: new line at the end of a file is not displayed in diff.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1487 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-02 20:14:06 +00:00
Jean-Philippe Lang
36162c6cf2 Diff: adds some space between 2 changes in the same file and reduces html size.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1486 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-02 19:18:17 +00:00
Jean-Philippe Lang
870e8654b4 Fixed: Atom feeds don't provide author section for repository revisions (#1348).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1485 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-02 18:16:56 +00:00
Jean-Philippe Lang
4cc3ba88a8 Fixed: Link to PDF doesn't work after creating new issue (#1346).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1484 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-02 17:01:02 +00:00
Jean-Philippe Lang
a06d2c41d5 Fixed: Reminder emails shouldn't include archived projects (#1351).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1483 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-06-02 16:59:15 +00:00
Jean-Philippe Lang
50c338b229 Additional test for r1481.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1482 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-30 18:42:56 +00:00
Jean-Philippe Lang
9894a3781e Fixed: browser's accept-language subcodes ignored (#1320).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1481 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-30 18:40:02 +00:00
Jean-Philippe Lang
5d2abb84bd Adds a Reply link to each issue note (#739). Reply is pre-filled with the quoted note.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1480 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-30 17:42:25 +00:00
Jean-Philippe Lang
88dea1a06d Adds multi-levels blockquotes support by using > at the beginning of lines.
Textile is preserved inside quoted text.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1479 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-30 16:35:36 +00:00
Jean-Philippe Lang
4311ecbc04 Fixed: Incorrect weekend definition in Hebrew calendar locale (#1328).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1478 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-30 15:34:53 +00:00
Jean-Philippe Lang
ffea044699 Trac importer: migrate attachments descriptions (#1326).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1477 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-29 19:31:21 +00:00
Jean-Philippe Lang
6ebdf848a5 Fixed: Unable to use angular braces after include word in c code highlighting (#1230).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1476 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-29 19:12:17 +00:00
Jean-Philippe Lang
e1a86106d0 Fixed: GitAdapter#get_rev should use current branch instead of hardwiring @master@ (#1319).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1475 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-29 18:48:00 +00:00
Jean-Philippe Lang
39216f327c Fixed: can not access old projects created with a numeric identifier (#1322).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1473 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-29 17:42:10 +00:00
Jean-Philippe Lang
eb0e218603 Adds new projects atom feed (#1290).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1465 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-27 16:49:18 +00:00
Jean-Philippe Lang
744d866926 Moved ProjectsController#list to ProjectsController#index.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1464 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-26 20:10:32 +00:00
Jean-Philippe Lang
aa87a73e41 No multiline text for textile links.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1463 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-26 19:39:51 +00:00
Jean-Philippe Lang
54138d2b17 Fixed roadmap links to versions (#1297).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1462 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-26 19:12:29 +00:00
Jean-Philippe Lang
d6daeca40a Fixed: IssueController#edit doesn't set default Activity as default (#1302).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1461 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-26 17:12:11 +00:00
Jean-Philippe Lang
b3e5f1a1c3 Fixed zh lang file.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1460 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 20:49:07 +00:00
Jean-Philippe Lang
0c81052770 Adds a rake task to send reminders. An email is sent to each user with a list of the issues due in the next days, if any.
See @rake -D redmine:send_reminders@ for options.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1459 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 17:31:50 +00:00
Jean-Philippe Lang
d99dc4070a Remove edit step from Status context menu (#1197).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1458 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 15:09:42 +00:00
Jean-Philippe Lang
dfcc8e1492 Change projects homepage limit to 255 chars (#663, #1095).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1457 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 13:37:29 +00:00
Jean-Philippe Lang
c7d83be613 Test for striked through wiki link (#199).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1456 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 13:30:54 +00:00
Jean-Philippe Lang
a92749ef93 Gantt chart: display issues that don't have a due date if they are assigned to a version with a date (#184).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1455 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 13:26:21 +00:00
Jean-Philippe Lang
03f0236a6e Prevents NoMethodError on @available_filters.has_key? in query.rb (#1178).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1454 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 12:50:33 +00:00
Jean-Philippe Lang
02757f5892 Translations updates.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1453 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 12:42:56 +00:00
Jean-Philippe Lang
fbafff8363 Hungarian translation added (#1198 by Gábor Takács).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1452 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 12:18:49 +00:00
Jean-Philippe Lang
e8d092e46a Fixed: using '*' as keyword for repository referencing keywords doesn't work when issue id is at the beginning of a line (#1253).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1451 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 11:43:20 +00:00
Jean-Philippe Lang
39fc8f38b8 Prevent admin users from making themselves non-administrator (#1276).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1449 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-25 11:22:53 +00:00
Jean-Philippe Lang
7f134a8c67 Prevent admin users from locking their own account (#1276).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1448 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-24 18:42:53 +00:00
Jean-Philippe Lang
0e5edccaf2 Fixed: Issue number display clipped on 'my issues' (#1291).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1447 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-24 18:37:06 +00:00
Jean-Philippe Lang
193b2450f4 Fixed: View differences for individual file of a changeset fails if the subversion repository URL doesn't point to the repository root (#1209, #1262, #1275).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1446 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-24 17:58:34 +00:00
Jean-Philippe Lang
9d4e71adf3 Fixed: error when previewing a new wiki page (#1292) introduced in r1415.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1445 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-23 16:29:40 +00:00
Jean-Philippe Lang
e02e047dd4 Fixed: TypeError in WikiController#destroy_attachment (#1281).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1444 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-22 18:26:43 +00:00
Jean-Philippe Lang
82c12d09e9 Fixed: non member or anonymous permissions change is effective only after an application restart (#1280).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1443 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-22 18:08:54 +00:00
Jean-Philippe Lang
62125cad33 Fixed: encoding problem when adding non-ASCII issue category in the new issue page (#1286).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1442 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-22 17:02:29 +00:00
Jean-Philippe Lang
e5bc1d370a Use display: block; for activity item descriptions.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1441 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-20 20:49:06 +00:00
Jean-Philippe Lang
03308028c9 Slight changes to the search results.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1440 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-20 20:45:53 +00:00
Jean-Philippe Lang
b0be3b95aa Ability to search a project and its subprojects (#1264).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1439 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-20 20:31:04 +00:00
Liwiusz Ociepa
94dbf641ff Memory leak (postgres -> zlib + ssl) has been fixed by apache developers.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1438 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-19 12:41:40 +00:00
Jean-Philippe Lang
82f204d8ac Adds icons on search results.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1436 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-18 16:33:50 +00:00
Jean-Philippe Lang
073818f8bc Ability to search all projects or the projects the user belongs to (#791).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1435 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-18 16:15:22 +00:00
Jean-Philippe Lang
1907c31138 Fixed: bold, italics, underline not working within parentheses (#1225).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1434 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-18 08:24:31 +00:00
Jean-Philippe Lang
439c697237 Fixed: possible error when attachment's filename is non-ASCII (#747, #1243, #1089).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1433 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-17 11:03:43 +00:00
Jean-Philippe Lang
9e225cc63f Fixed: private subprojects are listed on the issues view (#1217).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1432 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-14 18:19:37 +00:00
Jean-Philippe Lang
7ee38a95a0 Fixed: Calendar and Gantt show private subprojects even if current user is not a member of them (#1217).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1431 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-14 18:01:13 +00:00
Jean-Philippe Lang
06e44b8e64 Do not toggle assignable check box when using un/check all permissions links on role form.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1430 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-14 17:26:13 +00:00
Jean-Philippe Lang
4c6b9d9ce5 Fixed: Check All / Uncheck All in Email Settings doesn't work (#1180).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1429 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-14 17:23:40 +00:00
Jean-Philippe Lang
835cc7ed7c Fixed: Redmine::Scm::Adapters::GitAdapter#get_rev ignored GIT_BIN constant (#1207).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1428 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-13 17:54:51 +00:00
Jean-Philippe Lang
75d25b7e61 Fixed: Update issue form: comment field from log time end out of screen (#1227).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1427 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-13 17:51:55 +00:00
Jean-Philippe Lang
77e87eb0ba Fixed: some labels overflow the form box (#1228).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1426 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-13 16:56:34 +00:00
Liwiusz Ociepa
c4560c4f3b Merge changes from branch swistak.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1425 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-13 09:41:19 +00:00
Jean-Philippe Lang
0476669735 Wiki page protection (#851, patch #1146 by Mateo Murphy with slight changes).
New permission added: protect wiki pages. Once a page is protected, it can be edited/renamed/deleted only by users who have this permission.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1415 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-04 15:05:38 +00:00
Jean-Philippe Lang
556df99456 Doc update for 0.7.1 release.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1412 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-04 10:20:16 +00:00
Jean-Philippe Lang
9e5624c362 Prevent "can't convert nil into String" error when :sort_order param is not present.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1410 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-03 15:09:06 +00:00
Jean-Philippe Lang
35321d938b Translations updates (closes #1128, #1129, #1135, #1148, #1163).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1409 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-03 10:41:28 +00:00
Jean-Philippe Lang
251b1f75e9 Fixed: error on Trac import when :due attribute is nil (#1164).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1406 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-02 16:48:09 +00:00
Jean-Philippe Lang
c65d696f41 Fixed: error when using upcase language name in coderay (#1162) (Windows specific).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1405 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-02 15:35:41 +00:00
Jean-Philippe Lang
63951812a1 Split user edit screen into tabs.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1404 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-02 15:21:21 +00:00
Jean-Philippe Lang
7a969dafac Escape HTML comment tags (#1160).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1403 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-02 15:16:17 +00:00
Jean-Philippe Lang
7f8d959171 Show the project hierarchy in the drop down list for new membership on user administration screen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1401 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-01 13:50:39 +00:00
Jean-Philippe Lang
f705b889d9 Hide the 'Latest projects' box on the welcome screen if there are no projects (#1156).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1400 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-01 13:01:23 +00:00
Jean-Philippe Lang
2d11265ec5 Fixed: private subprojects names are revealed on the project overview (#1152).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1399 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-01 12:56:59 +00:00
Jean-Philippe Lang
6d637ad982 Add Redcloth's :block_markdown_rule to allow horizontal rules in wiki (#967).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1389 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-05-01 08:44:40 +00:00
Jean-Philippe Lang
b2abe48592 Use GET instead of POST on roadmap (#718), gantt and calendar forms.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1388 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-30 12:14:15 +00:00
Jean-Philippe Lang
f1ae453688 Fixed: Updating tickets add a time log with zero hours (#1147).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1385 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-30 09:09:28 +00:00
Jean-Philippe Lang
4525a7429a Fixed: Home, Logout, Login links are absolute (#1122, #1145).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1384 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-30 08:51:12 +00:00
Jean-Philippe Lang
4403e300ff Thai translation added (Gampol Thitinilnithi, #1136).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1383 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-30 08:47:14 +00:00
Jean-Philippe Lang
5f58e2ced2 Fixed: Search for target version of "none" fails with postgres 8.3 (#1134).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1379 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-29 09:57:47 +00:00
Jean-Philippe Lang
05d39eeb35 Changelog update.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1369 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-28 10:26:05 +00:00
Jean-Philippe Lang
e55c1d82e6 Notify project members when a message is posted if they want to receive notifications for everything on the project (#1079).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1368 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-28 09:25:51 +00:00
Jean-Philippe Lang
67e7758185 Translation updates (closes #1123, #1124):
* Spanish (Gumer Coronel)
* Norvegian (Kai Olav Fredriksen)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1367 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-28 08:52:35 +00:00
Jean-Philippe Lang
c72b53a8fa Forces Redmine to use rails 2.0.2 gem when vendor/rails is not present.
If you don't want to upgrade rails gem, freeze Redmine by running the following command in your Redmine directory:

  rake rails:freeze:edge TAG=rel_2-0-2

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1366 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-27 16:34:42 +00:00
Jean-Philippe Lang
a73f68a185 Fixed: Links to repository directories don't work (#1119).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1365 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-27 10:12:15 +00:00
Jean-Philippe Lang
6a3236daea Include subprojects versions on calendar and gantt (#1116).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1364 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-27 08:20:53 +00:00
Jean-Philippe Lang
ffbdc6b25b Postgresql 8.3 compatibility fix (#834).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1363 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-26 17:56:26 +00:00
Jean-Philippe Lang
64474802f9 Fixes custom field filters behaviour (#1078).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1362 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-26 16:55:24 +00:00
Jean-Philippe Lang
a6311a9603 Estimated time recognizes improved time formats (#1092).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1361 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-26 11:59:51 +00:00
Jean-Philippe Lang
1d570a40ff Fixed: ActiveRecord::StaleObjectError exception on closing a set of circular duplicate issues (#1105).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1360 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-26 10:54:46 +00:00
Jean-Philippe Lang
76b92fb999 Warn user that subprojects are also deleted when deleting a project (#1111) and add a checkbox to confirm the deletion.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1359 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-26 10:20:48 +00:00
Jean-Philippe Lang
a9f86444fc Fixed: Modules selection not remembered when new project creation fails (#1109).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1358 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-26 09:49:16 +00:00
Jean-Philippe Lang
596de073f9 Commits per author graph: remove email adress in usernames (#1066).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1357 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-24 18:35:56 +00:00
Jean-Philippe Lang
2b412e9e07 Fixed: trying to preview a new issue raises an exception (closes #984).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1356 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-24 17:35:04 +00:00
Jean-Philippe Lang
76b8d3eff2 CVS duplicate key violation fix (#996, #1098).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1355 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-24 17:28:55 +00:00
Jean-Philippe Lang
1a4f81163d Redirected user to where he is coming from after logging hours (#1062).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1354 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-16 17:27:53 +00:00
Jean-Philippe Lang
7061f73708 ApplicationHelperTest fix.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1353 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-15 20:27:10 +00:00
Jean-Philippe Lang
277bee62eb Issue list shows all tickets when going back to a global query inside a project (closes #1055).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1352 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-14 19:21:58 +00:00
Jean-Philippe Lang
741ddfb50b Hide export links in print media css.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1351 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-14 19:13:22 +00:00
Jean-Philippe Lang
0329094f01 Include macro can include a page of another project wiki using !{{include(projectname:Foo)}} (#1052).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1350 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-13 16:22:55 +00:00
Jean-Philippe Lang
e644435715 Add css class for ticket changes (#1032).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1349 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-13 13:24:03 +00:00
Jean-Philippe Lang
97fe797ad3 Replace closing html tags with html entity (#910).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1348 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-13 12:45:17 +00:00
Jean-Philippe Lang
8b9fb29d95 Translation updates (closes #1010, #1017, #1047):
* Finnish (Antti Perkiömäki)
* Spanish (Gumer Coronel)
* Czech (Maxim Krušina)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1347 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-13 12:25:22 +00:00
Jean-Philippe Lang
56683967da Left align filter buttons (closes #872) and reduce filters spacing.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1346 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-13 11:18:09 +00:00
Jean-Philippe Lang
a340d8c957 Better error message and AR errors in log for failed LDAP on-the-fly user creation (closes #932, #1042).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1345 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-13 09:12:43 +00:00
Jean-Philippe Lang
8eb86396e1 Fixed: Double dot displayed on ticket view when ticket not updated (closes #813).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1344 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-12 17:25:06 +00:00
Jean-Philippe Lang
7aaa538fd9 Fixed: error when browsing an empty Mercurial repository (#1046).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1343 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-12 17:13:17 +00:00
Jean-Philippe Lang
6d2a89142a Add an icon to each event on the activity view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1342 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-12 16:54:14 +00:00
Jean-Philippe Lang
85f040c536 Fixed: preview fails when updating an issue (broken by r1322). Patch #1027.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1341 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-09 17:52:41 +00:00
Jean-Philippe Lang
a3c89d4f69 Custom fields (list and boolean) can be used as criteria in time report (#1012).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1340 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-09 17:45:39 +00:00
Jean-Philippe Lang
f025b16be7 Fix date range filter js behaviour and css fix for IE.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1339 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-07 17:56:32 +00:00
Jean-Philippe Lang
5d34548539 CSV export added to timelog report (#1009).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1338 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-07 17:18:09 +00:00
Jean-Philippe Lang
fc1a295d8a Redmine.pm doc update
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1337 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-07 17:03:02 +00:00
Jean-Philippe Lang
2bcb782087 Redmine.pm for webdav authentication:
* make Authen::Simple::LDAP module optional
* handle TLS flag set in Redmine

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1336 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 17:36:26 +00:00
Jean-Philippe Lang
246e8f67c5 Redmine.pm support for LDAP authentication (patch by Liwiusz Ociepa). Closes #879, #918.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1335 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 17:29:09 +00:00
Jean-Philippe Lang
0249ae5f50 Preserve status filter and page number when using lock/unlock/activate links on the users list (closes #998).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1334 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 13:15:09 +00:00
Jean-Philippe Lang
beff2c54bc Mercurial: display working directory files sizes unless browsing a specific revision (#999).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1333 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 12:22:59 +00:00
Jean-Philippe Lang
db7f890030 Mercurial: Get proper file action on revision (#983).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1332 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 12:00:11 +00:00
Jean-Philippe Lang
a7ca01a8de Translation updates:
* Norwegian (Kai Olav Fredriksen)
* German (Thomas Löber)
* Bulgarian (Nikolay Solakov)
* Hebrew (Ficoos Bangaly)
* Russian (Michael Pirogov)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1331 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 11:07:16 +00:00
Jean-Philippe Lang
fe74ab8c06 Make the project files list sortable (#997).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1330 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 10:53:18 +00:00
Jean-Philippe Lang
154f60edd3 Fix repository browsing at given revision for various scm and add tests for this.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1329 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-06 10:35:55 +00:00
Jean-Philippe Lang
c37abb6415 Inline images alt attribute set to the attachment description.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1328 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-05 18:56:08 +00:00
Jean-Philippe Lang
c6271d8361 Fixed: inline image not displayed when including a wiki page (closes #1001).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1327 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-05 17:39:19 +00:00
Jean-Philippe Lang
4e961f44ef Various timelog report enhancements:
* report can be done using days as columns (#993)
* add a total column to the time report
* replace upper-right links by tabs to switch between details and report
* preserve date range filter when switching between details and report


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1326 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-05 16:40:26 +00:00
Jean-Philippe Lang
8d4aa6f9ad Fixed: single file 'View difference' links do not work because of duplicate slashes in url.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1325 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-03 22:29:58 +00:00
Jean-Philippe Lang
14a2b7e9b5 Verify rev and rev_to params format in RepositoriesController. And turn revision arguments into integers in SubversionAdapter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1324 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-03 16:50:53 +00:00
Jean-Philippe Lang
f6ce427a00 Display the context menu above and/or to the left of the click if needed (patch by Mike Duchene, closes #960).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1323 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-03 16:38:06 +00:00
Jean-Philippe Lang
7f0aa56119 Fixed: trying to preview a new issue raises an exception with postgresql (close #984).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1322 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-03 13:16:51 +00:00
Jean-Philippe Lang
6348eeaf8a Attachment model clean up: fixed some inconsistent indentation and an inaccurate comment (closes patch #903 by Rocco Stanzione).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1321 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-02 21:30:32 +00:00
Jean-Philippe Lang
4cbe6b626e Accept the following formats for the timelog "hours" field: 1h, 1 h, 1 hour, 2 hours, 30m, 30min, 1h30, 1h30m, 1:30.
Also accept 1,5 for 1.5 hour (closes #975). Note that 1.5 is still equal to 1h30 and not 1h50 (#947).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1320 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-02 19:52:12 +00:00
Jean-Philippe Lang
467f74510e Time report can be done at issue level (closes #970) + timelog views xhtml validation.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1319 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-01 22:42:10 +00:00
Jean-Philippe Lang
043cb37b16 Add predefined date ranges to the time report in the same way as the details view (closes #972). It nows defaults to 'All time'.
This patch also fixes time report periods (columns) computation.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1318 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-01 19:40:40 +00:00
Jean-Philippe Lang
e4da9d6f10 Prevent NoMethodError on nil class if custom_fields params is not present in IssuesController#new (#969).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1317 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-01 17:48:11 +00:00
Jean-Philippe Lang
80a5ad7ff3 Fixed: Boards are not deleted when project is deleted (closes #963).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1316 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-04-01 17:43:20 +00:00
Jean-Philippe Lang
68fe7856c9 Move repetitive calendar include code from views into helper (patch #966 by Peter Suschlik).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1315 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-31 21:48:01 +00:00
Jean-Philippe Lang
0d9e419646 Add overflow:auto to the content div (closes #676, #748, #961).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1314 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-31 20:51:56 +00:00
Jean-Philippe Lang
da641f4122 Global queries can be saved from the global issue list (follows r1311 and closes #897).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1312 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-30 14:20:07 +00:00
Jean-Philippe Lang
287d86e363 Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list (#897, closes #671).
Only admin users can create/edit queries that are public and for all projects.
Note: this change does not allow to save a query from the global issue list. You have to be inside a project but then you can mark the query as 'For all projects'.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1311 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-30 12:29:07 +00:00
Jean-Philippe Lang
faf1f1e812 Fixed: Feed content limit setting has no effect (closes #954).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1310 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-30 08:33:04 +00:00
Jean-Philippe Lang
cd64338a7f Fixed: Priorities not ordered when displayed as a filter in issue list (#956).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1309 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-30 08:19:56 +00:00
Jean-Philippe Lang
1b8c5d4058 Fixed: can not display attached images inline in message replies.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1308 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-29 22:35:04 +00:00
Jean-Philippe Lang
5ccbeba5c2 Use #blank? instead of #empty? in news/show view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1307 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-29 20:03:20 +00:00
Jean-Philippe Lang
a381b0978f Changelog updated.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1304 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-29 11:43:07 +00:00
Jean-Philippe Lang
0dfa2ad3cf Show date range on the activity (closes #837).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1303 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-29 11:12:57 +00:00
Jean-Philippe Lang
1bb51f743a Fixed: migrate_from_trac doesn't import timestamps of wiki and tickets (patch #882 by Andreas Neuhaus slightly edited).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1302 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-29 10:54:24 +00:00
Jean-Philippe Lang
85858cebe6 Fixed: https urls in the wiki are not displayed as external (closes #943).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1301 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-29 09:24:09 +00:00
Jean-Philippe Lang
6331809bd9 Translation updates: (closes #915, #927, #929, #923, #914, #919)
* Japanese (Satoru Kurashiki)
* Simplified Chinese (chaoqun zou)
* Danish (kim madsen)
* Norwegian (Kai Olav Fredriksen)
* Traditional Chinese (shortie lo)
* German (Sven Schuchmann)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1300 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-27 19:27:40 +00:00
Jean-Philippe Lang
b9e380c9fe Add breadcrumb nav for the forums (#892).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1299 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-27 18:41:42 +00:00
Jean-Philippe Lang
8960200409 If 'Display subprojects issues on main projects' is set to false:
* do not include subprojects in the issue count of the parent project overview (#939)
* do not include subproject timelogs on the parent project (#848)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1298 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-27 18:22:12 +00:00
Jean-Philippe Lang
ef80597c39 Trac importer: exclude more Trac wiki pages (#933).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1297 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-26 23:22:33 +00:00
Jean-Philippe Lang
ecc742f3ce Make the versions with the same date sorted by name (#864).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1296 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-26 22:56:30 +00:00
Jean-Philippe Lang
7a434c902a Bigger wiki h3 headings.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1295 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-26 22:46:18 +00:00
Jean-Philippe Lang
d37a30846f Fixed: when bulk editing, setting "Assigned to" to "nobody" causes an sql error with Postgresql (#935).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1294 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-26 22:22:45 +00:00
Jean-Philippe Lang
805864590a Do not use javascript to hide tabs content on page loading and make tabs work with javascript disabled.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1293 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-26 18:49:12 +00:00
Jean-Philippe Lang
1c49bd4258 Add the description field to the issue csv export (#753).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1292 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-26 18:08:24 +00:00
Jean-Philippe Lang
051875429e Fixed: 'This week' condition in filter consider monday as the first day of the week even if language sets otherwise (closes #913).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1291 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-23 16:16:55 +00:00
Jean-Philippe Lang
6936eb1022 Make 'Planning' string translatable (closes #890).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1290 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-23 09:04:21 +00:00
Jean-Philippe Lang
de5b0ad0a8 Translations (closes #875, #876, #889, #891, #909):
* Norwegian added (Kai Olav Fredriksen)
* Finnish updated (Antti Perkiömäki)
* Czech updated (Maxim Krušina)
* Russian updated (Michael Pirogov)
* Polish updated (Mariusz Olejnik)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1289 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-23 08:34:13 +00:00
Jean-Philippe Lang
472654aebe Fixed: revision is ignored in MercurialAdapter#cat.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1288 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 22:19:37 +00:00
Jean-Philippe Lang
5f78b8a9a0 Added links to repository files in wiki syntax help.
Styles added and small fixes to the detailed wiki syntax help.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1287 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 22:05:23 +00:00
Jean-Philippe Lang
7fb72e671b Trac importer: prevent validation failure due to the default value when saving the Resolution custom field if it already exists (#869).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1286 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 21:37:40 +00:00
Jean-Philippe Lang
180fe8f6a4 Fix IE6 display bug on the issue list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1285 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 21:08:00 +00:00
Jean-Philippe Lang
60c12ca3ab Doc update before 0.7-rc1 release.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1284 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 20:24:10 +00:00
Jean-Philippe Lang
a8e6f68aaf Add unloadable to the sample plugin controller (http://dev.rubyonrails.org/ticket/6001).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1283 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 20:17:09 +00:00
Jean-Philippe Lang
27cf6d8d64 Add unloadable to the sample plugin controller (http://dev.rubyonrails.org/ticket/6001).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1282 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 20:02:41 +00:00
Jean-Philippe Lang
09bf503fd2 Load Engines plugin if available (closes #180).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1281 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 19:59:43 +00:00
Jean-Philippe Lang
35a14cbfdc Wiki links:
* fixes wiki links with pipe in table (closes #893, #870, #894)
* prevent wiki link matching on multiple lines

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1280 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 17:39:02 +00:00
Jean-Philippe Lang
bbf422e229 Add done_ratio to the right-click context menu.
Closes #904 (back_to variable used in patch #641 and in r1277 is no longer defined).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1279 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-21 17:32:15 +00:00
John Goerzen
8ed97f43d2 Revert "Make an issue's done_ratio field adjustable from the right-click"
Reverts commit r1277
fixes #904
refs #641

This had been working for me in testing for some time, but received
issue #904 saying it broke the context menu.  I was able to make it do
so on a new project as well.  Will revert and comment in #641 about this.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1278 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-20 19:25:18 +00:00
John Goerzen
4ff77cc624 Make an issue's done_ratio field adjustable from the right-click
context menu.

Uses patch from, and fixes #641.  Patch by Dov Murik.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1277 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-20 17:41:03 +00:00
Jean-Philippe Lang
0cccce0c43 Change the tick image and replace the issue selection pencil with a small tick.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1276 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-19 21:39:21 +00:00
Jean-Philippe Lang
43fc812e0e Default theme: smaller font in top menu and new style for main menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1275 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-19 18:22:16 +00:00
Jean-Philippe Lang
f162337e1b Always show 'View' and 'Annotate' links on repository files (download will be forced when clicking 'View' if the file is binary).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1274 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-19 17:51:13 +00:00
John Goerzen
93a33c6286 Added line under tracker name to make clear what is going on here
Partially implements the patch given in r730


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1273 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-18 18:50:52 +00:00
Jean-Philippe Lang
3e102f281d Add a simple java scanner.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1272 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-18 17:39:12 +00:00
Jean-Philippe Lang
7673d69b96 Fixes #880: code tags not formatted correctly in the wiki (broken by r1216).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1271 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-17 23:01:35 +00:00
Jean-Philippe Lang
1c4bcc5b55 Add NewsController and TimelogController tests.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1270 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-17 20:48:22 +00:00
Jean-Philippe Lang
8cb5acf453 Add some tests on RolesController.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1269 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-17 20:02:51 +00:00
Jean-Philippe Lang
030afe7428 Small fix to the Redmine links regexp.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1268 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-17 18:01:26 +00:00
Jean-Philippe Lang
93d1b2e0a4 Add Redmine links for repository files using source: and export: keyworkds (#867).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1267 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-17 17:45:01 +00:00
Jean-Philippe Lang
cab300e650 Prevent page reloading if something goes wrong in the 'add more file' javascript.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1266 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 21:41:36 +00:00
Jean-Philippe Lang
f271e772af Add the following headers to email notifications (#830, #247):
* X-Redmine-Host: host name defined in application settings
* X-Redmine-Site: application title defined in settings
* X-Redmine-Project: identifier of the project that the notification is related to, if any
* X-Redmine-Issue-Id, -Author, -Assignee: ticket related info
* X-Redmine-Topic-Id: identifies the thread a message belongs to

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1265 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 16:52:49 +00:00
Jean-Philippe Lang
4bd35dae8d Allow issue list to be sorted by target version (#832).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1264 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 15:04:33 +00:00
Jean-Philippe Lang
2d01398d67 Trac importer:
* prevent duplication of associated trackers when the target project already exists (closes #829)
* warn user if the target project already exists

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1263 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 14:54:36 +00:00
Jean-Philippe Lang
f5b5688e8a Move the filters buttons inside the filters fieldset on the issue list (closes #614).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1262 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 14:31:17 +00:00
Jean-Philippe Lang
2eb085506b Adds a title attribute to the next/previous links on the activity view, containing the corresponding date range (#837).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1261 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 14:18:36 +00:00
Jean-Philippe Lang
a8fcf8487d Add a time tracking block for 'My page' (#615).
It lists current user's time entries for the last 7 days across all projects, grouped by day with subtotals for each day, and a grand total.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1260 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 12:21:54 +00:00
Jean-Philippe Lang
5b6978a1f3 Add a margin to the bottom of wiki tables (#843).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1259 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-16 10:09:35 +00:00
John Goerzen
888b254844 Further refine WikiCaps processing for Trac to eliminate problems in
some corner cases


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1258 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-15 13:24:08 +00:00
Jean-Philippe Lang
83061e9ca2 Fix tests broken by r1243 (Redirect to issue page after creating a new issue).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1257 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-15 11:27:46 +00:00
Jean-Philippe Lang
451aa6ba4e Add "--encoding utf8" option to the Mercurial "hg log" command in order to get utf8 encoded commit logs (#834).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1256 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-15 11:05:22 +00:00
Jean-Philippe Lang
01fdaf5977 Mercurial adapter:
* fetch changesets by batches of 100 (rather than in a single transaction)
* fix: fetch_changesets tries to re-insert the last revision that exists in the db (#860)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1255 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-15 10:30:56 +00:00
Jean-Philippe Lang
a59e6bfb02 Remove hardcoded "Redmine" strings in account related emails. And use application title instead.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1254 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-15 09:40:16 +00:00
Jean-Philippe Lang
185ecd5854 Translations update (close #845, #822):
* Finnish (Antti Perkiömäki)
* Czech (Maxim Krušina)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1253 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-15 09:25:35 +00:00
Jean-Philippe Lang
aec989707e Workflow copy:
* added the ability the copy an existing workflow when creating a new role (closes #841)
* use a single raw insert statement to copy tracker/role workflow rather than instantiating hundreds/thousands of objects

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1252 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-15 08:27:38 +00:00
Jean-Philippe Lang
993b60d61e Adds 2 permissions (closes #859):
* edit_time_entries: lets a user edit/delete any time entry
* edit_own_time_entries: lets a user edit/delete its own time entries only

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1249 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-14 21:17:09 +00:00
Jean-Philippe Lang
4957752d12 Strip repository urls (closes #852).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1248 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-14 18:59:10 +00:00
John Goerzen
b8b991a7dc Added documentation of commit: syntax to detailed wiki syntax screen
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1247 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-14 13:48:32 +00:00
John Goerzen
cdf3e2b6ef Fix trac converter WikiCaps to put a space before converted WikiCaps words
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1246 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-14 00:52:26 +00:00
John Goerzen
84d2ea054d Update Simplified Chinese lang file
Closes #840 and uses patch from chaoqun zou contained therein, updated
to trunk


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1245 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-13 21:46:31 +00:00
John Goerzen
076d9e7ade This patch takes the RedmineWikiFormatting page and makes it available
as a static HTML file locally. This way, intranet deployments, or
other deployments do not need to be dependent upon redmine.org in
order to display this help.

Closes #815.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1244 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-13 14:14:32 +00:00
John Goerzen
c67c375357 Redirect to issue page after creating a new issue
Previous behavior was to redirect to the issue list with a "successful
creation" message.  This patch will redirect to the page for the
newly-created issue, still with the "successful creation" message.

This matches the behavior after editing an issue and also provides
instant feedback for the user to see if anything went wrong.

Closes #261 and uses the patch contained therein


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1243 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-13 13:59:21 +00:00
John Goerzen
87fb78be0b Support WikiCaps for Trac migrations
Trac wikis support WikiCaps for links to pages.  They also use
!WikiCaps syntax to prevent links.  Support both.

Uses patch from and closes #758.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1242 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-13 05:48:37 +00:00
John Goerzen
eafaae73b7 Updated zh-tw lang file from shortie lo.
Closes #847.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1241 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-13 05:41:31 +00:00
John Goerzen
4f16dc53a4 Add commit: link type feature to wiki_syntax.html
The commit: feature merged to trunk in r1236


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1240 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-13 05:41:28 +00:00
Jean-Philippe Lang
ea161c9ea4 Prevent unexpected nil error in GitAdapter#info if the repository path is invalid.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1239 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-12 23:09:11 +00:00
Jean-Philippe Lang
2c1e63720e SCM AbstractAdapter use shell_quote to more properly escape path (closes #838 by John Goerzen).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1238 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-12 23:00:11 +00:00
Jean-Philippe Lang
d4429a544c Fixes #820: invalid project id causes a NoMethodError in SearchController (Angel Dobbs-Sciortino).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1237 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-12 20:50:48 +00:00
Jean-Philippe Lang
3a9b0988c7 Merged Git support branch (r1200 to r1226).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1236 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-12 20:28:49 +00:00
Jean-Philippe Lang
6fcc512cb7 Adds a setting for whether new projects should be public by default (closes #842, #839).
Patch by Rocco Stanzione, slightly edited.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1235 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-12 19:58:19 +00:00
Jean-Philippe Lang
3a75b6771f Prevent LDAP authentication with empty password related problems.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1231 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-12 17:56:19 +00:00
Jean-Philippe Lang
a9c972fbb3 Quotes Mercurial entries command depending on the OS.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1229 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-11 20:15:05 +00:00
Jean-Philippe Lang
71d3bb2f7b Fixes Mercurial browsing under unix-like os and for directory depth > 2 and (patch #826 by Frederic Moulins, slightly edited to preserve win32 compatibility).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1228 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-11 20:06:25 +00:00
Jean-Philippe Lang
624723d0ce Activity enhancements:
* overall activity view and feed added, link is available on the project list (#423, #494)
* switch added on the project activity view to include subprojects (closes #530)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1227 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-11 19:33:38 +00:00
Jean-Philippe Lang
64fb0a561a Removes the Redmine version from the footer (closes #794). It can still be viewed on admin -> info.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1225 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 22:24:38 +00:00
Jean-Philippe Lang
76a29ae337 Adds atom feed link on boards index.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1224 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 20:16:48 +00:00
Jean-Philippe Lang
4f35ec97e8 Replaces del tags by a css style (a.issue.closed) for closed issue links.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1223 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 18:27:55 +00:00
Jean-Philippe Lang
8195f95464 Fixes migrations that change string limits for sqlite.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1222 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 18:25:37 +00:00
Jean-Philippe Lang
494a6ecfb0 Trac and Mantis importers: check that default configuration is loaded before processing.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1221 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 17:23:22 +00:00
Jean-Philippe Lang
66594d46b2 Allow longer version names (#711, closes #712).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1220 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 15:36:47 +00:00
Jean-Philippe Lang
0ec13848b0 Show replies as well when choosing to display messages in the activity.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1217 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 12:15:27 +00:00
Jean-Philippe Lang
a92cce3851 Textile formatting:
* escape html tags, except pre tags (#807, #795)
* try to avoid unwanted quick phrase modifiers

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1216 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 11:47:36 +00:00
Jean-Philippe Lang
522b9e6b5b Display date/time instead of date on files list (#817).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1215 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-09 11:39:00 +00:00
Jean-Philippe Lang
07882590bb Strip out email address from authors in repository screens (#814).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1208 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-08 13:46:07 +00:00
Jean-Philippe Lang
9b59ea7256 Version details view changes:
* display related issues on the version detail view
* display total estimated and spent hours on the version detail view
* fixed wiki headings size (same as r1168)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1207 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-08 11:17:03 +00:00
Jean-Philippe Lang
1830064918 Changes 'Fixed version' label to 'Target version' (closes #723, #808).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1206 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-08 09:06:16 +00:00
Jean-Philippe Lang
a4c6c62c8b Added preview for forum messages.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1205 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-07 17:49:44 +00:00
Jean-Philippe Lang
4458a7282b Translations (closes #789, #790, #798, #803, #809):
* Danish added (Mads Vestergaard)
* Polish updated (Mariusz Olejnik)
* Finnish updated (Antti Perkiömäki)
* Simplified Chinese updated (chaoqun zou)
* Traditional Chinese updated (shortie lo)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1204 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-07 17:15:50 +00:00
Jean-Philippe Lang
e8035c22b2 Fixes module names localization on projects/add (closes #797).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1203 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-07 17:04:16 +00:00
Jean-Philippe Lang
482d9a4e82 Fix LDAP authentication (#714, broken by r1194).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1199 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-06 17:22:21 +00:00
Jean-Philippe Lang
533994e5ea Adds an application setting to choose whether or not subprojects issues should be displayed by default on the issue list, calendar and gantt (r1178). Default is true.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1198 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-06 08:32:56 +00:00
Jean-Philippe Lang
e951d84584 Add a user preference to choose how comments/replies are displayed: in chronological or reverse chronological order (#589, #776).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1197 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 15:41:54 +00:00
Jean-Philippe Lang
bbe8ea29e8 Display the last 30 days on the activity view rather than the current month.
Number of days can be configured in the application settings.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1196 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 13:44:08 +00:00
Jean-Philippe Lang
fbcdfee622 Trac importer: support database schema for Trac migration (#757 by John Goerzen).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1195 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 12:54:20 +00:00
Jean-Philippe Lang
a70737ad59 Fixed "LdapError: invalid binding information" when no username/password are set on the LDAP account (#764).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1194 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 12:43:14 +00:00
Jean-Philippe Lang
745fec76d0 Fixes #773: Changeset block is smashing the update frame on issues/show.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1193 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 11:59:56 +00:00
Jean-Philippe Lang
1eca3947a1 Reversed versions ordering on files list (closes #763).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1192 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 11:54:54 +00:00
Jean-Philippe Lang
d09f7d73b3 Added jsp mime type.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1191 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 11:42:59 +00:00
Jean-Philippe Lang
c61424e57a Display wiki syntax quick ref link within the jstoolbar (closes #629, #767).
Added named links syntax on quick ref (closes #766, #778).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1190 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 11:14:35 +00:00
Jean-Philippe Lang
b0754ca720 Fixes migration 87 error when running MySQL with STRICT_TRANS_TABLES on (#771).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1189 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 09:16:19 +00:00
Jean-Philippe Lang
4f9f3097d9 Fixes #765: Date pickers don't work on issues' bulk edit view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1188 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 09:06:00 +00:00
Jean-Philippe Lang
d8c97b32dd Fixes #780: Redmine fails to start with a const_missing error on Redmine::MenuManager::MenuItem::GLoc (occurs when a Redmine plugin is loaded before GLoc).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1187 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 09:01:37 +00:00
Jean-Philippe Lang
918937c873 Translations updates:
* Finnish (Antti Perkiömäki)
* Russian (Michael Pirogov)
* Chinese Traditional (shortie lo)
* Japanese (Satoru Kurashiki)
* Korean (Jongyoon Choi)
* Simplified Chinese (chaoqun zou)
* German (Thomas Löber)

Fixed zh and zh-tw encoding in PDF (chaoqun zou).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1186 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 08:54:26 +00:00
Jean-Philippe Lang
942091f9e8 Display links to Atom feeds (closes #496, #750).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1185 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-05 08:25:22 +00:00
Jean-Philippe Lang
8ea2ecb983 Fixed #759: Can not view a project without View time entries permission (broken by r1176).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1184 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-01 20:09:57 +00:00
Jean-Philippe Lang
7ee55562ff Fixed: fetch_changesets fails on commit comments that close 2 duplicates issues.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1183 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-03-01 09:00:02 +00:00
Jean-Philippe Lang
c01c64e978 Let the user choose when deleting issues with reported hours (closes #734, #71):
* to delete the hours
* to assign the hours to the project
* to reassign the hours to another issue


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1182 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-29 22:54:07 +00:00
Jean-Philippe Lang
87742f23ed Login field name changed to username (#755).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1181 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-29 21:18:35 +00:00
Jean-Philippe Lang
9daf39ec52 Adds an optional description to attachments.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1180 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-29 19:46:58 +00:00
Jean-Philippe Lang
4b15dc10c1 Fixed: Multiple "new" statuses in filing new ticket (closes #751).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1179 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-28 22:00:56 +00:00
Jean-Philippe Lang
b6bd5c7f12 Include subprojects on the issue list, calendar and gantt by default.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1178 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-28 21:57:03 +00:00
Jean-Philippe Lang
1ddb59df2a Fixed JournalControllerTest.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1177 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-27 23:01:35 +00:00
Jean-Philippe Lang
200842ba5e Propagates time tracking to the parent project (closes #433). Time report enhancements.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1176 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-27 20:50:19 +00:00
Jean-Philippe Lang
421d420311 Trac importer fix:
* error when trying to convert too long ticket ids (closes #719)

Enhancements (#619):
* Trac guide wiki pages skipped
* wiki attachments migration added

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1175 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-26 19:47:29 +00:00
Jean-Philippe Lang
8531e176aa Do not send an email with no recipient, cc or bcc (closes #743).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1174 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-26 18:30:24 +00:00
Jean-Philippe Lang
328df74dd1 Adds date range filter and pagination on time entries detail view (closes #434).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1173 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-26 18:15:58 +00:00
Jean-Philippe Lang
792b7f30e3 Menus items:
* fixed broken translation when a plugin is installed (closes #649)
* small fix to the plugin API: options parameter added to Redmine::Plugin#menu

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1172 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-22 18:19:00 +00:00
Jean-Philippe Lang
b0bb41ad35 Fixed: Issue custom fields "required" flag not stored (broken by r1090). Closes #715.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1171 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-22 17:48:37 +00:00
Jean-Philippe Lang
b935aebd99 Fixed: LDAP authentication without password may be possible (#714).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1169 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-22 17:26:53 +00:00
Jean-Philippe Lang
ade572048a Roadmap enhancements (closes #697, #698):
* separate related issues from wiki contents
* leading h1 in version wiki pages is hidden (done using css, won't work with IE6)
* smaller wiki headings
* xhtml validation

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1168 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-21 19:49:47 +00:00
Jean-Philippe Lang
7d10755072 Fixed: "undefined method 'textilizable'" error on email notification when running Repository#fetch_changesets from the console.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1167 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-21 19:30:27 +00:00
Jean-Philippe Lang
3f4a8469ac Added 'estimated time' in the csv export of the issue list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1166 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-21 17:57:00 +00:00
Jean-Philippe Lang
d461363d27 Fixed: Adding time when Updating a ticket is gone (closes #701).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1165 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-21 17:50:33 +00:00
Jean-Philippe Lang
948097bc4d Do not clear issue relations when moving an issue to another project if cross-project issue relations are allowed (closes #696).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1164 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-21 17:45:49 +00:00
Jean-Philippe Lang
09bd61da74 Order issues by id on the roadmap.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1163 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-18 18:28:37 +00:00
Jean-Philippe Lang
652dc1a73a Fixed: auto closing of duplicates doesn't work.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1162 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-17 15:02:54 +00:00
Jean-Philippe Lang
e5daf25618 Fixes:
* email notifications: host name is missing in generated links (#639, #201)
* email notifications: referenced changesets, wiki pages, attachments... are not turned into links (only ticket ids are)
* attachment links and inline images don't work in issue notes

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1161 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-17 14:17:20 +00:00
Jean-Philippe Lang
5d6d0136c1 Fixes for wiki_syntax.html (#678) by Thomas Löber.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1160 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 21:24:12 +00:00
Jean-Philippe Lang
d69a05a6ee Rescue and display an error message when trying to delete a role that is in use.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1159 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 21:05:10 +00:00
Jean-Philippe Lang
33493f8010 Mantis importer: do not duplicate Mantis username in firstname and lastname if realname is blank.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1158 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 19:28:24 +00:00
Jean-Philippe Lang
a798a1ac4d Removed fragment caching on gantt and calendar.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1157 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 18:28:46 +00:00
Jean-Philippe Lang
53a04b0a44 Fixed: CVS repository doesn't work if port is used in the url (#653).
Added functional tests for CVS adapter.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1156 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 18:09:26 +00:00
Jean-Philippe Lang
0153954ebb Added a simple rake task to fetch changesets from the repositories:
rake redmine:fetch_changesets

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1155 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 16:25:58 +00:00
Jean-Philippe Lang
153c4c242d Atom feeds:
* prevent duplicate entry ids for issue changes
* prevent empty email in author element

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1154 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 16:20:35 +00:00
Jean-Philippe Lang
0582337372 Added:
* the 'include' macro to include a wiki page
* macro escaping support (with exclamation mark)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1153 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 15:34:17 +00:00
Jean-Philippe Lang
1c8cf4ef83 Added the following permissions (#527, #585, #627):
* edit_issue_notes: let user edit any notes
* edit_own_issue_notes: let user edit his own notes only

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1152 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 13:19:33 +00:00
Jean-Philippe Lang
abb0b15407 Added translation support for project modules names and a few other strings.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1151 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 10:15:19 +00:00
Jean-Philippe Lang
384a444cee Fix grammar error in e-mail footer (closes #673).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1150 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-16 09:14:59 +00:00
Jean-Philippe Lang
38307c0979 Added Ukrainan translation (Natalia Konovka & Mykhaylo Sorochan).
Translation updates:
* Lithuanian (Sergej Jegorov)
* Russian (Michael Pirogov)
* Traditional Chinese (Shortie Lo)
* Finnish (Antti Perkiömäki)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1149 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-15 17:47:19 +00:00
Jean-Philippe Lang
96b78fdae5 Fix applied to ruby-net-ldap (#608).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1148 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-15 17:22:21 +00:00
Jean-Philippe Lang
377a45ae1a Slight changes to calendar and activity h2 titles.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1147 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-15 17:04:27 +00:00
Jean-Philippe Lang
29e297d273 Make Mantis importer preserve bug ids.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1146 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-15 16:41:44 +00:00
Jean-Philippe Lang
71d089c833 Escape titles in activity view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1145 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-14 21:17:28 +00:00
Jean-Philippe Lang
8adb320978 Fixed a bug in localization introduced by r1131 (anonymous users inherit the language of the first anonymous user).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1144 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-13 20:47:27 +00:00
Jean-Philippe Lang
0b6a010a12 Translation for various hard-coded strings (#577).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1143 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-12 22:43:37 +00:00
Jean-Philippe Lang
4dc7f662e3 Added issue subject to the time entries view and subject + tracker to the csv export (#616). Default order on date column set to desc.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1142 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-12 21:43:54 +00:00
Jean-Philippe Lang
a2626bbccf Fixed: not null constraints not removed with Postgresql.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1140 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-12 21:11:16 +00:00
Jean-Philippe Lang
616899d879 Fixed: empty status list shouldn't be displayed when the user can not change the status.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1139 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-12 18:33:38 +00:00
Jean-Philippe Lang
30a7314b86 Fixed: wiki and changeset links not displayed when previewing issue description or notes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1138 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-12 18:31:15 +00:00
Jean-Philippe Lang
c5d998528f The following menus can now be extended by plugins: top_menu, account_menu, application_menu (empty by default).
Sligth layout change: links in the top menu are now li elements.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1137 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-12 17:58:46 +00:00
Jean-Philippe Lang
93ef8b7f77 Replaced window.hash= by Element.scrollTo()
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1136 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-11 20:45:46 +00:00
Jean-Philippe Lang
15ed53cf17 Footer update.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1135 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-11 18:08:36 +00:00
Jean-Philippe Lang
5152771fdd Fixed: 404 error when selecting an other project on issues/move.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1134 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-11 18:06:38 +00:00
Jean-Philippe Lang
913a806f90 Fixed: context menu not available if the initial issue list is empty.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1133 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-11 17:59:41 +00:00
Jean-Philippe Lang
d859d38dd9 Translation updates:
* Finnish (Antti Perkiömäki, #612)
* Russian (Michael Pirogov, #622)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1132 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-10 14:24:51 +00:00
Jean-Philippe Lang
14b3d6d012 Fixed: Anonymous users may not see the issue list headers in the correct language.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1131 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-10 14:14:18 +00:00
Jean-Philippe Lang
4155c97222 Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once.
There are 2 ways to select a set of issues on the issue list:
* by using checkbox and/or the little pencil that will select/unselect all issues (#567)
* by clicking on the rows (but not on the links), Ctrl and Shift keys can be used to select multiple issues

Context menu was disabled on links so that the default context menu of the browser is displayed when right-clicking on a link (#545).
All this was tested with Firefox 2, IE 6/7, Opera 8 (use Alt+Click instead of Right-click) and Safari 2/3.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1130 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-10 13:17:41 +00:00
Jean-Philippe Lang
43a6f312ed Merged IssuesController #edit and #update into a single actions.
Users with 'edit issues' permission can now update any property including custom fields when adding a note or changing the status (#519, #581, #587).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1129 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-09 16:11:18 +00:00
Jean-Philippe Lang
6d109258c9 Added a few extensions/mimetypes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1128 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-07 18:06:35 +00:00
Jean-Philippe Lang
9a2ec76a81 Mantis importer: few fixes in user mapping.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1127 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-06 20:43:31 +00:00
Jean-Philippe Lang
c80c1e1ead Create a journal and send an email when an issue is closed by commit (#609).
The redmine user is found using the committer username or email. Otherwise, the journal is created with anonymous user.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1126 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-06 20:02:30 +00:00
Jean-Philippe Lang
943ba3e34f Trac importer: handle nil usernames.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1125 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-06 19:05:42 +00:00
Jean-Philippe Lang
68d3305ae2 Fixed settings.yml syntax (yaml parsing fails with JRuby 1.0.3: #606).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1124 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-06 18:56:52 +00:00
Jean-Philippe Lang
fde2a497da Activity test fix (r1120).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1123 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-05 18:50:21 +00:00
Jean-Philippe Lang
14b2d3f4b9 Slight change to the issue added/updated email templates.
Translations updates:
* Simplified Chinese (Liang Jin)
* Bulgarian (Nikolay Solakov)
* Lithuanian (Sergej Jegorov)
* Traditional Chinese (Shortie Lo)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1122 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-05 18:38:05 +00:00
Jean-Philippe Lang
54ff294da1 More appropriate default sort order on sortable columns.
Sortable column added on issue subject (#580).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1121 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-05 17:28:02 +00:00
Jean-Philippe Lang
80a60247f5 Slight changes to the activity view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1120 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-04 19:37:23 +00:00
Jean-Philippe Lang
a3dda6dc4a Use Postgresql's reset_pk_sequence in Trac importer to reset issue id sequence (#595).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1119 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-04 18:01:38 +00:00
Jean-Philippe Lang
4e244be21c Slight changes on users list view and hide Anonymous user.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1118 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 19:53:52 +00:00
Jean-Philippe Lang
09cfef094c New icons for the wiki toolbar (from http://www.famfamfam.com/lab/icons/silk/).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1117 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 18:05:26 +00:00
Jean-Philippe Lang
9c451ac157 Set wiki class to issue notes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1116 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 17:34:31 +00:00
Jean-Philippe Lang
5dd3c239d3 Fixed: error when uploading a file with no content-type specified by the browser.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1115 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 17:24:58 +00:00
Jean-Philippe Lang
0beafecd3b Fixed #208: Issue list does not scroll up when you click next
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1114 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 16:21:51 +00:00
Jean-Philippe Lang
2920daf2c8 Do not use RedCloth's glyphs (#210).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1113 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 15:34:58 +00:00
Jean-Philippe Lang
c3d909e0cc Slight style changes on issue associated changesets list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1112 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 15:15:52 +00:00
Jean-Philippe Lang
1ecef3a95a ProjectsController#add_news moved to NewsController#new.
Preview added when adding/editing a news (#590).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1111 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 14:38:04 +00:00
Jean-Philippe Lang
b124501a4e Add 'Author' to the available columns for the issue list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1110 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 14:02:23 +00:00
Jean-Philippe Lang
225637c5dc Translations updates (#254, #255, #260):
* Traditional Chinese (Shortie Lo)
* German (Thomas Löber)
* Russian (Michael Pirogov)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1109 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-03 13:54:59 +00:00
Jean-Philippe Lang
0123dc3651 Do not authorize project identifier with numbers only (would be interpreted as the project id in urls).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1108 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-02 15:51:48 +00:00
Jean-Philippe Lang
12c0f5f66e Do not show Roadmap menu item if the project doesn't define any versions.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1107 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-02 11:08:04 +00:00
Jean-Philippe Lang
45b69c4a65 Fixed an error on issue feeds.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1106 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-02 10:54:31 +00:00
Jean-Philippe Lang
bea49ae245 Administrators can edit issue notes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1105 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-02-02 10:50:31 +00:00
Jean-Philippe Lang
4abb82fd7b Fixed RepositoriesController: undefined local variable or method `show_error' (broken by r1094).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1104 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-25 10:55:16 +00:00
Jean-Philippe Lang
79f92a675a User display format is now configurable in administration settings.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1103 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-25 10:31:06 +00:00
Jean-Philippe Lang
3d5d1a38e3 Translations updates:
* Russian (Michael Pirogov)
* Finnish (Antti Perkiömäki)
* Traditional Chinese wiki toolbar (Shortie Lo)
* German wiki toolbar (Thomas Löber)


git-svn-id: http://redmine.rubyforge.org/svn/trunk@1102 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-24 18:31:02 +00:00
Jean-Philippe Lang
e13f49d919 Prevent unexpected nil in custom value validation.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1101 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-24 18:15:38 +00:00
Jean-Philippe Lang
7a1e928b8d Mantis importer:
* do not truncate projects descriptions
* encode attachment filenames to utf8

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1100 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-23 22:31:26 +00:00
Jean-Philippe Lang
b0f3de5c3b Fixed: PostgreSQL issues_seq_id not updated when using Trac importer.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1099 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-23 22:19:24 +00:00
Jean-Philippe Lang
2247700f24 Fixed: Incorrect filtering for unset values when using 'is not' filter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1098 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-23 20:07:17 +00:00
Jean-Philippe Lang
d8ac6d2b79 Issue properties below the description textarea.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1097 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-23 19:58:11 +00:00
Jean-Philippe Lang
2d9e669e85 Added preview for issue notes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1096 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-23 18:21:42 +00:00
Jean-Philippe Lang
d54ba39e7a Fixed: can not lock a topic when creating it.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1095 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-23 17:48:48 +00:00
Jean-Philippe Lang
91dc13f4b2 Show explicit error message when the scm command failed (eg. when svn binary is not available).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1094 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-23 17:25:11 +00:00
Jean-Philippe Lang
97e7432ce6 Fixed migration 87 (mysql: TEXT column can't have a default value).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1093 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-22 17:17:52 +00:00
Jean-Philippe Lang
dad5f6d403 Fixed search with all words (broken in r994).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1092 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-21 18:52:45 +00:00
Jean-Philippe Lang
c65ab7c0f2 Missing migration for r1090.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1091 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 23:38:55 +00:00
Jean-Philippe Lang
d6bfb7fa4d Added default value for custom fields. Fixed javascript on custom field form for project and user custom fields.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1090 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 21:29:51 +00:00
Jean-Philippe Lang
59c5d995c3 Fixed: custom fields empty on issue/edit (broken by r1086).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1089 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 19:45:08 +00:00
Jean-Philippe Lang
df99d8f308 Unlimited and optional project description. The project list will show truncated descriptions only (the first fews lines).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1088 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 18:37:51 +00:00
Jean-Philippe Lang
d5b9dedca2 Added tabindex property on wiki toolbar buttons and 'new category' link.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1087 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 17:36:01 +00:00
Jean-Philippe Lang
0b4a02f607 Display custom fields in two columns on the issue form.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1086 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 17:20:34 +00:00
Jean-Philippe Lang
b6549d763a Added related changesets messages on issue details view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1085 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 15:38:11 +00:00
Jean-Philippe Lang
5e2a01656d Test environments cleanup.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1084 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 14:24:19 +00:00
Jean-Philippe Lang
d79c20c4f2 Fixed: custom field selection is not saved when unchecking them all on project settings
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1083 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 14:01:02 +00:00
Jean-Philippe Lang
889bf388be Fixed: error when removing a project member (postgresql and sqlite only).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1082 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 13:53:45 +00:00
Jean-Philippe Lang
16e9ffce0d Added a 'New issue' link in the main menu (accesskey 7).
The drop-down lists to add an issue on the project overview and the issue list are removed.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1081 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 13:07:19 +00:00
Jean-Philippe Lang
44ac1a0deb ProjectsController#add_issue moved to IssuesController#new.
Tracker can now be changed/selected on the new issue form. This action can be invoked without the tracker_id parameter (the first enabled tracker will be used by default).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1080 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 11:30:57 +00:00
Jean-Philippe Lang
1b002983c3 Display the issue status in the email subject only if the status was actually changed.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1079 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 10:42:16 +00:00
Jean-Philippe Lang
1535ac1220 Fixed: when changing the status of an issue, the email subject contains the previous status of the issue.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1078 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-20 09:49:25 +00:00
Jean-Philippe Lang
2a945f794f Wiki toolbar Russian and Czech translations (Michael Pirogov).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1077 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-19 12:29:41 +00:00
Jean-Philippe Lang
0faa4568a0 Highlight the current item of the main menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1076 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-19 11:53:43 +00:00
Jean-Philippe Lang
3e031b4243 Fixed: locked users should not receive email notifications.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1075 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-17 19:58:03 +00:00
Jean-Philippe Lang
32b9bf0ef2 Added i18n support to the jstoolbar (only english and french are actually translated).
Translations can be found in public/javascripts/jstoolbar/lang/

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1074 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-17 18:39:17 +00:00
Jean-Philippe Lang
1c5a9b1773 Prettier tabs for settings views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1073 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-17 17:43:54 +00:00
Jean-Philippe Lang
061977d77d Fixed: typo in en.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1072 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-17 17:40:45 +00:00
Jean-Philippe Lang
049051103b On the calendar, the gantt and in the Tracker filter on the issue list, only active trackers of the project (and its sub projects) can be selected.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1071 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-16 21:27:48 +00:00
Jean-Philippe Lang
18066ba8bf Added a couple of mime types so that corresponding files can be viewed in the browser.
Added a simple (and not perfect) CodeRay scanner for php.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1070 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-16 20:45:13 +00:00
Jean-Philippe Lang
ad25d15d6c Fixed error on migration 85 with Oracle (index name can not be more than 30 characters long).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1069 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-15 20:40:59 +00:00
Jean-Philippe Lang
e228110614 Lithuanian translation added (Sergej Jegorov).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1068 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-15 19:03:17 +00:00
Jean-Philippe Lang
8a39862b19 Fixed: issue queries can not use custom fields marked as 'for all projects' in a project context.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1067 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-15 18:31:45 +00:00
Jean-Philippe Lang
bf3066d698 Fixed: Date custom fields not displayed as specified in application settings.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1066 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-15 18:30:21 +00:00
Jean-Philippe Lang
35c17355fb Fixed: issue filters may be lost when paginating after r1026.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1065 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-15 18:18:49 +00:00
Jean-Philippe Lang
702b521b45 Redmine links can be used to link to documents, versions and attachments.
For now, attachments of the current object can be referenced only (if you're on an issue, it's possible reference attachments of this issue only).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1064 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-15 18:12:12 +00:00
Jean-Philippe Lang
4e1e5985a1 Wiki toolbar improvements (mainly for Firefox).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1063 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-13 18:39:37 +00:00
Jean-Philippe Lang
8b710cf9de Do not show sticky and locked checkboxes when replying to a message.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1062 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-13 18:33:55 +00:00
Jean-Philippe Lang
df30e18a8c Added missing wiki div on news/index and news/show.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1059 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-12 16:26:37 +00:00
Jean-Philippe Lang
64eaf328ea Fixed: wrong url for wiki syntax pop-up when Redmine urls are prefixed.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1058 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-12 14:54:26 +00:00
Jean-Philippe Lang
941f9bf3dd Non-ascii attachement filename fix for IE.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1053 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-10 22:42:41 +00:00
Jean-Philippe Lang
a39f655a7c Added details by assignees on issue summary view (Hans Yoon).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1052 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-10 19:20:36 +00:00
Jean-Philippe Lang
84cdc8f2bc Translations:
* Finnish added (Antti Perkiömäki)
* Traditional Chinese updated (Shortie Lo)
* Russian updated
* Polish updated (Mariusz Olejnik)
* Korean updated (Hans Yoon)
* Japanese calendar fix (Nobuhiro Imai)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1051 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-10 18:34:14 +00:00
Jean-Philippe Lang
b2b56adbfa Fixed: Themes are not applied with Rails 2.0
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1047 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-07 20:14:50 +00:00
Jean-Philippe Lang
a80dbc49b1 Admin settings screen split to tabs.
Email notification options moved to this view as a tab and LDAP list is accessible from the 'Authentication' tab.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1046 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-06 20:24:26 +00:00
Jean-Philippe Lang
78d9ae9754 Fixed: crash when fetching Mercurial changesets if changeset[:files] is nil (same fix as r921).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1045 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-06 17:33:41 +00:00
Jean-Philippe Lang
3d920c13b4 wrapper div added to the layout.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1044 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-06 17:28:20 +00:00
Jean-Philippe Lang
976a31e941 Merged IssuesController change_status and add_note actions.
The 'Change status' specific form removed and now accessible from issue/show view with no additional request (click on 'Update' to show the form).
The 'Change issue status' permission is removed. To change the status, the user just needs to have either 'Edit' or 'Add note' permissions and some workflow transitions allowed.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1043 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-06 17:06:14 +00:00
Jean-Philippe Lang
4a729036bf Prevent 'has already been taken' error messages for user login and email if these fields are left empty.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1042 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-06 13:09:23 +00:00
Jean-Philippe Lang
c9fd7513ed Default configuration data can now be loaded from the administration screen.
A message is automatically displayed on this screen if roles, trackers,... have not been configured yet.
The rake task is still available and the data loading code is wrapped in a transaction.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1040 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-05 11:33:49 +00:00
Jean-Philippe Lang
8d9b04865b Fixed Serbian lang file.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1039 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-04 20:03:31 +00:00
Jean-Philippe Lang
4024f4ac39 Updated Serbian translation (Dragan Matic).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1038 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-04 19:07:16 +00:00
Jean-Philippe Lang
6ae87d7c4c Moved redmine:load_default_data code to a module so that it can be called from the application.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1037 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-04 18:27:05 +00:00
Jean-Philippe Lang
860ff9345f Fixed: private projects name are displayed on account/show even if the current user doesn't have access to these private projects.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1036 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-04 18:02:34 +00:00
Jean-Philippe Lang
bd85c0cbb1 Fixed: table of content not rendered properly when used in an issue or document description.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1035 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-04 17:55:08 +00:00
Jean-Philippe Lang
832c7eaaa5 Fixed: undefined local variable or method 'log' in CvsAdapter when a cvs command fails.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1034 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-03 18:28:14 +00:00
Jean-Philippe Lang
b21e85b6dc Updated Spanish translation (Gumer Coronel Pérez).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1033 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-03 18:10:52 +00:00
Jean-Philippe Lang
3e0acc0b7e Slight improvements to the browser views.
ApplicationHelper#set_html_title replaced by html_title with arguments and can be called several times in views to append elements to the title.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1032 e93f8b46-1217-0410-a6f0-8f06a7374b81
2008-01-02 22:41:53 +00:00
Jean-Philippe Lang
636579b17d Fix query management broken by r1027.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1031 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-31 12:37:32 +00:00
Jean-Philippe Lang
97f0da0b1a Moved login and logout links to ApplicationHelper methods for easier customization.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1030 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-30 11:44:46 +00:00
Jean-Philippe Lang
9072753489 Moved current user management to a dedicated method for modularity.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1029 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-30 10:51:34 +00:00
Jean-Philippe Lang
66420fe4b7 TabularFormBuilder moved out of application_helper.rb
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1028 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-30 10:48:11 +00:00
Jean-Philippe Lang
5bc7dc77e2 Do not store query object in session but id or filters only. This allows to use Rails 2.0 cookie based sessions.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1027 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-30 10:46:09 +00:00
Jean-Philippe Lang
9a1b46fe42 New setting added to specify how many objects should be displayed on most paginated lists.
Default is: 25, 50, 100 (users can choose one of these values).
If one value only is entered in this setting (eg. 25), the 'per page' links are not displayed (prior behaviour).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1026 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-29 11:36:30 +00:00
Jean-Philippe Lang
7eec539222 Fixed r1024: context submenus on the issue list don’t show up with IE6.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1025 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-29 10:43:33 +00:00
Jean-Philippe Lang
7f3c516940 Fixed: context submenus on the issue list don't show up with IE6.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1024 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-28 21:58:33 +00:00
Jean-Philippe Lang
3ff95e4031 Fixed 'export to' links positioning on wiki page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1023 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-22 12:47:23 +00:00
Jean-Philippe Lang
bb8d360188 Set doctype to transitional. Fixed a few non matching tags in views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1022 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-21 18:01:02 +00:00
Jean-Philippe Lang
9595029709 Trunk version changed to 0.6.devel
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1021 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-20 19:44:16 +00:00
Jean-Philippe Lang
31c6ebb310 Added wiki annotate view. It's accessible for each version from the page history view.
Slight style change: pre-wrap added on file/diff contents.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1020 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-20 19:10:24 +00:00
Jean-Philippe Lang
3d5381b24b Do not run Mercurial functional tests if the test repository is not set up.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1019 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-19 22:14:03 +00:00
Jean-Philippe Lang
a456225852 Add email notification to IssuesController#edit.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1018 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-19 22:09:31 +00:00
Jean-Philippe Lang
5f871e9657 Fixed: Textile image with style attribute cause internal server error.
Also added tests for inline images with attributes and moved auto_link and auto_mailto rules after textile rules.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1017 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-19 21:06:06 +00:00
Jean-Philippe Lang
bf3b2ec973 Change status select box default to current status (Rocco Stanzione).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1016 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-19 20:23:03 +00:00
Jean-Philippe Lang
49bdf62243 Add autoscroll div for each file diff.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1015 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-19 20:19:48 +00:00
Jean-Philippe Lang
e219af1fbd Ignore empty diffs.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1014 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-19 20:11:44 +00:00
Jean-Philippe Lang
4a2efa9252 Ported r1009 from 0.6-stable branch.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1013 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-18 19:07:54 +00:00
Jean-Philippe Lang
8e00f57a88 Moved ProjectsController#list_documents and add_document to DocumentsController#index and new.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1011 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-18 18:50:41 +00:00
Jean-Philippe Lang
524cd689cf Project identifier is now used in URLs (instead of project id).
URLs with a project id will still be recognized.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1007 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-17 21:00:56 +00:00
Jean-Philippe Lang
b4eafd9ea8 Changes for 0.6.2 release.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1004 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-16 14:03:26 +00:00
Jean-Philippe Lang
2bcd448dda Updated Japanese translation (Satoru Kurashiki).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1003 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-16 13:33:15 +00:00
Nicolas Chuche
1af9c47a27 bug when using apache authentication method
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1002 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-15 12:23:39 +00:00
Jean-Philippe Lang
ea35fff5bf SCM adapters: moved Errno::ENOENT exception rescuing to the abstract adapter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1001 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-15 12:14:40 +00:00
Jean-Philippe Lang
124ef65c1f Fixed warning: toplevel constant User referenced by WikiContent::User
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1000 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-15 11:57:48 +00:00
Jean-Philippe Lang
361c50c1f4 Added some functional tests (wiki).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@999 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-15 11:57:06 +00:00
Jean-Philippe Lang
27d6334afa Fixed: Unable to create a wiki (Rails 2.0 compatibility).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@998 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 22:00:03 +00:00
Jean-Philippe Lang
963b1283c2 Fixed Bazaar test repository path.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@997 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 21:49:23 +00:00
Jean-Philippe Lang
777edc13c1 Fixed: can not save numeric, date and boolean custom fields (broken by r994).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@996 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 21:47:57 +00:00
Jean-Philippe Lang
d1a3fbea40 Fixed Trac importer error with Rails 2.0: readonly? is defined by ActiveRecord.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@995 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 21:31:30 +00:00
Jean-Philippe Lang
58610ec52a Search engine: issue custom fields can now be searched.
Each issue custom field (excepting numeric, date and boolean fields) can be marked as "Searchable" (default to false).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@994 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 18:54:55 +00:00
Jean-Philippe Lang
38b185f1dc Fixed: empty lines when displaying repository files with Windows style eol.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@993 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 17:48:11 +00:00
Jean-Philippe Lang
e69631f26c Fixed: missing body closing tag in repository annotate and entry views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@992 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 17:47:30 +00:00
Jean-Philippe Lang
47f399104b Added a Mercurial test repository with unit and functional tests.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@991 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 17:46:45 +00:00
Jean-Philippe Lang
86319feef2 Added ApplicationController#attach_files as a common method to attach files in all actions.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@990 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 17:33:05 +00:00
Jean-Philippe Lang
eb7cbd481e Added some tests for projects controller and helper.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@989 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-14 17:31:24 +00:00
Jean-Philippe Lang
17c7886791 Removed unused UsersController#destroy.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@988 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-13 18:53:34 +00:00
Jean-Philippe Lang
48949f979a Added some functional tests and a CVS test repository.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@987 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-13 18:52:09 +00:00
Jean-Philippe Lang
86d756d22d News comments are now textilized.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@986 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 22:57:20 +00:00
Jean-Philippe Lang
ab4ff48abc Added /coverage and /vendor/rails to svn-ignore.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@985 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 22:23:34 +00:00
Jean-Philippe Lang
63ef594033 Added some functional tests (issues).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@984 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 22:22:33 +00:00
Jean-Philippe Lang
bd8eded670 Fixed: 500 error when validation fails on issue edition with no custom fields.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@983 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 21:10:04 +00:00
Jean-Philippe Lang
d5cc40c9b6 Fixed: calendar and gantt broken with Rails 2.0
git-svn-id: http://redmine.rubyforge.org/svn/trunk@982 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 21:03:36 +00:00
Jean-Philippe Lang
76ed8cc200 Added some functional tests (projects and repositories).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@981 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 20:56:22 +00:00
Jean-Philippe Lang
3539bef96b Updated Chinese translation (Shortie Lo).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@980 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 20:49:02 +00:00
Jean-Philippe Lang
e29539df9c Fixed: 'assigned to me' filter broken.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@979 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-12 20:45:32 +00:00
Jean-Philippe Lang
7e9c454478 Fixed: 'LDAP account password is too long' error when leaving the field empty on creation.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@977 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-10 20:58:24 +00:00
Jean-Philippe Lang
c00b8fd12e Doc and version changes for 0.6.1 release.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@976 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-10 18:39:57 +00:00
Jean-Philippe Lang
6d9490ddcc Merged Rails 2.0 compatibility changes.
Compatibility with Rails 1.2 is preserved.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@975 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-10 17:58:07 +00:00
Jean-Philippe Lang
f58db70bde More detailed html title on several views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@964 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 18:42:40 +00:00
Jean-Philippe Lang
51adc242a3 Updated Polish translation (Mariusz Olejnik).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@963 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 17:58:44 +00:00
Jean-Philippe Lang
7fae4b0892 Bazaar adapter: fixed log with partial revisions parsing.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@962 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 17:51:54 +00:00
Jean-Philippe Lang
6239e319ac Fixed versions/show layout with IE.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@961 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 15:02:57 +00:00
Jean-Philippe Lang
60c82a03db Fixed drop down lists overflow on My account.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@960 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 14:57:17 +00:00
Jean-Philippe Lang
36c0ab196c Added Traditional Chinese translation (by Shortie Lo).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@959 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 14:43:07 +00:00
Jean-Philippe Lang
a7c2b63fb6 Transaction and performance improvement on workflow copy when creating a new tracker.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@958 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 13:35:38 +00:00
Jean-Philippe Lang
5e38bd9363 Performance improvement on workflow setup screen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@957 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 11:19:30 +00:00
Jean-Philippe Lang
a79cf8d574 Fixed a parenthesis warning in news/show.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@956 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 10:27:52 +00:00
Jean-Philippe Lang
3c44aac1f5 Added version details view accessible from the roadmap.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@955 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-07 10:26:07 +00:00
Jean-Philippe Lang
355289fa67 Roadmap progress bars now differentiate the progress due to closed issues from the open issues progress (2 different colors).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@954 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-05 19:21:25 +00:00
Jean-Philippe Lang
b536f4c657 Restored wiki syntax quick ref pop-up (accessible from wiki/edit).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@953 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-04 18:14:09 +00:00
Jean-Philippe Lang
d00014221e Changesets retrieval optimization on the activity view. Prevents additional query from being executed for each displayed changeset.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@952 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-03 23:05:45 +00:00
Jean-Philippe Lang
3b4cfe0ba8 Added some unit tests for the Bazaar adapter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@951 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-03 19:19:36 +00:00
Jean-Philippe Lang
056e3703da Added Bazaar adapter.
Fixed 'quick jump to a revision' form on the revisions list.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@950 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-03 17:40:43 +00:00
Jean-Philippe Lang
92a23c05bb Project name format limitation removed (name can now contain any character).
Project identifier maximum length changed from 12 to 20.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@949 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-03 10:28:08 +00:00
Jean-Philippe Lang
7d8af70a63 Changed the maximum length of LDAP account to 255 characters.
Added length validations on AuthSource model.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@948 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-02 22:07:56 +00:00
Jean-Philippe Lang
8c65cc4712 Added Annotate/Blame view for Subversion, CVS and Mercurial repositories.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@947 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-02 20:58:02 +00:00
Jean-Philippe Lang
e4724c7626 Trac importer:
* should now support mysql and postgresql Trac database
* minor fixes

git-svn-id: http://redmine.rubyforge.org/svn/trunk@946 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-02 15:09:43 +00:00
Jean-Philippe Lang
6e74a06808 Fixed: error on admin/info if there's more than 1 plugin installed.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@945 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-02 14:20:28 +00:00
Jean-Philippe Lang
bc060b31ae Email notifications are now sent as Blind carbon copy by default. This can be changed in email notifications settings (new setting added).
Emission email address setting moved to the email notifications settings view.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@944 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-02 13:52:16 +00:00
Jean-Philippe Lang
aebcfb1eda When creating a new role, permissions are pre-filled with 'Non member' role permissions.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@943 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-02 12:58:07 +00:00
Jean-Philippe Lang
457c9a8e72 Fixed: svn or ldap password can be found in clear text in the html source in editing mode.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@942 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-01 22:03:45 +00:00
Jean-Philippe Lang
3f2f7153a9 Fixed: Date and time formats defined in settings not applied to the issues CSV export.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@941 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-01 21:34:16 +00:00
Jean-Philippe Lang
f5d68cf688 Fixed a broken link in the SCM browser
git-svn-id: http://redmine.rubyforge.org/svn/trunk@940 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-01 21:33:15 +00:00
Jean-Philippe Lang
81ada666bb 'Assigned to' drop down list is now sorted by user's lastname.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@939 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-01 17:42:26 +00:00
Jean-Philippe Lang
db002edabd * Added links to previous and next revisions on revision view (patch by Cyril Mougel slightly edited)
* Fixed TimelogController#report december error
* Fixed ProjectsControllerTest#test_activity 1st and 2nd day of the month failure

git-svn-id: http://redmine.rubyforge.org/svn/trunk@938 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-12-01 17:15:42 +00:00
Jean-Philippe Lang
3baf086e2d Fixed: 'View all issues' link doesn't work on issues/show.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@937 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-29 20:14:01 +00:00
Jean-Philippe Lang
2cf11bd64e Fixed Mantis importer: projects trackers and modules assignment
Fixed Trac and Mantis importers: roles assignments

git-svn-id: http://redmine.rubyforge.org/svn/trunk@936 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-29 20:08:14 +00:00
Jean-Philippe Lang
bf6e02c739 Search engine: search can be restricted to an exact phrase by using quotation marks (eg. hello "bye bye" can be used to search for "hello" and "bye bye" strings).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@935 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-29 18:33:42 +00:00
Jean-Philippe Lang
233990dac3 * Updated German translation (Thomas Löber)
* Updated Spanish translation (Gumer Coronel Pérez)
* Fixed: test in method project in Attachment Model useless (Cyril Mougel)
* Fixed: public/.htaccess lacks support for mod_fcgid and adds handlers without checking for their existance (Nils Adermann)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@934 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-27 17:20:57 +00:00
Jean-Philippe Lang
c383486d71 Added custom fields marked as "For all projects" to the csv export of the cross project issue list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@933 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-27 17:04:13 +00:00
Jean-Philippe Lang
508b0bbb8e * Updated Spanish translation (Gumer Coronel Pérez)
* Fixed mailer test errors

git-svn-id: http://redmine.rubyforge.org/svn/trunk@932 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-26 18:47:49 +00:00
Jean-Philippe Lang
3937caeb3c Trac importer improvements (by Mat Trudel):
* better support for wiki internal links (still not perfect, but much improved)
* support for unordered lists
* support for most of trac's highlighting tags (underline, bold, etc)
* import progress dots now flush to stdout on every dot, so the import doesn't look frozen
* support for migration of multiple trac instances into a single Redmine install (as separate projects)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@931 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-25 12:11:40 +00:00
Jean-Philippe Lang
f2a12d9eb5 Added user status criteria in Redmine.pm
git-svn-id: http://redmine.rubyforge.org/svn/trunk@930 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-24 16:55:08 +00:00
Jean-Philippe Lang
acad206063 Issue context menu now also available on 'My page'.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@929 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-24 15:16:04 +00:00
Jean-Philippe Lang
f80f04e379 Slight optimization in User#role_for_project.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@928 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-24 15:14:32 +00:00
Jean-Philippe Lang
fde4a42e2a Removed the 12 characters limit on passwords.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@927 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-24 12:52:29 +00:00
Jean-Philippe Lang
29b3614bcb Forums enhancements:
* messages can now be edited/deleted (explicit permissions need to be given)
* topics can be locked so that no reply can be added (only by users allowed to edit messages)
* topics can be marked as sticky so that they always appear at the top of the list (only by users allowed to edit messages)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@926 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-24 12:25:07 +00:00
Jean-Philippe Lang
866e9e2503 Fixed: error on account/register when validation fails.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@925 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-23 23:23:39 +00:00
Jean-Philippe Lang
c21ee95ade * Updated Russian translation (iGor kMeta)
* Fixed front page typo: View all issues instead of View all news (Derek Montgomery)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@924 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-23 18:27:26 +00:00
Jean-Philippe Lang
7704e2d919 Forums: attachments can now be added to replies.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@923 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-22 19:19:47 +00:00
Jean-Philippe Lang
0634591b3d Themes:
* Fixed: themes are not found when running Apache+fastcgi
* Added 'Classic' theme (inspired from the v0.51 design)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@922 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-22 18:03:02 +00:00
Jean-Philippe Lang
5e6fa147da * Fixed: Error when displaying the issue list if a float custom field is marked as 'used as filter'
* Fixed: Mercurial adapter breaks on missing :files entry in changeset hash (James Britt)
* Fixed: Wrong feed URLs on the home page

git-svn-id: http://redmine.rubyforge.org/svn/trunk@921 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-21 18:45:18 +00:00
Jean-Philippe Lang
8d91afc33e Added per-project tracker selection. Trackers can be selected on project settings.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@920 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-20 20:29:03 +00:00
Jean-Philippe Lang
987a5aa221 Anonymous users can now be allowed to create, edit, comment issues, comment news and post messages in the forums.
These permissions need to be explicitly given to the Anonymous role (Admin -> Roles & Permissions -> Anonymous).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@919 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-20 15:40:16 +00:00
Jean-Philippe Lang
99f9aea80a * Referencing issues in commit messages: enter * in 'Referencing keywords' to link any issue id without using keywords.
* Updated Polish translation (Mariusz Olejnik).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@918 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-20 12:07:28 +00:00
Jean-Philippe Lang
deb182337d * Added time zone support: users can select their time zone on their account view.
* Updated Polish translation (Mariusz Olejnik).
* Fixed: Projects should be listed with case mixed.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@917 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-19 22:28:43 +00:00
Nicolas Chuche
a1f3497ec4 * add Redmine.pm to authenticate with mod_perl
* add a --test option in reposman.rb
* change owner right to fit with apache write access to repositories
* add a deprecated warning in reposman.pl


git-svn-id: http://redmine.rubyforge.org/svn/trunk@916 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-18 18:51:48 +00:00
Jean-Philippe Lang
9c9ae21771 There's now 3 account activation strategies (available in application settings):
* activation by email: the user receives an email containing a link to active his account
* manual activation: an email is sent to administrators for account approval (default)
* automatic activation: the user can log in as soon as he has registered

git-svn-id: http://redmine.rubyforge.org/svn/trunk@915 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-18 17:46:55 +00:00
Jean-Philippe Lang
f8aa2dc9b7 'fixed version' field can now be displayed on the issue list.
Category and fixed version fields added to the CSV export.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@914 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-18 15:53:58 +00:00
Jean-Philippe Lang
bb2de53d93 Added an alternate theme which provides issue list colorization based on issues priority.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@912 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-18 14:32:39 +00:00
Jean-Philippe Lang
e2c606e974 Fixed: Update of time entry fails when the issue has been moved to an other project.
Fixed: Error when moving an issue without changing its tracker (Postgresql).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@909 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-17 17:45:21 +00:00
Jean-Philippe Lang
9ad79612fe Roadmap: more accurate completion percentage calculation (done ratio of open issues is now taken into account).
Issues and issues list: 'done ratio' field now displayed as a progress bar.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@908 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-17 15:34:10 +00:00
Jean-Philippe Lang
1469a4c8df Fixed (CVS adapter): changes not recorded when using :pserver string.
Updated Russian js calendar (iGor kMeta).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@907 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-16 21:24:22 +00:00
Jean-Philippe Lang
76cdef46f2 Fixed: localization problem on issue list headers.
Updated Russian translation (iGor kMeta).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@906 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-16 20:46:33 +00:00
Jean-Philippe Lang
e4ce95c3a1 Added a couple of new formats for the 'date format' setting.
Added a 'time format' setting.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@905 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-16 20:26:36 +00:00
Jean-Philippe Lang
4951676172 Added Russian translation (iGor kMeta).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@904 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-15 18:24:18 +00:00
Jean-Philippe Lang
b0a8888e35 Fixed: admin should be able to move issues to any project.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@903 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-14 21:54:16 +00:00
Jean-Philippe Lang
833c7bd659 Fixed: adding an attachment is not possible when changing the status of an issue.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@902 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-12 17:29:41 +00:00
Jean-Philippe Lang
5944696b6d Custom fields can now be reordered.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@901 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-12 17:23:14 +00:00
Jean-Philippe Lang
a727f0d25a Removed hard coded string on 'My account'.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@900 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-12 16:47:07 +00:00
Jean-Philippe Lang
0fe5c7b3e0 Added an option on 'My account' for users who don't want to be notified of changes that they make.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@899 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-12 16:43:49 +00:00
Jean-Philippe Lang
843d04f0e3 Fixed: No mime-types in documents/files downloading
git-svn-id: http://redmine.rubyforge.org/svn/trunk@898 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-12 15:13:42 +00:00
Jean-Philippe Lang
8a8f819d27 Added wiki macros support. 2 builtin macros are defined: hello_world (sample macro that displays the arguments) and macro_list (display the list of installed macros).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@897 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-12 14:36:33 +00:00
Jean-Philippe Lang
a8419c1425 Fixed: error on activity page when displaying a document (undefined method 'author').
git-svn-id: http://redmine.rubyforge.org/svn/trunk@896 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-12 08:00:00 +00:00
Jean-Philippe Lang
362364fd6f Fixed: CSV constant warning
git-svn-id: http://redmine.rubyforge.org/svn/trunk@895 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-11 20:55:27 +00:00
Jean-Philippe Lang
b0bb1baeaa Trac importer: user can now choose between sqlite and sqlite3 adapter for Trac database.
Trac importer: issues and wiki modules are enabled by default for the imported project.
Fixed: 404 error when trying to save a custom query under certain circumstance.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@894 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-09 13:32:14 +00:00
Jean-Philippe Lang
1454a711ca Diff style (inline or side by side) automatically saved as a user preference.
Fixed a Postgres test failure.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@893 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-08 19:14:34 +00:00
Jean-Philippe Lang
fa95501fe5 Added issues status changes on the activity view (initial patch by Cyril Mougel).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@892 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-08 19:00:37 +00:00
Jean-Philippe Lang
a069c4afcf Added forums topics on the activity view (disabled by default).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@891 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-07 23:01:24 +00:00
Jean-Philippe Lang
cc8220dde8 Fixed: error when sorting the messages if there's only one board for the project.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@890 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-07 21:21:12 +00:00
Jean-Philippe Lang
63ceea2e21 Custom fields can now be displayed as columns on the issue list.
Custom fields marked as "for all projects" can be added to the default columns of the issue list (in application settings).
Project specific custom fields can be displayed on custom queries.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@889 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-07 20:42:28 +00:00
Jean-Philippe Lang
ad68a82be1 Moved ProjectsController#list_news to NewsController#index.
Removed FeedsController, issues and news feeds are now handled by issues and news controllers.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@888 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-05 22:22:51 +00:00
Jean-Philippe Lang
8509cf80f0 ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index
git-svn-id: http://redmine.rubyforge.org/svn/trunk@887 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-05 18:38:42 +00:00
Jean-Philippe Lang
26a1ae4808 Fixed: <td> closed with a </th>
git-svn-id: http://redmine.rubyforge.org/svn/trunk@886 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-05 17:33:28 +00:00
Jean-Philippe Lang
040cfa6ae2 Fixed: <<me>> doesn't appear in the drop down filters on a project issue list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@885 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-05 17:30:45 +00:00
Jean-Philippe Lang
d0af24870e Slight changes for 0.6.0 release.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@883 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 13:19:42 +00:00
Jean-Philippe Lang
308118ce97 LDAP authentication: only ask for the user's DN if on-the-fly registration is disabled
git-svn-id: http://redmine.rubyforge.org/svn/trunk@882 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 11:49:03 +00:00
Jean-Philippe Lang
7535c211d5 Removed IssueStatus html_color attribute.
Issue list colorization can be done using a custom theme. Each row is given a class that correspond to the issue status (eg. status-1 where 1 is the status position).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@881 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 11:40:17 +00:00
Jean-Philippe Lang
d46e3a501e Pretty URL for the repository browser (Cyril Mougel)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@880 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 11:20:21 +00:00
Jean-Philippe Lang
d4e47d5d64 Added radio buttons on the documents list to sort documents by category, date, title or author.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@879 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 11:15:04 +00:00
Jean-Philippe Lang
11cf016c58 Added Korean translation (Choi Jong Yoon)
Updated Japanese translation (Go Maeda)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@878 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 10:59:37 +00:00
Jean-Philippe Lang
bd434427e6 Mailer:
* added an application setting to specify the application protocol (http or https) used to generate urls
* added layouts for text and html emails
* no more language specific templates
* urls are now generated using UrlWriter
* the mailer now uses AdvAttrAccessor code style to set email parameters

git-svn-id: http://redmine.rubyforge.org/svn/trunk@877 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 10:43:39 +00:00
Jean-Philippe Lang
4ded4277c5 Activity view now uses events attributes.
Fixed: error on activity feed if it contains a document.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@876 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-28 16:13:39 +00:00
Jean-Philippe Lang
b60bedafc0 Added a missing string to lang files.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@875 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-28 15:07:10 +00:00
Jean-Philippe Lang
9a3d743ae5 Some slight improvements in AJAX errors handling.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@874 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-28 15:04:17 +00:00
Jean-Philippe Lang
0af6f34758 Added the hability to copy an issue.
It can be done from the 'issue/show' view or from the context menu on the issue list.
The Copy functionality is of course only available if the user is allowed to create an issue.
It copies the issue attributes and the custom fields values.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@873 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-28 14:31:59 +00:00
Jean-Philippe Lang
bb4acc02d0 Added AJAX based context menu on the project issue list that provide shortcuts for editing, re-assigning, changing the status or the priority, moving or deleting an issue.
The context menu shows up when right-clicking an issue (Opera users have to use Ctrl + left-click instead since right-click can't be reassigned for this browser).
Works with Firefox 2, IE 7 (not perfect), Opera 9 and Safari 2. IE 6 doesn't display submenus.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@872 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-28 10:55:59 +00:00
Jean-Philippe Lang
d9e6359a83 Fixed: some quotation marks are rendered as strange characters in pdf.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@871 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-26 16:35:27 +00:00
Jean-Philippe Lang
8610b191ae Added "Float" as a custom field format.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@870 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-25 17:38:05 +00:00
Jean-Philippe Lang
01ef9f12c8 Serbian translation added (Dragan Matic)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@869 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-25 16:49:06 +00:00
Jean-Philippe Lang
24ec30b10c SCM browser:
* open subfolders are preserved when collapsing/re-expanding a folder
* prevent a folder to be loaded twice if double-clicked while loading

git-svn-id: http://redmine.rubyforge.org/svn/trunk@868 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-23 20:42:15 +00:00
Jean-Philippe Lang
152a5da64d SCM browser:
* js code improvement (was very slow when collapsing a folder with a lot of entries)
* folder icons changed

git-svn-id: http://redmine.rubyforge.org/svn/trunk@867 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-23 19:07:59 +00:00
Jean-Philippe Lang
295e8c86ab Fixed: error when bulk editing with Postgresql
git-svn-id: http://redmine.rubyforge.org/svn/trunk@866 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-23 17:15:00 +00:00
Jean-Philippe Lang
5d1d778ed5 Removed 'not null' constraint on position fields.
Previous migrations updated for new sqlite databases.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@865 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-22 21:07:29 +00:00
Jean-Philippe Lang
8f7f305f7c Removed 'not null' constraint on position fields.
Previous migrations updated for new sqlite databases.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@864 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-22 21:07:13 +00:00
Jean-Philippe Lang
33003e5b2d SCM browser: directories can now be collapsed and re-expanded with no additional request.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@863 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-22 19:34:21 +00:00
Jean-Philippe Lang
8ca4d35dcc Added a bit of AJAX on the SCM browser (tree view).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@862 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-22 17:45:41 +00:00
Jean-Philippe Lang
b30b6717a2 Commit message parser:
* Fixed: Error when parsing a commit message with duplicate issue identifiers
* Strip referencing and fixing keywords

git-svn-id: http://redmine.rubyforge.org/svn/trunk@861 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-22 16:52:36 +00:00
Jean-Philippe Lang
cedca57620 SVN integration: reposman.rb can now register created repositories in Redmine, so that the administrator doesn't have to enter the repository url in Redmine once it's created.
To do so, use the --url option when running reposman (see reposman help).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@860 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-21 16:26:14 +00:00
Jean-Philippe Lang
0d605006a3 Fixed flashes style for IE6.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@859 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-21 14:30:01 +00:00
Jean-Philippe Lang
a200e97667 * Emails footer can now be customized from the admin interface (Admin -> Email notifications).
* Added html part to all email templates.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@858 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-21 14:10:07 +00:00
Jean-Philippe Lang
2ee11c9089 Added status and priority related classes for each row on the issue list so that a custom theme can colorize issues by priority or status.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@857 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-20 16:47:10 +00:00
Jean-Philippe Lang
01105966d9 More accurate vertical positioning of #main-menu
git-svn-id: http://redmine.rubyforge.org/svn/trunk@856 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-20 15:09:32 +00:00
Jean-Philippe Lang
90d33c3e51 More flexible mail notifications settings at user level. A user has now 3 options:
* notification on any event on all his projects
* notification on any event on selected projects only (if the user belongs to more than 1 project)
* notification only for things that he watches or he is involded in (eg. issues that he watches or he is author or assignee)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@855 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-20 12:47:05 +00:00
Jean-Philippe Lang
eacd050630 Fixed: LDAP authentication crashes if one of the LDAP attributes name is left blank on the LDAP setup screen.
When not checking "On-the-fly" register, the 3 optional fields can now be safely left blank.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@854 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-19 19:36:42 +00:00
Jean-Philippe Lang
0e4e0a795a Fixed: unable to add a file to an issue without entering a note.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@853 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-19 19:09:47 +00:00
Jean-Philippe Lang
ecfc40629f Quote subversion username and password in svn commands.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@852 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-19 17:59:59 +00:00
Jean-Philippe Lang
0006c5f3b0 New document form can be accessed from the document list with no additional request.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@851 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-18 16:59:28 +00:00
Jean-Philippe Lang
3c42abe07e Added the ability to unassign issues with bulk edit.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@850 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-18 16:29:23 +00:00
Jean-Philippe Lang
11cc0a4857 Updated Polish translation (Mariusz Olejnik)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@849 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-18 16:12:13 +00:00
Jean-Philippe Lang
11f7a13971 Removed issue assignment validation to avoid validation failure when updating the issue and if the assignee is no longer a member of the project.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@848 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-18 16:07:36 +00:00
Jean-Philippe Lang
d10e9f1157 Disallow /repositories/diff in robots.txt
git-svn-id: http://redmine.rubyforge.org/svn/trunk@847 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-17 19:18:20 +00:00
Jean-Philippe Lang
f3eeff03c4 Added Hebrew translation (Bob Builder).
Updated Bulgarian translation (Nikolay Solakov).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@846 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-16 20:11:17 +00:00
Jean-Philippe Lang
49eb65e925 Added LDAPS support migration and fixed connection test flash messages.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@845 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-16 19:19:10 +00:00
Jean-Philippe Lang
4c509c9423 Added LDAPS support for LDAP authentication.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@844 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-16 19:09:21 +00:00
Jean-Philippe Lang
9ce5713ee4 Fixed: log is not displayed when browsing a copy in a svn repository.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@843 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-15 18:41:27 +00:00
Jean-Philippe Lang
b9cc65db61 Search engine: added a checkbox to search titles only (usefull when searching on common words).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@842 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-15 16:53:39 +00:00
Jean-Philippe Lang
74ecb37be6 Search engine:
* results are now displayed using different colors for tokens highlighting
* added label tag around "all words" checkbox

git-svn-id: http://redmine.rubyforge.org/svn/trunk@841 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-15 16:15:20 +00:00
Jean-Philippe Lang
7d54215ccb Fixed: 'Issues' table shows weird date for 'Start' and 'Due date' columns
git-svn-id: http://redmine.rubyforge.org/svn/trunk@840 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-15 15:58:53 +00:00
Jean-Philippe Lang
58b67fa914 Added reposman Ruby version (Nicolas Chuche).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@839 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-14 17:27:04 +00:00
Jean-Philippe Lang
f55a5e4572 Slight style change on plugin configuration view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@837 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-13 14:11:06 +00:00
Jean-Philippe Lang
a53c86f063 Removed inconsistent user manual stuff (html/docbook content and controller). Help link now points to the Redmine guide which will be more easy to maintain.
Also removed the useless components directory.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@835 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-13 10:30:24 +00:00
Jean-Philippe Lang
dead6a28f8 Removed translated email templates attachments_added and document_added (no longer usefull).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@834 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-12 18:04:56 +00:00
Jean-Philippe Lang
0682b8cfc4 Added html part to news_added mail.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@833 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-12 17:22:18 +00:00
Jean-Philippe Lang
4b3ff7af50 Moved translated strings of 'register' and 'lost password' mail templates to lang files.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@832 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-12 16:28:06 +00:00
Jean-Philippe Lang
65e05d822a Status can now be updated when bulk editing issues.
Workflow permissions are applied as when changing the status of a single issue. The issue is not saved (and an error is displayed) if the status transition is not allowed for the user.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@831 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-12 15:55:06 +00:00
Jean-Philippe Lang
bce286f458 Fixed: Can not set 'No change' value for commit_fix_done_ratio setting.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@830 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-12 15:11:10 +00:00
Jean-Philippe Lang
b950caa21e Gantt chart:
* now starts at the current month by default
* month count and zoom factor are automatically saved as user preferences

git-svn-id: http://redmine.rubyforge.org/svn/trunk@829 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-11 20:57:37 +00:00
Jean-Philippe Lang
3a0cd55622 Fixed: unable to change how many months are displayed on the gantt.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@828 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-11 20:38:49 +00:00
Jean-Philippe Lang
f7daee47a6 Updated Japanese translation (Go Maeda).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@827 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-11 17:32:09 +00:00
Jean-Philippe Lang
7486125e6d Bulk editing:
* Fixed: Done ratio always set to 0 even if (No change) is selected
* Added mail notifications

git-svn-id: http://redmine.rubyforge.org/svn/trunk@826 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-11 17:20:23 +00:00
Jean-Philippe Lang
ff2e031400 Bulk editing:
* Fixed: Done ratio always set to 0 even if (No change) is selected
* Added mail notifications

git-svn-id: http://redmine.rubyforge.org/svn/trunk@825 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-11 17:20:02 +00:00
Jean-Philippe Lang
2ce184d1de Added revision number in Redmine::VERSION (the revision number is read from .svn/entries if it exists).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@824 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-11 16:59:08 +00:00
Jean-Philippe Lang
3844e4bca8 Fixed: a user not authorized to edit wiki pages gets the edit form if the page doesn't exist. He now gets a 404.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@823 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-10 21:18:10 +00:00
Jean-Philippe Lang
38f540a701 Added custom fields in issue related mail notifications.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@822 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-10 19:43:54 +00:00
Jean-Philippe Lang
5f10cc8673 Added the ability to set the "done ratio" of issues fixed by commit (original path by Nikolay Solakov, slightly edited).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@821 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-10 18:56:59 +00:00
Jean-Philippe Lang
45203143c1 Fixed: Bulk edit doesn't change the category or fixed version properties.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@820 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-10 18:08:49 +00:00
Jean-Philippe Lang
6b63889fcd Added missing string in lang files.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@819 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-10 17:27:14 +00:00
Jean-Philippe Lang
824a67ab5a Added basic Theme support.
Theme is set at application level (in Admin -> Settings).
For now, themes can override stylesheets only (application.css).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@818 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-10 17:17:37 +00:00
Jean-Philippe Lang
2c4647f8c6 Added 'Bulk edit' functionality.
This can be done by clicking on the edit link (little pen icon) at the upper-left corner of the issue list.
Most properties can be set (priority, assignee, category, fixed version, start and due dates, done ratio) and a note can be entered.
Only issues of the current project can be selected for bulk edit (subproject issues can't).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@817 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-09 19:07:19 +00:00
Jean-Philippe Lang
df631e8c06 Set enumeration positions and default priority (Normal) in default configuration data.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@816 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-08 16:58:52 +00:00
Jean-Philippe Lang
ec51cdd0f9 Calendar:
* added an helper and moved the rendering code to a shared partial (used by project calendar and my calendar)
* first day of week can now be set in lang files (general_first_day_of_week)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@815 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-07 20:07:11 +00:00
Jean-Philippe Lang
cdb2781b48 Default encodings for repository files can now be set in application settings (Admin -> Settings -> Repositories encodings).
These encodings are used to convert files content and diff to UTF-8 so that they're properly displayed.
Multiple values are allowed (comma separated).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@814 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-07 15:21:40 +00:00
Jean-Philippe Lang
bb724e75c0 Fixed: improper 0x5c char handling in PDF output (Go Maeda).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@813 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-06 14:27:35 +00:00
Jean-Philippe Lang
5259dec061 Added preview on add/edit issue form.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@812 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-06 08:54:05 +00:00
Jean-Philippe Lang
75c4c4f6b3 Content of projects/add_issue.rhtml and issues/edit.rhtml moved to a shared partial.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@811 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-06 08:08:29 +00:00
Jean-Philippe Lang
fa094a3fe5 Merged IssuesController#export_pdf into IssuesController#show.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@810 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 23:17:49 +00:00
Jean-Philippe Lang
31467731fa Fixed: Migration 71 broken if run with code >= r803 (Enumeration#before_save relies on an attribute added in migration 72).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@809 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 22:53:26 +00:00
Jean-Philippe Lang
57d3dd3b80 Sligth changes on my page issue tables and wiki history, changesets tables.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@808 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 20:34:21 +00:00
Jean-Philippe Lang
26528d1004 'Manage repository' permission requires to be a project member.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@807 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 20:08:46 +00:00
Jean-Philippe Lang
df8945177a Added label tags on role form permission checkboxes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@806 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 20:06:53 +00:00
Jean-Philippe Lang
69c2965051 Fixed: Title with non-ascii characters breaks wiki
git-svn-id: http://redmine.rubyforge.org/svn/trunk@805 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 19:33:25 +00:00
Jean-Philippe Lang
e8971e5f83 Added some accesskeys:
* e => edit
* r => preview
* f => quick search
* 4 => search


git-svn-id: http://redmine.rubyforge.org/svn/trunk@804 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 18:05:41 +00:00
Jean-Philippe Lang
73dba2ac04 Added default value for enumerations.
Only default issue priority is actually used.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@803 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-05 17:44:15 +00:00
Jean-Philippe Lang
fd7910efc9 Added wiki_syntax.html Japanese translation (Motohiro Takayama).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@802 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-04 18:59:21 +00:00
Jean-Philippe Lang
185547af69 Issues sorted by priority position.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@801 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-04 17:15:55 +00:00
Jean-Philippe Lang
c216ab325b Added position on Enumeration model.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@800 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-04 17:04:50 +00:00
Jean-Philippe Lang
479b9b5433 Updated Japanese translation (Go Maeda).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@799 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-03 19:02:07 +00:00
Jean-Philippe Lang
f6f1fee92f Updated Spanish translation (Manuel Garcia Ortega).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@798 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-03 18:59:08 +00:00
Jean-Philippe Lang
a32d6a49c0 Fixed: pagination broken on news list with Opera.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@797 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-03 18:43:38 +00:00
Jean-Philippe Lang
586231067b Fixed: URL with ~ broken in wiki formatting.
All RedCloth quick phrase modifiers are now limited to a single line.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@796 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-03 18:00:50 +00:00
Jean-Philippe Lang
cb8bee3a4e Fixed: can't select columns when creating a new query.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@795 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-03 17:38:18 +00:00
Jean-Philippe Lang
20b4e226fe Performance improvement on calendar and gantt (about 45% on gantt for large number of issues).
Partial issues/_tooltip is replaced by an helper and some translated strings are now cached.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@794 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-03 17:20:04 +00:00
Jean-Philippe Lang
c3e3a1891b Small fix in project activity feed.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@793 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 18:49:31 +00:00
Jean-Philippe Lang
47e7ceacd7 Better handling of external link style assignment.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@792 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 17:45:40 +00:00
Jean-Philippe Lang
48fb20f540 Fixed TOC positionning in wiki pages.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@791 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 16:46:46 +00:00
Jean-Philippe Lang
0fc93a1197 Span caps turned off in textile formatting.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@790 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 15:25:31 +00:00
Jean-Philippe Lang
0f966dbcfd Added label tags on various checkboxes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@789 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 15:22:03 +00:00
Jean-Philippe Lang
ca094446b3 Don't show attributes on role form for built-in roles.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@788 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 14:00:38 +00:00
Jean-Philippe Lang
50096526bc Removed ProjectsController#feeds. This view was incomplete and inconsistent with permissions.
Feeds can still be accessed from the corresponding screens (eg. news feed is accessible from the news view).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@787 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 13:13:04 +00:00
Jean-Philippe Lang
c6e8cf5c21 Moved media print specific styles to application.css (print.css removed).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@786 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 12:36:38 +00:00
Jean-Philippe Lang
c6e61a5f19 Default columns displayed on the issue list can now be selected at application level.
Saved queries can overide this selection.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@785 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 12:04:24 +00:00
Jean-Philippe Lang
514cdacc87 Custom query columns: checkboxes replaced by two selects that let the user specify columns order.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@784 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 11:39:34 +00:00
Jean-Philippe Lang
96b4ac12cb Added a checkbox on custom query form to explicitly say if the query uses default columns or not.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@783 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 10:44:45 +00:00
Jean-Philippe Lang
e5f5671d66 Added the ability to customize columns of a saved query.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@782 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-10-01 08:44:17 +00:00
Jean-Philippe Lang
427b47b4d7 Fixed: Can not authenticate user against LDAP if its DN contains non-ascii characters.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@781 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-30 18:07:23 +00:00
Jean-Philippe Lang
c2220cffcf Added svn command output to error log when SubversionAdapter#entries parsing fails.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@780 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-30 17:38:07 +00:00
Jean-Philippe Lang
3e86dde31e Added Romanian translation (Csongor Bartus).
Fixed a typo in en.yml.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@779 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-30 15:40:20 +00:00
Jean-Philippe Lang
665497f5fb Fixed: Manage pu(b)lic queries typo (Thomas Lecavelier).
As this fix modifies manage_public_queries permission symbol, this permission has to re-entered.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@778 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-30 15:32:03 +00:00
Jean-Philippe Lang
dc74a1780f Updated Japanese language file for calendar (Go Maeda).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@777 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-30 15:26:59 +00:00
Jean-Philippe Lang
3cacd4b3b9 Updated polish translation (Tomasz Gawryl).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@776 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-30 15:23:12 +00:00
Jean-Philippe Lang
b4d66593ef Fixed: Links get chopped by punctuation marks in anchors.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@775 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-30 15:16:58 +00:00
Jean-Philippe Lang
cae547a7ea Redmine acts_as_* plugins moved to vendor/plugins.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@774 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-29 10:37:08 +00:00
Jean-Philippe Lang
f2a5304d64 Sligth changes to wiki views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@773 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-29 10:26:57 +00:00
Jean-Philippe Lang
b64e89daec Native eol property set on config/*
git-svn-id: http://redmine.rubyforge.org/svn/trunk@772 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-27 22:30:57 +00:00
Jean-Philippe Lang
66c8c1e292 Fixed: unable to migrate from an empty database.
(Message model is loaded at startup, which fails if it doesn't exist)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@771 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-27 22:24:09 +00:00
Jean-Philippe Lang
05e27d0d83 Slight style update.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@770 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-27 19:56:33 +00:00
Jean-Philippe Lang
e1bb4a5baa Fixed: Links to other wiki pages in headings get corrupted (class attributes shown).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@769 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-27 19:44:23 +00:00
Jean-Philippe Lang
20aff7cc70 Added wiki index by date.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@768 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-27 19:35:53 +00:00
Jean-Philippe Lang
d823c28484 Updated lang files (:label_result)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@767 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-27 18:52:02 +00:00
Jean-Philippe Lang
a96421019f Search engines now supports pagination.
Results are sorted in reverse chronological order.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@766 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-27 17:28:22 +00:00
Jean-Philippe Lang
d723bea502 Slight changes to the stylesheet and footer.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@765 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-25 16:44:09 +00:00
Jean-Philippe Lang
4b430e6ce2 Added Czech translation (Jan Kadlecek).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@764 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-25 16:37:51 +00:00
Jean-Philippe Lang
19f2853a2a Boards: new message form displayed with no additional request.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@763 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 19:54:48 +00:00
Jean-Philippe Lang
24b000fb24 Slight change to issues/show.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@762 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 19:26:09 +00:00
Jean-Philippe Lang
964c550a60 Sligth stylesheet change.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@761 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 18:59:35 +00:00
Jean-Philippe Lang
650888c73b Added a named route for the home page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@760 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 18:38:45 +00:00
Jean-Philippe Lang
042ef42da0 Fixed projects search.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@759 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 18:08:24 +00:00
Jean-Philippe Lang
42fe6c6e04 Search engine now only searches objects the user is allowed to view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@758 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 17:46:25 +00:00
Jean-Philippe Lang
dfffa0a7f8 Project activity view now only shows what the user is allowed to view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@757 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 17:33:24 +00:00
Jean-Philippe Lang
f3673aff28 Added length validation for IssueCategory name.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@756 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-24 17:15:05 +00:00
Jean-Philippe Lang
dd6f438fd1 Modified history.png
git-svn-id: http://redmine.rubyforge.org/svn/trunk@755 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-23 22:18:45 +00:00
Jean-Philippe Lang
9a360bd574 Fixed: Planning title displayed in the project sidebar even if there is no link below.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@754 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-23 22:00:21 +00:00
Jean-Philippe Lang
dbcf2065b8 Added a sample plugin.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@753 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-23 18:50:53 +00:00
Jean-Philippe Lang
e4f0864e3a Basic plugin support.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@752 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-23 17:19:27 +00:00
Jean-Philippe Lang
a42a115b8f Subversion repository now accepts svn+ssh url.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@751 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-22 21:02:41 +00:00
Jean-Philippe Lang
2b77964468 The news list now shows the full news contents.
News add/edit forms are now accessible with no additional request.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@750 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-22 17:52:43 +00:00
Jean-Philippe Lang
fe7c0d6484 Added polish translation (Tomasz Gawryl).
Added a gloc task to update lang files based on the english file content.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@749 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-22 14:56:09 +00:00
Jean-Philippe Lang
384cbadce6 Fixed: error in calendar french translation (Thomas Lecavelier).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@748 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-22 14:12:44 +00:00
Jean-Philippe Lang
827e998afe Application layout refactored.
The project menu is now the main menu.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@747 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-22 13:17:49 +00:00
Jean-Philippe Lang
43f583d332 Fixed: error in english string :label_end_to_start
git-svn-id: http://redmine.rubyforge.org/svn/trunk@746 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-21 15:24:52 +00:00
Jean-Philippe Lang
99dcf2ffe5 Fixed: project homepage length validation inconsistent with database field.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@745 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-20 18:58:19 +00:00
Jean-Philippe Lang
31eda0fcb2 Fixed setting value serialization.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@744 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-19 16:29:45 +00:00
Jean-Philippe Lang
83eed09109 Added 2 log messages in SubversionAdapter#entries.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@743 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-18 21:22:28 +00:00
Jean-Philippe Lang
25012efc9c Fixed: Oracle error when saving serialized setting (eg. mail notifications)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@742 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-18 17:50:17 +00:00
Jean-Philippe Lang
eb371db5b9 Fixed: RMagick not loaded on case sensitive filesystems.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@741 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-17 16:56:11 +00:00
Jean-Philippe Lang
f23daffd7d Fixed: error on document list with a document without description.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@740 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-17 16:52:39 +00:00
Jean-Philippe Lang
29413d6bee Fixed: error when uploading a file with a content type longer than 60 chars.
(Maximum size changed to 255. Mime type not saved if longer)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@739 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-17 16:51:39 +00:00
Jean-Philippe Lang
fc64fc3e9c Added RMagick availability on admin/info.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@738 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 20:39:40 +00:00
Jean-Philippe Lang
a2206ab5a0 Updated german translation (Thomas Löber).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@737 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 20:14:12 +00:00
Jean-Philippe Lang
00bf5f04db Date added as acronym title in ApplicationHelper#authoring
git-svn-id: http://redmine.rubyforge.org/svn/trunk@736 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 17:56:48 +00:00
Jean-Philippe Lang
780d5fa070 Fixed: lines in wiki content containing just a single wiki link are not displayed.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@735 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 17:17:09 +00:00
Jean-Philippe Lang
1c69c43293 Fixed: unable to save a new wiki page that just contains the default h1 title
git-svn-id: http://redmine.rubyforge.org/svn/trunk@734 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 16:57:37 +00:00
Jean-Philippe Lang
fa969504d4 A category with assigned issue can now be deleted. 2 options are proposed:
* remove assignments (issues are set to 'no category')
* reassign issues to another category (if at least an other category exists)
If no issue is assigned to the category, it's deleted silently.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@733 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 16:52:32 +00:00
Jean-Philippe Lang
3c6ddc9cec Changed author display on issues, news and document files.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@732 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 15:20:08 +00:00
Jean-Philippe Lang
89b349818b Added 'Estimated hours' attribute on issues.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@731 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 14:54:15 +00:00
Jean-Philippe Lang
4967f10356 Project modules are checked (default) when creating a project.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@730 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-15 08:56:31 +00:00
Jean-Philippe Lang
f2a058f8cf Main project list now displays root projects with their subprojects.
Added files turned into links (if not removed) on the issue history.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@729 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-14 19:55:51 +00:00
Jean-Philippe Lang
23264ec3eb Mail notification options restored (default is: issue_added and issue_updated).
Added mail notification when adding a news (disabled by default).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@728 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-14 15:30:46 +00:00
Jean-Philippe Lang
1fa1f62018 Fixed: Spent Time on Reports page only visible to administrators.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@727 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-14 11:42:23 +00:00
Jean-Philippe Lang
8929bfca63 Fixed: can't preview/save the very first wiki page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@726 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-14 11:35:47 +00:00
Jean-Philippe Lang
21c97c6a13 Added project module concept.
A project module (eg. issue tracking, news, wiki,...) is a set of permissions that can enabled/disabled at project level.
For each project, modules can be enabled on the project settings view ('Modules' tab).
This requires a specific permission: 'Select project modules' (if this permission is turned off, only Redmine administrators can choose which modules a project uses).

When applying this migration, all modules are enabled for all existing projects.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@725 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-14 11:34:08 +00:00
Jean-Philippe Lang
29348fafb7 Fixed: watchers should be notified even if they uncheck 'mail notifications'
git-svn-id: http://redmine.rubyforge.org/svn/trunk@724 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-11 18:13:32 +00:00
Jean-Philippe Lang
74ed14f8a2 Notifications about issues (add/edit) are now sent in plain text and html.
Removed lang specific strings in the corresponding mail templates, so that there is only one template for all languages.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@723 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-11 17:12:34 +00:00
Jean-Philippe Lang
6db28b3899 Added Subversion repository unit tests.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@722 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-10 18:23:44 +00:00
Jean-Philippe Lang
1590ad2518 Added "% done" in the filter list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@721 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-09 19:46:28 +00:00
Jean-Philippe Lang
b4d9ca8875 Added the ability to rename wiki pages (specific permission required).
Existing links that point to the old page are preserved and automatically redirected to the new page (this behaviour can be disabled when renaming the page).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@720 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-09 17:05:38 +00:00
Jean-Philippe Lang
f6fe15716e Small fix to TOC regexp.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@719 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-09 10:41:02 +00:00
Jean-Philippe Lang
f3364b9dce Added automatic table of content support on wiki pages, based on h1., h2. and h3. headings.
To display the page TOC, insert a line with this tag:
{{toc}} or {{<toc}} => left aligned toc
{{>toc}} => right aligned toc

git-svn-id: http://redmine.rubyforge.org/svn/trunk@718 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-09 10:16:59 +00:00
Jean-Philippe Lang
7d899166c6 Updated INSTALL doc.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@717 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-08 17:22:42 +00:00
Jean-Philippe Lang
27d6da9457 Added javascript highlightment support (http://pastie.textmate.org/50774/)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@716 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-07 21:30:46 +00:00
Jean-Philippe Lang
7e4611ad31 Removed @html_title assignments in controllers.
Views can now set the header title using set_htmh_title(title) method.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@715 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-07 20:52:45 +00:00
Jean-Philippe Lang
fdf842a4c4 Improved Redmine links:
* issue and changeset links generated only if the object exists
* issue subject and status appear in the link title
* strike issue link if issue is closed
* red wiki page link if page doesn't exist
* new icon for external links

Wiki page cache had to be disabled.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@714 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-07 20:07:54 +00:00
Jean-Philippe Lang
b812705976 Fixed: 'Move' button always visible on issues list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@713 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-07 17:26:14 +00:00
Jean-Philippe Lang
98a01d62c2 Automatically scroll down to the preview when previewing wiki page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@712 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-06 21:56:40 +00:00
Jean-Philippe Lang
422677b9b7 Added background on <pre> wiki blocks.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@711 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-06 18:51:35 +00:00
Jean-Philippe Lang
42db3cac06 Added code highlighting support in wiki, using this syntax:
<pre><code> <-- cut here

  <pre><code class="ruby">
    Place you code here.
  </code></pre>  

cut here --> </pre></code>

git-svn-id: http://redmine.rubyforge.org/svn/trunk@710 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-06 17:06:07 +00:00
Jean-Philippe Lang
22c5e0d614 'current week' filter fix.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@709 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-06 16:24:12 +00:00
Jean-Philippe Lang
22ad806a43 Removed RedCloth checks since it's now supplied with the application.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@708 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-05 20:51:11 +00:00
Jean-Philippe Lang
0803e6fcaa Search field automatically focused.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@707 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-05 20:13:06 +00:00
Jean-Philippe Lang
1b2e80545a Fixed: custom field displayed as deleted in the issue history even if no value was set.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@706 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-05 19:56:33 +00:00
Jean-Philippe Lang
8dcc041244 Issue notes are now included in search.
Fixed: search results too long when there are many matches.
Fixed: search results not escaped.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@705 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-05 19:37:13 +00:00
Jean-Philippe Lang
c27106d859 Added a new value for date filters: 'this week'
git-svn-id: http://redmine.rubyforge.org/svn/trunk@704 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-05 17:47:17 +00:00
Jean-Philippe Lang
a19a0d7b92 Subprojects are now grouped by projects in the 'Projects' top navigation drop-down menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@703 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-05 17:24:22 +00:00
Jean-Philippe Lang
17a3f9e44c Added an index on custom_values table (customized_type + customized_id columns) to speed up issue queries that use custom field filters.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@702 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-04 22:07:44 +00:00
Jean-Philippe Lang
f16ab838d8 Small fix in Mailer.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@701 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-04 16:58:30 +00:00
Jean-Philippe Lang
6260892949 'Due in' label removed from the changelog view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@700 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 20:47:41 +00:00
Jean-Philippe Lang
8a3e713f2f Added Redmine::WikiFormatting module and tests for wiki links.
RedCloth librairy is now present in Redmine lib directory.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@699 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 20:41:47 +00:00
Jean-Philippe Lang
324b904ed5 Fix: Inline image links broken in rev 690.
TODO: Fix urls with &

git-svn-id: http://redmine.rubyforge.org/svn/trunk@698 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 15:06:29 +00:00
Jean-Philippe Lang
b1cafef07a Buttons (edit, watch...) on issues/show are now located in the upper-right corner.
Pdf export link is at the bottom of the screen.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@697 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 14:34:13 +00:00
Jean-Philippe Lang
70da1c7771 Changed the application default title (redMine -> Redmine).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@696 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 12:22:17 +00:00
Jean-Philippe Lang
3ae8c53cba Small fix in issue history display.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@695 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 12:20:05 +00:00
Jean-Philippe Lang
eb6ab2af50 Trac importer: 'resolution' field imported with history as a custom field.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@694 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 12:00:48 +00:00
Jean-Philippe Lang
72b5cd3889 Trac importer now migrates status changes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@693 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 10:07:04 +00:00
Jean-Philippe Lang
a2439f3b34 Trac importer now checks the existence of trac.db and attachments directory before processing.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@692 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 09:12:49 +00:00
Jean-Philippe Lang
e76d153064 Added namespace for Redmine specific rake tasks.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@691 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-02 08:08:10 +00:00
Jean-Philippe Lang
521f4a6ddb Fixed: auto-generated links corrupted when url contains & characters in the query string.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@690 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-01 20:17:45 +00:00
Jean-Philippe Lang
296b6aee5a Trac importer initial commit. The script migrates:
* users (default password = 'trac')
* components
* milestones
* tickets
* ticket comments, files, custom fields
* wiki

git-svn-id: http://redmine.rubyforge.org/svn/trunk@689 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-09-01 20:03:34 +00:00
Jean-Philippe Lang
c6ac590d17 Added 'reported by me' and 'assigned to me' issue feeds on 'My page'.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@688 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-31 21:43:13 +00:00
Jean-Philippe Lang
1281d99f30 Added the ability to move issues (to another project) without changing their trackers.
Added length validation for homepage project attribute.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@687 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-31 20:56:14 +00:00
Jean-Philippe Lang
c68dac7e9a Added atom feed on the new cross-project issue list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@686 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-31 20:22:36 +00:00
Jean-Philippe Lang
6bdc13b33d Added cache for application settings (Setting model).
Once the values are cached, only one database query is done at each user request (to check if the cache is still valid).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@685 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-31 17:45:32 +00:00
Jean-Philippe Lang
404bfce446 Added a cross-project issue list. It displays the issues of all the projects visible by the user.
The users list available in the filters ('assigned to' / 'created by') is made of the members of all projects the current user belongs to.
For now, this view is only accessible from 'My page' ('issues assigned to me' or 'issues reported by me' blocks, to view the full lists)

On 'My page', assigned issue are now sorted by priority.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@684 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-31 17:02:44 +00:00
Jean-Philippe Lang
1187ad96ac Fixed: autologin broken.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@683 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-30 16:33:50 +00:00
Jean-Philippe Lang
840f18b1c7 Added Redmine::Info to store various information about the application.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@682 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 22:27:43 +00:00
Jean-Philippe Lang
088563db3e Fixed: "new issue" drop-down only visible by admin users.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@681 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 21:52:50 +00:00
Jean-Philippe Lang
bd6ab74318 Added border and padding on wiki table headers.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@680 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 21:43:01 +00:00
Jean-Philippe Lang
fc1024a52a Translated a few strings in fr.yml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@679 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 20:17:52 +00:00
Jean-Philippe Lang
05ff26c141 Fixed: "subproject of" list should not show archived projects.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@678 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 20:13:02 +00:00
Jean-Philippe Lang
39c9874a41 Added the ability to reset its own RSS access key on "My account".
git-svn-id: http://redmine.rubyforge.org/svn/trunk@677 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 20:07:28 +00:00
Jean-Philippe Lang
317b460d96 Some deprecation fixes (end_form_tag and count API).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@676 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 17:25:22 +00:00
Jean-Philippe Lang
c8b3c8dfec Fix: error when posting to projects/add or users/add with no custom_fields parameter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@675 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 17:07:28 +00:00
Jean-Philippe Lang
603e11d7a5 Merged 0.6 branch into trunk.
Permissions management was rewritten. Some permissions can now be specifically defined for non member and anonymous users.
This migration:
* is irreversible (please, don't forget to *backup* your database before upgrading)
* resets role's permissions (go to "Admin -> Roles & Permissions" to set them after upgrading)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@674 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-29 16:52:35 +00:00
Jean-Philippe Lang
8da5bad295 Fixed: queries with multiple custom fields return no result.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@668 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-26 12:29:53 +00:00
Jean-Philippe Lang
452a20a69a Added missing image.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@667 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-26 12:29:00 +00:00
Jean-Philippe Lang
edba1f692b Gantt chart can now be exported to a graphic file (png).
This functionality is only available if RMagick is present.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@666 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-26 07:55:57 +00:00
Jean-Philippe Lang
c1eb587c6d Fixed: calendar and gantt not updated when adding/editing/deleting a project version.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@665 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 20:19:19 +00:00
Jean-Philippe Lang
db4781d068 Replaced hard-coded urls in Mailer#attachments_add
git-svn-id: http://redmine.rubyforge.org/svn/trunk@664 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 20:09:33 +00:00
Jean-Philippe Lang
4fa51992b5 Automatic closing of duplicate issues.
When closing an issue, all related issues marked as duplicates are now also closed.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@663 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 17:45:51 +00:00
Jean-Philippe Lang
b96dc97d15 Fixed: Bad url to project forums from the wiki home page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@662 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 16:40:52 +00:00
Jean-Philippe Lang
0a629237fd Mantis importer: small fix in categories mapping.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@661 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 15:53:40 +00:00
Jean-Philippe Lang
f44f6c7876 Mantis importer:
* validation skip on issue assignement (assignee must be a project member in Redmine)
* Mantis bugs with severity 'feature' are imported as 'Feature request' in Redmine

git-svn-id: http://redmine.rubyforge.org/svn/trunk@660 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 15:45:12 +00:00
Jean-Philippe Lang
4dad4fab50 Mantis importer: issue categories truncated to 30 chars.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@659 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 14:55:07 +00:00
Jean-Philippe Lang
72714d86f6 Fixed: wiki preview doesn't work on long entries.
POST is now used for previews instead of GET.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@658 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 14:51:06 +00:00
Jean-Philippe Lang
c754e017dc Changeset comments are now stripped before being stored in the database (patch by Nicholas Wieland).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@657 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 14:41:55 +00:00
Jean-Philippe Lang
138566de0b Committer field in the Changesets table is now varchar 255.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@656 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-25 14:35:18 +00:00
Jean-Philippe Lang
1e28f7758f Added wiki syntax to online help.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@655 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-17 15:53:39 +00:00
Jean-Philippe Lang
f601d5fb9e Fixed: cursor not positioned correctly when using wiki toolbar buttons under IE (Balazs Dan).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@654 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-17 12:58:01 +00:00
Jean-Philippe Lang
d1780270da Small change to ApplicationHelper#textilizable to allow links to other wikis main page with custom text (eg. project:|mytext).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@653 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-17 12:06:50 +00:00
Jean-Philippe Lang
00238738b1 Application welcome text is now textilized.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@652 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-17 11:32:58 +00:00
Jean-Philippe Lang
7b366758fd Textilized project descriptions on project list and home page.
Added jsToolbar on project form.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@651 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-17 11:21:58 +00:00
Jean-Philippe Lang
a7033c8bac Code improvement in ProjectsController#activity (Nicolas Chuche)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@650 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-16 21:23:54 +00:00
Jean-Philippe Lang
446889b3f0 Added a 'Assignable' boolean on Role model.
If unchecked, issues can not be assigned to users having this role.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@649 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-16 17:47:41 +00:00
Jean-Philippe Lang
4cedecad4d Added a link to add a new category when creating or editing an issue.
The user is prompted for the category name. The new category is created and the drop-down list updated using an ajax call.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@648 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-16 16:45:06 +00:00
Jean-Philippe Lang
1f991c6a79 Added feeds auto discovery links on projects/show (patch by Nicolas Chuche).
Also fixed 'issue changes details' feed title.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@647 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-16 11:01:00 +00:00
Jean-Philippe Lang
2f0edb0b61 Activity view improvements:
* issue status changes are now displayed
* display options are kept when using previous/next month links

git-svn-id: http://redmine.rubyforge.org/svn/trunk@646 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-16 10:38:23 +00:00
Jean-Philippe Lang
5b35bfd434 Fixed: nil error on 'commits per month' graph.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@645 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-15 23:04:14 +00:00
Jean-Philippe Lang
889d50089d Added syntax highlightment for repository files (using CodeRay).
Supported languages: c, ruby, rhtml, yaml, html, xml.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@644 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-15 20:20:18 +00:00
Jean-Philippe Lang
a5849ee044 Wiki links can now refer other project wikis, using this syntax:
[[project:]] -> wiki starting page
[[project:page]]
[[project:page|text]]
where 'project' is the project name or identifier.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@643 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-15 17:31:01 +00:00
Jean-Philippe Lang
38e0c237a4 Image attachments are now sent inline to be viewed directly in the browser.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@642 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-15 15:36:15 +00:00
Jean-Philippe Lang
c4239a4fd2 Removed hard-coded URLs in mail templates.
Untranslated templates were deleted.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@641 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-15 15:16:15 +00:00
Jean-Philippe Lang
7379d4e2d0 Mantis importer: fixed default role mapping
git-svn-id: http://redmine.rubyforge.org/svn/trunk@638 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-15 11:11:27 +00:00
Jean-Philippe Lang
f94be4f8ab Fixed: SQL error on roadmap and changelog if there is no tracker to display.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@636 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-15 10:45:46 +00:00
Jean-Philippe Lang
3eec500320 Small change to mantis importer to be 0.5.1 compatible.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@635 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-14 13:58:39 +00:00
Jean-Philippe Lang
c16e27625c Mantis importer: fixed a few bugs
git-svn-id: http://redmine.rubyforge.org/svn/trunk@634 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-14 12:51:25 +00:00
Jean-Philippe Lang
5313f48ff4 Mantis importer: replaced find by find_by_id
git-svn-id: http://redmine.rubyforge.org/svn/trunk@633 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-14 10:48:27 +00:00
Jean-Philippe Lang
0061a3f04a Added 'email sending test' functionality.
Go to Admin -> Mail notifications and click on 'Send a test email'.
If an error occurs while sending the mail, the error message is displayed to the user.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@632 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-14 10:36:19 +00:00
Jean-Philippe Lang
7e755a53b8 Firstname, lastname and email LDAP attributes are now required if "on-the-fly register" is checked.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@631 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-14 09:14:33 +00:00
Jean-Philippe Lang
ecf208f660 Issue history is now 'oldest first' sorted.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@630 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-14 09:02:40 +00:00
Jean-Philippe Lang
b3f3634df3 On the issue report page, 0 issue counts are now displayed as dashes.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@629 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 17:00:59 +00:00
Jean-Philippe Lang
29c623fa58 Mantis importer: added priorities mapping.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@628 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 16:48:43 +00:00
Jean-Philippe Lang
343cab8148 Mantis importer: steps_to_reproduce and additional_information fields added to issue description.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@627 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 15:51:23 +00:00
Jean-Philippe Lang
f179eee7a0 Added migration of Mantis bug monitors.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@626 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 15:35:52 +00:00
Jean-Philippe Lang
5b4812add8 Added migration of Mantis bug relationships.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@625 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 15:29:16 +00:00
Jean-Philippe Lang
005ce1b21d More accurate status and role mapping in Mantis importer.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@624 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 15:04:45 +00:00
Jean-Philippe Lang
1dcf50b59a Mantis migration task initial import.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@623 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 14:37:11 +00:00
Jean-Philippe Lang
a8b202c9bc Fixed: non-active users can be viewed with account/show
git-svn-id: http://redmine.rubyforge.org/svn/trunk@622 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 10:28:55 +00:00
Jean-Philippe Lang
64d805b009 Updated UPGRADING documentation
git-svn-id: http://redmine.rubyforge.org/svn/trunk@621 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-13 10:19:46 +00:00
Jean-Philippe Lang
79b8bd0a38 Added an option to be able to relate issues in different projects.
It can be set in Admin -> Settings (default: false).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@620 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 15:31:04 +00:00
Jean-Philippe Lang
cf4e216502 Project name is now displayed in news titles when not inside the project (eg. home page).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@619 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 14:47:54 +00:00
Jean-Philippe Lang
1eff42eda6 Translated 'Sort by' label on table headers.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@618 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 14:42:15 +00:00
Jean-Philippe Lang
5478e5cbae Attachment content-type is now chomped before being saved.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@617 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 14:32:07 +00:00
Jean-Philippe Lang
29f25601bb Fixed: versions not sorted correctly in drop down lists.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@616 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 14:27:40 +00:00
Jean-Philippe Lang
e4f2e0fd37 Removed deprecated Object#type in CustomFieldsController.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@615 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 14:24:04 +00:00
Jean-Philippe Lang
4e65be9ed1 Fixed: the link to delete issue relations is displayed even if the user is not authorized to delete relations
git-svn-id: http://redmine.rubyforge.org/svn/trunk@614 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 14:22:02 +00:00
Jean-Philippe Lang
6862b97909 Removed IssuesController#history, all changes are now displayed on issues/show (not only the last 15).
Added anchor links to issue notes, eg: /issues/show/1#note-3

git-svn-id: http://redmine.rubyforge.org/svn/trunk@613 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 13:57:29 +00:00
Jean-Philippe Lang
64e91b2e13 Fixed custom fields alignment on issues/show (Balazs Dan)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@612 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 12:59:05 +00:00
Jean-Philippe Lang
9f0ddb89a0 Changed 'versions' table creation to allow null values for 'effective_date' field.
This change was done in migration 048 but seems to have no effect with SQLite.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@611 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 12:37:05 +00:00
Jean-Philippe Lang
e9ba8a4494 Changed AR error messages style (same as flash errors).
Fixed flash styles for IE6.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@610 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 11:25:25 +00:00
Jean-Philippe Lang
58ea44a462 Updated german translation (Hans-Peter Werner)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@609 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 10:29:29 +00:00
Jean-Philippe Lang
7681487af4 Fixed: Roadmap percentages not being calculated correctly (Nick Read).
The roadmap percentages are now calculated using floating point.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@608 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 10:23:07 +00:00
Jean-Philippe Lang
c4fee11969 Forum notifications are now also sent to the authors of the thread, even if they don't watch the board.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@607 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 10:16:30 +00:00
Jean-Philippe Lang
5bd26ede42 Fixed my_controller_test.rb (errors are now in flash[:error])
git-svn-id: http://redmine.rubyforge.org/svn/trunk@606 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 10:04:44 +00:00
Jean-Philippe Lang
3c8e7c79b6 Overdue versions (date reached and open issues > 0) are now always displayed on the roadmap.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@604 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-12 09:58:38 +00:00
Jean-Philippe Lang
3be226d0c4 Added a confirmation dialog box for project archiving
git-svn-id: http://redmine.rubyforge.org/svn/trunk@603 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-02 20:10:37 +00:00
Jean-Philippe Lang
dfaf8f7e6a Changed the footer link from http://redmine.rubyforge.org to http://www.redmine.org/
git-svn-id: http://redmine.rubyforge.org/svn/trunk@602 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-02 19:44:38 +00:00
Jean-Philippe Lang
acebceb1d7 Applied 'register notice' patch by Matt Jones.
The user is now redirected to the login screen after having registered.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@601 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-02 17:54:35 +00:00
Jean-Philippe Lang
2d5ac54d2e Applied the flash notices patch by Matt Jones (slightly edited).
flash[:notice] and flash[:error] are now used for notice/error messages.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@600 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-02 17:42:20 +00:00
Jean-Philippe Lang
7701de9ae4 Fixed: on spent time details view, the h3 issue link now links back to the issue
git-svn-id: http://redmine.rubyforge.org/svn/trunk@599 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-01 20:04:31 +00:00
Jean-Philippe Lang
46745614b4 Fixed: error when creating a tracker without copying an existing wokflow
git-svn-id: http://redmine.rubyforge.org/svn/trunk@598 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-01 19:51:02 +00:00
Jean-Philippe Lang
efbe29249c Added icon on external wiki links
git-svn-id: http://redmine.rubyforge.org/svn/trunk@597 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-01 19:38:13 +00:00
Jean-Philippe Lang
188077d634 History box on issues/show is now hidden if there's no history
git-svn-id: http://redmine.rubyforge.org/svn/trunk@596 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-01 18:59:39 +00:00
Jean-Philippe Lang
f8da6fb679 Fixed a bug in CVS model (clash when 2 projects point to the same repository)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@595 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-08-01 17:53:05 +00:00
Jean-Philippe Lang
6edfcd83c1 Removed a line break on news/show
git-svn-id: http://redmine.rubyforge.org/svn/trunk@594 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-18 17:22:19 +00:00
Jean-Philippe Lang
fcefdb22bf Added several validates_length_of
git-svn-id: http://redmine.rubyforge.org/svn/trunk@593 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-16 17:16:49 +00:00
Jean-Philippe Lang
7363428703 Fixed mailer (error when no assignee)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@592 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-15 12:01:53 +00:00
Jean-Philippe Lang
25f8c64f92 Doc update for 0.5.1 release.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@591 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-15 11:44:52 +00:00
Jean-Philippe Lang
fd2839c833 Now, when a user turns mail notifications off, he will still receive notifications about issue changes if he is the author or the assignee of the issue.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@590 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-15 11:12:08 +00:00
Jean-Philippe Lang
1cb5fc747f Slight documentation update.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@589 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-15 10:11:25 +00:00
Jean-Philippe Lang
4670426e4e Hours displayed using %.2f on time report.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@588 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-14 19:07:35 +00:00
Jean-Philippe Lang
05c1888703 Fix: SVN commit dates are now stored as local time
git-svn-id: http://redmine.rubyforge.org/svn/trunk@587 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-14 14:53:18 +00:00
Jean-Philippe Lang
e94e88e3ad Added the ability to log time when changing an issue status.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@586 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-14 14:37:22 +00:00
Jean-Philippe Lang
9c38458f8b Added an option to choose the date format: language based (as defined in each lang file) or ISO 8601 (YYYY-MM-DD).
This option can be set in Admin -> Settings.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@585 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-14 13:29:20 +00:00
Jean-Philippe Lang
98cf33070f Fixed: Error when editing the wokflow after deleting a status
git-svn-id: http://redmine.rubyforge.org/svn/trunk@584 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-14 11:31:43 +00:00
Jean-Philippe Lang
5e20417e6d Added wiki diff.
Diff can be viewed from the page history, or directly from the project activity page for each edit.
Uses Lars Christensen's diff library.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@583 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-14 11:25:03 +00:00
Jean-Philippe Lang
bf74efcd11 Added a margin for inline images in wiki text
git-svn-id: http://redmine.rubyforge.org/svn/trunk@582 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-02 17:23:31 +00:00
Jean-Philippe Lang
384aa50be3 Fixed: issue_id not nullified on time entries when deleting the issue
git-svn-id: http://redmine.rubyforge.org/svn/trunk@581 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-02 15:59:35 +00:00
Jean-Philippe Lang
8687401d65 Fixed: trash icon not visible on files list.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@580 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-07-02 15:32:42 +00:00
Jean-Philippe Lang
7eba6786d3 Changesets stored in the database are now displayed on the repository page even if the repository can not be reached (eg. svnserve down).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@579 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-29 18:50:48 +00:00
Jean-Philippe Lang
65be9d3c86 Removed User#display_name (replaced by User#name).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@578 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-29 17:27:27 +00:00
Jean-Philippe Lang
87bad767c6 Each category can now be associated to a user, so that new issues in that category are automatically assigned to that user.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@577 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-29 17:21:37 +00:00
Jean-Philippe Lang
f816d4f378 Fixed: Long text custom fields displayed without line breaks
Added wiki toolbar for issue notes

git-svn-id: http://redmine.rubyforge.org/svn/trunk@576 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-27 19:12:52 +00:00
Jean-Philippe Lang
184be9d0e3 Fixed: time report doesn't take account of the project for time calculations
git-svn-id: http://redmine.rubyforge.org/svn/trunk@575 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-27 18:59:36 +00:00
Jean-Philippe Lang
7eb3b186c4 Fixed an error when trying to delete a project (versions/issues dependency)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@574 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-25 19:17:58 +00:00
Jean-Philippe Lang
ba1b857197 Added Darcs basic support.
Files in the repository can not be viewed or downloaded since Darcs doesn't support cat-like command.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@573 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-24 19:30:38 +00:00
Jean-Philippe Lang
faa3d984ab Added time report.
Report can be generated by member/activity/tracker/version and year/month/week for the selected period.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@572 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-24 16:07:06 +00:00
Jean-Philippe Lang
6d7a855ca2 Added pagination on wiki page history.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@571 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-23 18:53:45 +00:00
Jean-Philippe Lang
600018d5ad Fixed Iconv::IllegalSequence errors in csv exports
git-svn-id: http://redmine.rubyforge.org/svn/trunk@570 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-23 16:55:17 +00:00
Jean-Philippe Lang
ec44c94c12 Fixed an error on welcome screen for users with no membership
git-svn-id: http://redmine.rubyforge.org/svn/trunk@569 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-23 16:36:01 +00:00
Jean-Philippe Lang
48c2a690c2 Don't show "Projects" label if projects list is empty.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@568 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-23 14:10:13 +00:00
Jean-Philippe Lang
1a2aee84b2 Fixed confidentiality issue on account/show.
Only public projects or private projects that the logged in user belongs to are displayed.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@567 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-23 14:06:21 +00:00
Jean-Philippe Lang
1c44600c62 Added per user custom queries.
Any logged in user can now save queries (they are not visible to the other users).
Only users with explicit permission can manage queries that are visible to anyone.
The queries list is removed from the "Reports" view. It can now be accessed from the issues list.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@566 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-23 13:49:29 +00:00
Jean-Philippe Lang
5332c4362c Added page association on versioned WikiContent
git-svn-id: http://redmine.rubyforge.org/svn/trunk@565 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-17 19:32:58 +00:00
Jean-Philippe Lang
f2acb56041 A wiki page can now be attached to each version.
For that, edit the version and set the wiki page name (project wiki must be enabled).
The wiki page content is displayed for each version on the roadmap view.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@564 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-14 18:26:27 +00:00
Jean-Philippe Lang
ff1343882a Swedish mail templates added (Thomas Habets)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@563 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-13 16:56:37 +00:00
Jean-Philippe Lang
2dbb397818 Fixed version field on issue view page now links to the corresponding version in the roadmap.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@562 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-12 23:07:00 +00:00
Jean-Philippe Lang
136a2a614b Applied this fix http://dev.rubyonrails.org/ticket/4967 to solve namespaced models dependencies problem.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@561 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-12 23:03:38 +00:00
Jean-Philippe Lang
a681d8bf4d Added an error message when trying to create an issue with no default status defined.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@560 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-12 22:31:05 +00:00
Jean-Philippe Lang
438161ad1f Added basic support for CVS and Mercurial SCMs.
Browsing, changesets fetching and diff viewing are implemented.
Only tested with local repositories.

Thanks to Ralph Vater for CVS specific code.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@559 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-06-12 20:12:05 +00:00
Jean-Philippe Lang
4dddb606a6 Added :dependent => :delete_all on IssueStatus Workflow association.
Also added compact in find_new_statuses_allowed_to to remove nil statuses.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@558 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-31 17:19:01 +00:00
Jean-Philippe Lang
22c7419a70 Japanese translation updated (Satoru KURASHIKI)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@557 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-30 17:52:24 +00:00
Jean-Philippe Lang
7fb03b1ca3 Fixed: error on csv/pdf export and feeds (oracle)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@556 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-29 22:20:43 +00:00
Jean-Philippe Lang
97f6315bd0 Fixed: SQL error when a non-admin user displays the project list
git-svn-id: http://redmine.rubyforge.org/svn/trunk@555 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-29 19:48:50 +00:00
Jean-Philippe Lang
e7ff47cff5 Fixed date query filters (wrong results and sql error with postgresql)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@554 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-29 19:40:48 +00:00
Jean-Philippe Lang
4a20ece43e Added Swedish translation supplied by Thomas Habets.
English email templates suffix removed so that they are used when translated template is not available.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@553 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-29 17:57:10 +00:00
Jean-Philippe Lang
b2d4666bf1 Attachments can be displayed inline in Documents
git-svn-id: http://redmine.rubyforge.org/svn/trunk@552 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-28 12:15:19 +00:00
Jean-Philippe Lang
515caa8f37 Fixed: open/closed issue counts are always 0 on reports view (postgresql)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@551 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-28 09:09:37 +00:00
Jean-Philippe Lang
4cf1b68969 Added filename header when sending an image inline
git-svn-id: http://redmine.rubyforge.org/svn/trunk@550 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-27 18:45:48 +00:00
Jean-Philippe Lang
413247ee5b Added the ability to archive projects:
* Only administrators can archive/unarchive projects.
* Once archived, the project is visible on the admin project listing only. It doesn't show up anywhere else in the app. Subprojects are also archived.
* Archive/unarchive preserve everything on the project (issues, members, ...).
* A subproject can not be unarchived if its parent project is archived.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@549 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-27 17:42:04 +00:00
Jean-Philippe Lang
70374d084e Slight views refactoring
git-svn-id: http://redmine.rubyforge.org/svn/trunk@548 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-27 12:38:29 +00:00
Jean-Philippe Lang
f335e943ad Password fields hidden on users/add form when selecting an external authentication mode.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@547 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-27 11:57:49 +00:00
Jean-Philippe Lang
f04225321c Account information can now be sent to the user when creating an account.
ActionMailer logger set to nil for production environment to disable email contents output in production.log

git-svn-id: http://redmine.rubyforge.org/svn/trunk@546 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-27 10:57:13 +00:00
Jean-Philippe Lang
f12315075f Optimistic locking added for wiki edits.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@545 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-26 17:22:27 +00:00
Jean-Philippe Lang
c99da15445 Show a 404 error page if attachment can not be read.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@544 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-26 16:57:25 +00:00
Jean-Philippe Lang
ef39db234b Added issue count details for versions on Reports view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@543 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-26 16:06:02 +00:00
Jean-Philippe Lang
8af6d24a36 Fixed "Projects" drop-down menu for IE.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@542 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-26 15:53:15 +00:00
Jean-Philippe Lang
f8ef65e8f6 Attachments can now be added to wiki pages (original patch by Pavol Murin). Only authorized users can add/delete attachments.
Attached images can be displayed inline, using textile image tag (for wiki pages, issue descriptions and forum messages).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@541 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-26 15:42:37 +00:00
Jean-Philippe Lang
6446c312be Added the ability to destroy wiki pages (content and its history are deleted from the database).
This permission has to be explicitly given (Roles & Permissions -> Wiki pages/Delete).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@540 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-25 16:44:50 +00:00
Jean-Philippe Lang
4a524ff911 Dutch translation added (Linda van den Brink)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@539 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-24 17:29:11 +00:00
Jean-Philippe Lang
9fe0dd051d User's projects alphabetically sorted in the Projects drop down menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@538 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-23 17:18:21 +00:00
Jean-Philippe Lang
3782501275 Fixed a couple of spelling errors (JT Zemp)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@537 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-20 18:11:49 +00:00
Jean-Philippe Lang
d34ea9a569 Versions can now be created with no date.
Versions with no date appear at the end of the roadmap, sorted by name.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@536 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-20 17:46:02 +00:00
Jean-Philippe Lang
bb1fccb7b7 Fixed: performance issue on RepositoriesController#revisions when a changeset has a great number of changes (eg. 100,000).
Also added pagination for changes on changeset details view.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@535 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-15 21:32:36 +00:00
Jean-Philippe Lang
777c9acae8 "My projects" are now listed under the drop-down "Projects" top menu item (20 projects max.).
The left menu section for "My projects" is removed.
Patch by Damien McKenna (slightly edited).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@534 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-15 17:39:01 +00:00
Jean-Philippe Lang
7b13b58a2f Text search added on messages.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@533 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-14 17:46:58 +00:00
Jean-Philippe Lang
b11dd1f213 Reply form on the message view is displayed only if user is logged in.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@532 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-14 17:07:40 +00:00
Jean-Philippe Lang
7ca7e4bad5 Added mail notification when a new message is posted in the forums.
Only users who "watch" the board receive notifications. To watch a board, go to the board and click on the "Watch" link.

Notifications are sent by MessageObserver observer.
GLoc was modified to use the mail template without language suffix when translated template (with language suffix) doesn't exist.
Usefull when there's no hard coded text in the mail tempate.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@531 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-14 17:03:59 +00:00
Jean-Philippe Lang
bca5bd9c62 Added watchers for message boards (watchers controller modified to support any watchable model).
No notification yet when a new message is posted.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@530 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-13 19:43:35 +00:00
Jean-Philippe Lang
b90e84b9fe Per project forums added.
Permissions for forums management can be set in "Admin -> Roles & Permissions".
Forums can be created on the project settings screen ("Forums" tab).
Once a project has a forum, a "Forums" link appears in the project menu.
For now, posting messages in forums requires to be logged in. Files can be attached to messages.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@529 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-13 17:09:56 +00:00
Jean-Philippe Lang
75582f80f8 Fixed: error when viewing a file diff from a revision view (only if repository url doesn't point to the root of the repository).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@528 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-10 18:39:49 +00:00
Jean-Philippe Lang
270e3a4345 Added "assigned to" field in mail notifications.
Also fixed mail_handler unit test (wrong fixture filename).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@527 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-10 17:46:16 +00:00
Jean-Philippe Lang
0fab627a3c Added some javascript to prevent from selecting the same from/to revision for the diff view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@526 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-10 17:36:45 +00:00
Jean-Philippe Lang
599e49e4d0 Added the ability to view a file diff with free to/from revision selection.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@525 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-10 17:28:18 +00:00
Jean-Philippe Lang
cff3950e6b Added a test for the mail handler.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@524 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-09 19:24:07 +00:00
Jean-Philippe Lang
42193960f2 Added a simple mail handler.
It lets users add notes to an existing issue by replying to the initial notification email.
Permissions are checked in the same way as in the application (the user is identified by its mail address).

Information about configuring the application so that it receives emails can be found here:
http://wiki.rubyonrails.com/rails/pages/HowToReceiveEmailsWithActionMailer

RedMine mail hander is MailHandler#receive

git-svn-id: http://redmine.rubyforge.org/svn/trunk@523 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-09 18:46:43 +00:00
Jean-Philippe Lang
98d08439dc Fixed: files with an apostrophe in their names can't be accessed in the repository
git-svn-id: http://redmine.rubyforge.org/svn/trunk@522 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-09 17:22:15 +00:00
Jean-Philippe Lang
8614c00c8a Text files can now be viewed online when browsing the repository.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@521 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-08 15:49:20 +00:00
Jean-Philippe Lang
df0a49ff14 "me" value is now available in queries for "assigned to" and "author" filters.
When executing the query, it is replaced by the currently logged in user.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@520 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-08 12:46:15 +00:00
Jean-Philippe Lang
50429d0819 Fixed the order of the japanese day names
git-svn-id: http://redmine.rubyforge.org/svn/trunk@519 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-08 11:51:20 +00:00
Jean-Philippe Lang
5c88c1f50b Changed the length of 'language' column in users table from 2 to 5, to allow long language codes like pt-br.
Updated portuguese translation (Arthur Zapparoli).
Current pt translation moved to pt-br.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@518 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-08 09:26:57 +00:00
Jean-Philippe Lang
d85f5518d9 Removed "Wiki edits" option in the activity view if the project has no wiki.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@517 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-07 16:57:42 +00:00
Jean-Philippe Lang
8e24c6458d Added an option to see all versions in the roadmap view (including completed ones).
On calendar and gantt, versions are now clickable and link to the corresponding entry in the roadmap.

Since calendar and gantt are now cached, don't forget to empty your cache before restarting the application.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@516 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-07 16:54:26 +00:00
Jean-Philippe Lang
b748455d96 Added fragment caching for calendar and gantt views
git-svn-id: http://redmine.rubyforge.org/svn/trunk@515 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-06 16:40:33 +00:00
Jean-Philippe Lang
7eb6471559 Added autologin feature (disabled by default).
To enable this feature, go to administration settings and choose a duration for autologin.
When enabled, a checkbox on the login form lets users activate autologin.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@514 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-06 12:49:32 +00:00
Jean-Philippe Lang
56513a8c66 Added a "clear" link when displaying a saved query. It clears the query filter to show all issues.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@513 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 17:52:08 +00:00
Jean-Philippe Lang
8b1455c945 Filter values hidden by default to avoid show/hide flashes when loading screen.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@512 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 16:10:45 +00:00
Jean-Philippe Lang
b9be1d1268 Ajaxified issue filter reset link
git-svn-id: http://redmine.rubyforge.org/svn/trunk@511 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 15:59:06 +00:00
Jean-Philippe Lang
71e6f22670 Issue#long_id no more used and removed
git-svn-id: http://redmine.rubyforge.org/svn/trunk@510 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 15:55:50 +00:00
Jean-Philippe Lang
0dbbf776c6 Slight modifications on project settings views
git-svn-id: http://redmine.rubyforge.org/svn/trunk@509 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 15:35:28 +00:00
Jean-Philippe Lang
3eed7e622c Members management in project settings is now AJAXified
git-svn-id: http://redmine.rubyforge.org/svn/trunk@508 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 15:21:18 +00:00
Jean-Philippe Lang
a6a181c70c Issue filter no more reseted when clicking 'Issues' menu link
git-svn-id: http://redmine.rubyforge.org/svn/trunk@507 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 13:35:33 +00:00
Jean-Philippe Lang
92b02014d2 Issue relations first commit (not thoroughly tested). 4 kinds of relation are available:
* relates to: do nothing special. Just to know that the 2 issues are related...
* duplicates: will close the related issue with the same status when closing the issue (not implemented yet)
* blocks: will require to close the blocking issue before closing the blocked issue (not implemented yet)
* precedes (end to start relation): start date of the related issue depends on the due date of the preceding issue (implemented). A delay can be set so that the related issue can only start n days after the end of the preceding issue. When setting dates for an issue, dates of all downstream issues are set according to these relations.

To set a relation, the 2 issues have to belong to the same project (may change in the future). So if an issue is moved to another project, all its relations are removed.
Circular dependencies are checked when creating a relation.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@506 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 13:22:27 +00:00
Jean-Philippe Lang
987e843cd1 Removed alpha transparency from time icon
git-svn-id: http://redmine.rubyforge.org/svn/trunk@505 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 10:28:49 +00:00
Jean-Philippe Lang
5050586a9e Changed delete icon
git-svn-id: http://redmine.rubyforge.org/svn/trunk@504 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 10:06:13 +00:00
Jean-Philippe Lang
da4fd6b71a Login field automatically focused on login form
git-svn-id: http://redmine.rubyforge.org/svn/trunk@503 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-05 09:23:56 +00:00
Jean-Philippe Lang
e07c44543f Bulgarian translation added (Nikolay Solakov)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@502 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-02 19:36:00 +00:00
Jean-Philippe Lang
78b5e57a4a Fixed an unicode problem on gantt (first letter of the day name)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@501 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-02 19:13:38 +00:00
Jean-Philippe Lang
10a49d476d HTML select tags are no longer hidden with IE7 when showing navigation drop-down menu.
They are still hidden for IE6 (no z-index support for select tags).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@500 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-02 17:31:42 +00:00
Jean-Philippe Lang
0759212a44 Added fragment caching for svn diffs.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@499 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-01 20:56:19 +00:00
Jean-Philippe Lang
7eda64e464 Issue subjects column width set to 330 on gantt chart
git-svn-id: http://redmine.rubyforge.org/svn/trunk@498 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-01 08:48:24 +00:00
Jean-Philippe Lang
124cca3af0 Text formatting drop down disabled if RedCloth is not available (system settings).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@497 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-05-01 08:37:07 +00:00
Jean-Philippe Lang
7faf77804d Subproject name added in csv and pdf exports.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@496 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 20:18:28 +00:00
Jean-Philippe Lang
d94bcd285a A 403 error page is now displayed (instead of a blank page) when trying to access a protected page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@495 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 19:47:28 +00:00
Jean-Philippe Lang
9af49e07f3 Added last commit message for each entry in repository browser.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@494 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 18:20:22 +00:00
Jean-Philippe Lang
0f0ab74560 Fixed: last day of the month not included in project activity
git-svn-id: http://redmine.rubyforge.org/svn/trunk@493 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 18:03:42 +00:00
Jean-Philippe Lang
5288b8550b Removed hard coded 'Search' string in base layout.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@492 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 14:17:20 +00:00
Jean-Philippe Lang
66d789229d Added a DropOut effect when removing a block on my page layout.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@491 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 09:09:45 +00:00
Jean-Philippe Lang
bba9be6a4d Removed an used li element in navigation menu.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@490 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 09:08:13 +00:00
Jean-Philippe Lang
ebe10fa645 Added a quick search form in page header. Search functionality moved to a dedicated controller.
When used:
* outside of a project: searches projects
* inside a project: searches issues, changesets, news, documents and wiki pages of the current project

If an issue number is given, user is redirected to the corresponding issue.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@489 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-30 08:52:39 +00:00
Jean-Philippe Lang
833c5035a6 Fixed comments header label on time log details
git-svn-id: http://redmine.rubyforge.org/svn/trunk@488 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-28 17:32:11 +00:00
Jean-Philippe Lang
aa3445bdb6 Moved functional tests for MyController
git-svn-id: http://redmine.rubyforge.org/svn/trunk@487 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-28 17:30:17 +00:00
Jean-Philippe Lang
66fe12db71 Fixed a TemplateError nil:NilClass (oracle specific) on _news.rhtml
git-svn-id: http://redmine.rubyforge.org/svn/trunk@486 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-27 19:34:31 +00:00
Jean-Philippe Lang
5db3396c07 Added an ajax indicator for all ajax calls. Also removed highlight effects on my page layout edition.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@485 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-27 19:32:57 +00:00
Jean-Philippe Lang
c1a18a2889 Subproject name displayed on issue list, calendar and gantt (only for issues that belong to a subproject).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@484 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-27 16:21:53 +00:00
Jean-Philippe Lang
89db185726 Added a link on revision screen to see the entire diff for the revision.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@483 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-26 18:46:55 +00:00
Jean-Philippe Lang
a301d0eb4e Updated migration 41 to support table name prefix/sufix.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@482 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-25 16:48:01 +00:00
Jean-Philippe Lang
076655cdd8 Updated migration 41 to support table name prefix/sufix.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@481 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-25 16:47:29 +00:00
Jean-Philippe Lang
8e4a5996b0 Fixed: 9268 These files should be moved out of revision control
Renamed to *.example:
* config/database.yml
* public/dispatch.cgi
* public/dispatch.fcgi
* public/dispatch.rb

git-svn-id: http://redmine.rubyforge.org/svn/trunk@480 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-25 16:21:23 +00:00
Jean-Philippe Lang
52547466f0 Fixed: 10342 Creation of Schema in Oracle
Comment is a reserved keyword for Oracle. The five 'Comment' columns are renamed to 'Commments'.
Migration scripts were modified to let oracle users create the database. For the others, migration 41 will rename the columns (only if columns have the 'old' name).
Fixed also a few oracle specific issues.

Note: currently (in Rails 1.2.3), there's bug in Rails oracle adapter. See: http://dev.rubyonrails.org/ticket/7344
Attached patch is required for redMine to work properly.


git-svn-id: http://redmine.rubyforge.org/svn/trunk@479 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-25 15:06:20 +00:00
Jean-Philippe Lang
4967fa8733 Journal details truncated only if values are strings
git-svn-id: http://redmine.rubyforge.org/svn/trunk@478 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-24 18:26:42 +00:00
Jean-Philippe Lang
8065001c0d Fixed 10335 Error in journalizing an issue with longtext custom fields (Postgresql)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@477 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-24 16:17:57 +00:00
Jean-Philippe Lang
72a5839931 Removed an old, no longer used, model.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@476 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-24 15:53:00 +00:00
Jean-Philippe Lang
c995be94d9 Fixed: default status not showing in new issue
git-svn-id: http://redmine.rubyforge.org/svn/trunk@475 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-24 15:19:49 +00:00
Jean-Philippe Lang
018b81a46a Fixed 10337 Regression: Admin raises issue in project not assigned to
git-svn-id: http://redmine.rubyforge.org/svn/trunk@474 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-24 14:49:05 +00:00
Jean-Philippe Lang
941a240535 Commit messages are now scanned for referenced or fixed issue IDs.
Keywords and the status to apply to fixed issues can be defined in Admin -> Settings.

Default keywords:
- for referencing issues: refs, references, IssueID
- for fixing issues: fixes,closes
There's no default status defined for fixed issue. You'll have to specify it if you want to enable auto closure of issues.

Example of a working commit message: "This commit references #1, #2 and fixes #3"

git-svn-id: http://redmine.rubyforge.org/svn/trunk@473 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-24 13:57:27 +00:00
Jean-Philippe Lang
ed5b5d0559 Missing fav_off icon.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@472 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-23 19:56:13 +00:00
Jean-Philippe Lang
104b7d457d Removed some parentheses before arguments.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@471 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-23 16:46:04 +00:00
Jean-Philippe Lang
feb973b970 The ability to change the issue status to the same status is no longer forced.
This behaviour can be defined in workflow setup.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@470 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 22:20:09 +00:00
Jean-Philippe Lang
e02068eb2a Removed some parentheses before arguments.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@469 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 21:19:16 +00:00
Jean-Philippe Lang
eea1878a3b Italian translation update (Alessio Spadaro)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@468 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 20:29:00 +00:00
Jean-Philippe Lang
4499c7a030 Grey scale icon for issue not watched.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@467 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 20:03:08 +00:00
Jean-Philippe Lang
2f1d8630f1 Fixed: error on history atom feed when there's no notes on an issue change
git-svn-id: http://redmine.rubyforge.org/svn/trunk@466 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 12:50:26 +00:00
Jean-Philippe Lang
cf59496957 Fixed 10058: issue URL in repository comment break
git-svn-id: http://redmine.rubyforge.org/svn/trunk@465 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 10:58:15 +00:00
Jean-Philippe Lang
32de29ea35 Fixed 10061 problem with textilize and :hard_breaks (Pavol Murin)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@464 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 10:10:56 +00:00
Jean-Philippe Lang
8d7de50ca8 Fixed 10211 Wiki names can't have periods in them.
Same validations as WikiPage model now applied to wiki start page.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@463 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-22 09:50:16 +00:00
Jean-Philippe Lang
3d685f7bec Fixed: blank lines in left menu with IE
git-svn-id: http://redmine.rubyforge.org/svn/trunk@462 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 18:06:01 +00:00
Jean-Philippe Lang
05b08ae38f Right overflow of the left menu now hidden.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@461 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 17:11:30 +00:00
Jean-Philippe Lang
623d2f25b1 Projects menu item now shows the list of public projects and projects for which the user is a member (marked with a star).
If current user is admin, private projects are also listed.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@460 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 16:40:56 +00:00
Jean-Philippe Lang
634d3557f2 Online help japanese translation added (Ken Date)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@459 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 16:11:12 +00:00
Jean-Philippe Lang
6957eceee0 Added portuguese translation (Joao Carlos Clementoni).
Email templates copied from english.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@458 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 16:02:28 +00:00
Jean-Philippe Lang
5097f6394d Fixed: error when using a custom query feed with custom field filter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@457 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 13:16:04 +00:00
Jean-Philippe Lang
77cfc1cc59 Added a new block available for my page: "Watched issues"
git-svn-id: http://redmine.rubyforge.org/svn/trunk@456 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 12:28:22 +00:00
Jean-Philippe Lang
5d8200b9fc Added missing parentheses on news/show and removed useless call to auto_link
git-svn-id: http://redmine.rubyforge.org/svn/trunk@455 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 12:10:50 +00:00
Jean-Philippe Lang
18255881ca Added create_watchers migration
git-svn-id: http://redmine.rubyforge.org/svn/trunk@454 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 12:09:07 +00:00
Jean-Philippe Lang
2fb84af3e9 Added "Watch" functionality on issues. It allows users to receive mail notifications about issue changes.
For now, it's only usefull for users who are not members of the project, since members receive notifications for each issue (this behaviour will change).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@453 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 12:08:31 +00:00
Jean-Philippe Lang
907f906ec6 Fixed: error when exporting to PDF an issue list using a custom field filter.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@452 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-21 08:21:23 +00:00
Jean-Philippe Lang
acfb87a07b News box on project/show is hidden if there is no news to display.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@451 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-20 10:26:57 +00:00
Jean-Philippe Lang
c10541feb7 Removed some spaces before argument parentheses.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@450 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-20 10:23:25 +00:00
Jean-Philippe Lang
e72778ea84 Removed some spaces before argument parentheses.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@449 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-20 09:53:44 +00:00
Jean-Philippe Lang
a824017d8c Checkboxes on the workflow screen diagonal no longer disabled
git-svn-id: http://redmine.rubyforge.org/svn/trunk@448 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-17 11:02:46 +00:00
Jean-Philippe Lang
d570bc5cc5 Custom fields for issues can now be used as filters on issue list.
To use a custom field as a filter, check "Used as a filter" on the custom field edit screen.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@447 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-17 10:53:20 +00:00
Jean-Philippe Lang
559b2069ac User#<=> modified to sort on firstname if same lastname
git-svn-id: http://redmine.rubyforge.org/svn/trunk@446 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-12 16:49:02 +00:00
Jean-Philippe Lang
6c5e89ede0 Redmine::VERSION updated
git-svn-id: http://redmine.rubyforge.org/svn/trunk@445 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-11 16:38:19 +00:00
Jean-Philippe Lang
6a8ddc954f Doc files updated for 0.5.0 release
git-svn-id: http://redmine.rubyforge.org/svn/trunk@443 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-11 15:33:27 +00:00
Jean-Philippe Lang
8f1c0eb2dd Closed issues no longer displayed on "my page" -> "issues assigned to me".
git-svn-id: http://redmine.rubyforge.org/svn/trunk@442 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-11 15:18:36 +00:00
Jean-Philippe Lang
8c01275ee9 Japanese lang file updated (Satoru Kurashiki)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@441 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-11 15:14:44 +00:00
Jean-Philippe Lang
d6f4208a15 Fixed 10031 revision links and auto linking URLs conflict
git-svn-id: http://redmine.rubyforge.org/svn/trunk@440 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-11 15:10:02 +00:00
Jean-Philippe Lang
2e78bc1bc4 Fixed pagination links on admin project listing
git-svn-id: http://redmine.rubyforge.org/svn/trunk@439 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-10 17:08:59 +00:00
Jean-Philippe Lang
20feb44564 Changesets comments truncated at 500 characters on activity view.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@438 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-09 18:18:23 +00:00
Jean-Philippe Lang
1506d3ddab Form to add an attachment on document view is now togglable.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@437 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-09 17:59:31 +00:00
Jean-Philippe Lang
5cb64fff91 Replaced deprecated content_for_layout in the layout.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@436 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-08 20:43:57 +00:00
Jean-Philippe Lang
1adf56664d Replaced hard coded help link.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@435 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-08 18:16:45 +00:00
Jean-Philippe Lang
183ede84fd Various changes on views. On project summary, members are now grouped by role and subprojects are listed inline.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@434 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-08 17:44:54 +00:00
Jean-Philippe Lang
bd9a44c225 Added permissions report (link available on roles list view).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@433 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-07 20:27:19 +00:00
Jean-Philippe Lang
30734ba8e8 Added toggle_link helper.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@432 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-07 18:56:12 +00:00
Jean-Philippe Lang
cf4651b6bb Added link_to_issue helper.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@431 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-07 18:30:01 +00:00
Jean-Philippe Lang
14314b77ee Added a warning message on tracker list for trackers that don't have any workflow defined.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@430 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-07 17:33:07 +00:00
Jean-Philippe Lang
ef71edd331 Added versions due dates on calendar.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@429 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-07 12:16:09 +00:00
Jean-Philippe Lang
708c3c9ec6 Added versions due dates on gantt chart.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@428 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-07 12:09:01 +00:00
Jean-Philippe Lang
c1a5c5b9f8 Removed repository creation callback
git-svn-id: http://redmine.rubyforge.org/svn/trunk@427 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-07 09:49:36 +00:00
Jean-Philippe Lang
1cc7006555 Modified the change_status view to use the form builder.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@426 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-05 18:02:56 +00:00
Jean-Philippe Lang
3f87f3c47a Feature 9867 Allow file upload in comment and add to issue history
git-svn-id: http://redmine.rubyforge.org/svn/trunk@425 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-05 17:20:04 +00:00
Jean-Philippe Lang
f3a1b4e38c Added the ability to easily rollback to a previous version of a wiki page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@424 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-05 14:45:44 +00:00
Jean-Philippe Lang
7eb4abae80 Removed RedCloth :hard_break option that broke textile rendering.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@423 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-05 14:34:11 +00:00
Jean-Philippe Lang
0ea1b712be "Author" column replaced by "Assigned to" in issue list.
"Assigned to" column added in the csv export.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@422 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-05 07:33:51 +00:00
Jean-Philippe Lang
9cf96580bf RedCloth attribute :hard_break set to true to keep line breaks
git-svn-id: http://redmine.rubyforge.org/svn/trunk@421 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 22:16:17 +00:00
Jean-Philippe Lang
46d67cb349 Fixed a regression (crash when an admin with no role on the project try to create an issue)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@420 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 21:52:53 +00:00
Jean-Philippe Lang
f7d5141251 Added svn:eol-style native property for various files
git-svn-id: http://redmine.rubyforge.org/svn/trunk@419 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 18:20:45 +00:00
Jean-Philippe Lang
8e11dac375 Added gantt and calendar url in robots file, to avoid recursive indexing by bots.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@418 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 18:09:28 +00:00
Jean-Philippe Lang
adee6de140 Added a unit test on User#role_for_project
git-svn-id: http://redmine.rubyforge.org/svn/trunk@417 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 17:52:07 +00:00
Jean-Philippe Lang
4ed89dc2d3 Fixed User role_for_project method
git-svn-id: http://redmine.rubyforge.org/svn/trunk@416 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 17:46:51 +00:00
Jean-Philippe Lang
8e6d575d4e Modified logged_in_user_membership controller method so that it returns a role
git-svn-id: http://redmine.rubyforge.org/svn/trunk@415 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 17:32:23 +00:00
Jean-Philippe Lang
e227b92972 Various code cleaning, mainly on User, Permission and IssueStatus models.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@414 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 17:26:05 +00:00
Jean-Philippe Lang
a9a082f05c Patch 9725 Email templates of chinese simplified (Andy Wu)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@413 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 16:22:00 +00:00
Jean-Philippe Lang
be54cb9531 Feature #9808 Allow user to "change" issue status to the same status
git-svn-id: http://redmine.rubyforge.org/svn/trunk@412 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-04 16:14:26 +00:00
Jean-Philippe Lang
18a6b8e101 Fixed 9793 Preview fail for first wiki page of a project
git-svn-id: http://redmine.rubyforge.org/svn/trunk@411 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-03 22:24:59 +00:00
Jean-Philippe Lang
52ced19e2e Added subprojects issue count on project "Reports" page
git-svn-id: http://redmine.rubyforge.org/svn/trunk@410 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-03 19:48:49 +00:00
Jean-Philippe Lang
1c0971b12c Fixed pagination on users/list (status filter lost)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@409 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-03 19:22:56 +00:00
Jean-Philippe Lang
2db9bdf7a2 Slight modifications on revisions table
git-svn-id: http://redmine.rubyforge.org/svn/trunk@408 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-03 19:16:09 +00:00
Jean-Philippe Lang
a09b2a23b9 Feature 9784 Set status when raising issue.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@407 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-03 18:34:22 +00:00
Jean-Philippe Lang
6d2ecefca0 Quick fix for:
* 9750 sort field is lost, when displaying next part of issues list
* 9782 show issues in page is wrong

Still some problems, eg. status criteria is lost when paginating or sorting on users/list

git-svn-id: http://redmine.rubyforge.org/svn/trunk@406 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-03 17:46:05 +00:00
Jean-Philippe Lang
568c22016a Colored square added on "my page" issue list
git-svn-id: http://redmine.rubyforge.org/svn/trunk@405 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 20:24:02 +00:00
Jean-Philippe Lang
6e1b9326e4 Added parent project name (if it exists) on project list and project overview.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@404 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 20:17:02 +00:00
Jean-Philippe Lang
3c8a38212e Applied the same column width in different similar views.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@403 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 19:27:05 +00:00
Jean-Philippe Lang
eba4af7a9f added svn-executable property on perl scripts
git-svn-id: http://redmine.rubyforge.org/svn/trunk@402 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 19:01:31 +00:00
Jean-Philippe Lang
f8a5725214 Renamed the repository management script and removed hard coded parameters.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@401 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 19:00:22 +00:00
Jean-Philippe Lang
791077c240 Added some attributes length validations.
Also added some information about attribute length constraints on forms.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@400 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 18:44:35 +00:00
Jean-Philippe Lang
bd8de9a6f8 Added the ability to copy an existing workflow when creating a new tracker.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@399 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 17:45:21 +00:00
Jean-Philippe Lang
0a82489ddc Added the ability to include subprojects issues on calendar & gantt (options box)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@398 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 17:12:02 +00:00
Jean-Philippe Lang
006b8716ed Migration to add identifier attribute on project.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@397 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-02 06:29:09 +00:00
Jean-Philippe Lang
4ff8386e3d Initial commit for svn repository management and access control:
* Identifier attribute added on Project model. Used as the unix group name for the project
* Web services (disabled by default) and scripts for repository management on a remote svn host

git-svn-id: http://redmine.rubyforge.org/svn/trunk@396 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-04-01 19:43:59 +00:00
Jean-Philippe Lang
cb6c8bee47 Patch #9705 Tracker filtering on Main Calendar (Jeffrey Jones)
Slightly edited.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@395 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-31 17:15:30 +00:00
Jean-Philippe Lang
3a35883250 Added calendar-zh.js for chinese translation (Andy Wu)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@394 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-31 15:53:56 +00:00
Jean-Philippe Lang
2a00565bc4 Added chinese simplified translation (Andy Wu)
Fixed rfpdf chinese.rb

git-svn-id: http://redmine.rubyforge.org/svn/trunk@393 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-31 15:51:44 +00:00
Jean-Philippe Lang
5e0e951867 Japanese lang file updated (Satoru KURASHIKI)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@392 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-30 23:02:35 +00:00
Jean-Philippe Lang
4c75bd404b removed hard coded strings in views
git-svn-id: http://redmine.rubyforge.org/svn/trunk@391 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-29 19:02:48 +00:00
Jean-Philippe Lang
2b70760594 patch #9627 Add Side by Side in Diff view (Cyril Mougel)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@390 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-29 18:14:59 +00:00
Jean-Philippe Lang
d8ce97f766 german lang file updated (Thomas Löber)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@389 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-28 17:52:20 +00:00
Jean-Philippe Lang
cf221c8f75 removed filter_html on RedCloth textile conversions
git-svn-id: http://redmine.rubyforge.org/svn/trunk@388 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-27 17:49:52 +00:00
Jean-Philippe Lang
b938c60396 slight svg rendering modifications
git-svn-id: http://redmine.rubyforge.org/svn/trunk@387 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-26 18:13:42 +00:00
Jean-Philippe Lang
3a28fa01b0 added info about textile availabality on admin/info
git-svn-id: http://redmine.rubyforge.org/svn/trunk@386 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-26 18:03:25 +00:00
Jean-Philippe Lang
8a84884d50 added changes counts on the "commits per author" svn stat graph
git-svn-id: http://redmine.rubyforge.org/svn/trunk@385 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-26 17:14:06 +00:00
Jean-Philippe Lang
b103052ff0 replaced an hard coded label
git-svn-id: http://redmine.rubyforge.org/svn/trunk@384 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-26 16:47:35 +00:00
Jean-Philippe Lang
71b6dd232e fixed #9542 sqlite3 exception in db:migrate on AddChangesetCommitDate
git-svn-id: http://redmine.rubyforge.org/svn/trunk@383 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-26 16:41:54 +00:00
Jean-Philippe Lang
1f7863e323 fixed bug 9537 fetch_changesets broken
git-svn-id: http://redmine.rubyforge.org/svn/trunk@382 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-25 22:33:40 +00:00
Jean-Philippe Lang
e951209d68 added pagination on revisions list
git-svn-id: http://redmine.rubyforge.org/svn/trunk@381 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-25 18:18:29 +00:00
Jean-Philippe Lang
0ef114e006 added simple svn statistics graphs, rendered using SVG::Graph
git-svn-id: http://redmine.rubyforge.org/svn/trunk@380 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-25 17:11:46 +00:00
Jean-Philippe Lang
887f11435b Patch #9530 Progress bars for roadmap versions (Nick Read)
Slightly edited and links to issues list added

git-svn-id: http://redmine.rubyforge.org/svn/trunk@379 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-25 12:59:48 +00:00
Jean-Philippe Lang
d7f1b873c8 show anonymous on activity view when a commit has no author
git-svn-id: http://redmine.rubyforge.org/svn/trunk@378 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-25 12:24:07 +00:00
Jean-Philippe Lang
16f9f50f50 SVN commits are now stored in the database, and added to the activity view and the search engine.
New commits are automatically retrieved and stored when consulting the repository in the app. This behaviour can be disabled by unchecking 'Autofecth commits' in configuration settings.
Commits can be fetched offline by running (recommanded at least for the initial import of past commits): 
ruby script/runner "Repository.fetch_changesets"
It will load commits for all of the repositories.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@377 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-25 12:12:15 +00:00
Jean-Philippe Lang
6f1dcdc08f updated INSTALL doc with rake db:migrate instead of the deprecated rake migrate
git-svn-id: http://redmine.rubyforge.org/svn/trunk@376 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-24 20:09:07 +00:00
Jean-Philippe Lang
3cd50da3b0 text formatting setting cached at controller level
git-svn-id: http://redmine.rubyforge.org/svn/trunk@375 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-24 09:16:33 +00:00
Jean-Philippe Lang
0125ec3b48 removed td padding
git-svn-id: http://redmine.rubyforge.org/svn/trunk@374 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 23:50:12 +00:00
Jean-Philippe Lang
7611f52faf added some parenthesis
git-svn-id: http://redmine.rubyforge.org/svn/trunk@373 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 19:03:22 +00:00
Jean-Philippe Lang
669b2342ff added some parenthesis in views
git-svn-id: http://redmine.rubyforge.org/svn/trunk@372 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 19:00:48 +00:00
Jean-Philippe Lang
1493c2a9b4 added roadmap and activity calls in projects functional tests
git-svn-id: http://redmine.rubyforge.org/svn/trunk@371 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 15:58:53 +00:00
Jean-Philippe Lang
724ca74f51 patch #9429 Display Wiki edits in activity log (Nick Read)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@370 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 15:58:02 +00:00
Jean-Philippe Lang
76d4ac17a2 added 999 as a maximum for time entry hours
git-svn-id: http://redmine.rubyforge.org/svn/trunk@369 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 13:11:47 +00:00
Jean-Philippe Lang
8d54d97007 Simple time tracking functionality added. Time can be logged at issue or project level.
There's no aggregation reports for now, it's just possible to see all time entries for a project or an issue.
A new "activities" enumeration is added.
Permission for a role to log time must be set (new "Time tracking" section in role permissions screen).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@368 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 12:22:31 +00:00
Jean-Philippe Lang
7cf2d889d8 native eol property set on lang files
git-svn-id: http://redmine.rubyforge.org/svn/trunk@363 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 08:15:22 +00:00
Jean-Philippe Lang
59a2d1c974 closed issues are now striked on roadmap
git-svn-id: http://redmine.rubyforge.org/svn/trunk@362 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 08:13:59 +00:00
Jean-Philippe Lang
5108a9c6fe german translation improved (thanks to Daniel Weinand)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@361 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-23 08:13:33 +00:00
Jean-Philippe Lang
6e98df0e28 fixed #9397 Roadmap - Distinguishing open and closed issues
(closed) is added at the end of closed issue subjects

git-svn-id: http://redmine.rubyforge.org/svn/trunk@360 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-21 18:56:47 +00:00
Jean-Philippe Lang
f3f75f557a added some diagnostic information on admin/info
git-svn-id: http://redmine.rubyforge.org/svn/trunk@359 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 20:03:27 +00:00
Jean-Philippe Lang
8bf5759d26 fixed #9398 RSS feed on custom reports not displaying subproject changes
git-svn-id: http://redmine.rubyforge.org/svn/trunk@358 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 18:55:33 +00:00
Jean-Philippe Lang
cbf797ed95 removed a non matching closing select tag
git-svn-id: http://redmine.rubyforge.org/svn/trunk@357 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 18:37:53 +00:00
Jean-Philippe Lang
17c4d733d0 fixed #9403 Include "Fixed version" when creating a new issue
git-svn-id: http://redmine.rubyforge.org/svn/trunk@356 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 18:37:21 +00:00
Jean-Philippe Lang
dd52fb7e2e accidentally committed a database name change...
git-svn-id: http://redmine.rubyforge.org/svn/trunk@355 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 18:34:07 +00:00
Jean-Philippe Lang
b1f5103c75 fixed #9401 New Wiki, cannot create new page (good one)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@354 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 18:14:23 +00:00
Jean-Philippe Lang
f19e8af33b fixed #9404 Issue and revision textile links in issue notes
git-svn-id: http://redmine.rubyforge.org/svn/trunk@353 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 18:09:14 +00:00
Jean-Philippe Lang
a559c0cfc2 fixed #9401 New Wiki, cannot create new page.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@352 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 17:41:04 +00:00
Jean-Philippe Lang
5132252daa added "return false;" for onclick event on unclickable menu items
git-svn-id: http://redmine.rubyforge.org/svn/trunk@351 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-20 17:38:34 +00:00
Jean-Philippe Lang
dfb81dd89c added back "subproject" filter on issue list
git-svn-id: http://redmine.rubyforge.org/svn/trunk@350 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-19 20:31:02 +00:00
Jean-Philippe Lang
59e3802c74 fixed migration scripts to work with mysql 5 running in strict mode
git-svn-id: http://redmine.rubyforge.org/svn/trunk@349 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-19 18:12:35 +00:00
Jean-Philippe Lang
a1d2acd574 fixed #9374 Edit issue doesn't have blank category
git-svn-id: http://redmine.rubyforge.org/svn/trunk@348 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-19 17:46:02 +00:00
Jean-Philippe Lang
8bb60b6474 added a status filter on users/list
git-svn-id: http://redmine.rubyforge.org/svn/trunk@347 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-18 20:44:33 +00:00
Jean-Philippe Lang
143be7ee02 added a setting option to set the feeds content limit
git-svn-id: http://redmine.rubyforge.org/svn/trunk@346 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-18 18:32:59 +00:00
Jean-Philippe Lang
d967bb4a54 added back the anchor for each page on the wiki full export
git-svn-id: http://redmine.rubyforge.org/svn/trunk@345 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-18 16:52:25 +00:00
Jean-Philippe Lang
fd37f37ee4 fixed problems when svn path doesn't point to the root directory of the repository.
a root_url property has been added on the repository. it's automatically retrieved the first time the repository is browsed

git-svn-id: http://redmine.rubyforge.org/svn/trunk@344 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-18 15:48:05 +00:00
Jean-Philippe Lang
db3e8616c8 better rendering time for projects/calendar
git-svn-id: http://redmine.rubyforge.org/svn/trunk@343 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-18 10:17:59 +00:00
Jean-Philippe Lang
8fdef1f820 admin menu modification
git-svn-id: http://redmine.rubyforge.org/svn/trunk@342 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-18 10:17:21 +00:00
Jean-Philippe Lang
b481e76ee2 members are now sorted according to roles order on projects/show
removed the useless "members" item in the project menu

git-svn-id: http://redmine.rubyforge.org/svn/trunk@341 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-17 17:44:29 +00:00
Jean-Philippe Lang
3477f9bfe0 added feed icon
git-svn-id: http://redmine.rubyforge.org/svn/trunk@340 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-17 15:51:26 +00:00
Jean-Philippe Lang
10cf1ccc1a added rss/atom feeds at project levels for:
* news
* new issues reported
* details of issue changes

issue cutom queries can be used as feeds

git-svn-id: http://redmine.rubyforge.org/svn/trunk@339 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-17 15:18:50 +00:00
Jean-Philippe Lang
22b42dc90a fixed self.down in AddSearchPermission migration
git-svn-id: http://redmine.rubyforge.org/svn/trunk@338 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-17 14:50:08 +00:00
Jean-Philippe Lang
e6f58e4dcc fixed #9308 table_name pre/suffix support
git-svn-id: http://redmine.rubyforge.org/svn/trunk@337 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-15 22:11:02 +00:00
Jean-Philippe Lang
192b9008bd fixed: error on feeds/news when no news exist
git-svn-id: http://redmine.rubyforge.org/svn/trunk@336 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-15 19:20:49 +00:00
Jean-Philippe Lang
56d0af472d removed project_id presence validation on wiki model which was failing when creating a project with a wiki
git-svn-id: http://redmine.rubyforge.org/svn/trunk@335 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-14 17:23:38 +00:00
Jean-Philippe Lang
85f32b956f added italian translation [Alessio Spadaro]
git-svn-id: http://redmine.rubyforge.org/svn/trunk@334 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-12 18:34:25 +00:00
Jean-Philippe Lang
027bf93849 added svn:eol-style native property on /app files
git-svn-id: http://redmine.rubyforge.org/svn/trunk@333 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-12 17:59:02 +00:00
Jean-Philippe Lang
071f8e18d0 fixed #9207 Can't Save Changes to Project
git-svn-id: http://redmine.rubyforge.org/svn/trunk@332 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-12 17:33:20 +00:00
Jean-Philippe Lang
19d962c3aa added svn:executable property on the scripts
git-svn-id: http://redmine.rubyforge.org/svn/trunk@331 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-12 17:29:04 +00:00
Jean-Philippe Lang
dae2d4686e width of all wiki content textareas set to 99.5%
git-svn-id: http://redmine.rubyforge.org/svn/trunk@329 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-11 14:22:53 +00:00
Jean-Philippe Lang
fc3ee67b1f send a 404 when trying to access an unexisting repository
git-svn-id: http://redmine.rubyforge.org/svn/trunk@328 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-11 14:06:05 +00:00
Jean-Philippe Lang
a54a15523b wiki:
* added "Heading" and "Inline quote" buttons to the toolbar
* changed "Link" button behaviour (now produces [[Link]])
* added a simple help on text formatting

git-svn-id: http://redmine.rubyforge.org/svn/trunk@327 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-11 14:00:15 +00:00
Jean-Philippe Lang
5b135c07d0 fixed the "preview" link on wiki/edit
git-svn-id: http://redmine.rubyforge.org/svn/trunk@326 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-10 15:46:34 +00:00
Jean-Philippe Lang
dd83445fd7 extended the search to wiki content
git-svn-id: http://redmine.rubyforge.org/svn/trunk@325 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-10 15:34:38 +00:00
Jean-Philippe Lang
290485b144 added missing calendar-ja.js, partially translated
git-svn-id: http://redmine.rubyforge.org/svn/trunk@324 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-10 15:20:37 +00:00
Jean-Philippe Lang
c514316a2e wiki branch merged into trunk
git-svn-id: http://redmine.rubyforge.org/svn/trunk@323 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-10 15:09:49 +00:00
Jean-Philippe Lang
8b98ceb92c improved search engine
* it's now possible to search for multiple words ("all words" or "one of the words" options)
* added a fixed limit for result count

git-svn-id: http://redmine.rubyforge.org/svn/trunk@321 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-10 13:32:04 +00:00
Jean-Philippe Lang
7a20a4d32b feature #9137 Password-protected SVN repositories
* added login and password attributes on repositories
* fixed svn calls (svn waiting for user input)

git-svn-id: http://redmine.rubyforge.org/svn/trunk@319 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-09 18:03:31 +00:00
Jean-Philippe Lang
8cbb78bb1d patch #9104 Disable cleartext logging of passwords in log files
git-svn-id: http://redmine.rubyforge.org/svn/trunk@310 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-07 17:59:41 +00:00
Jean-Philippe Lang
ef84339003 fixed #9097: Minor rendering problem within Safari at admin/mail_options and roles permissions
git-svn-id: http://redmine.rubyforge.org/svn/trunk@308 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-06 22:46:58 +00:00
Jean-Philippe Lang
909954ac34 fixed dotted hr for IE6
git-svn-id: http://redmine.rubyforge.org/svn/trunk@305 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-06 18:45:08 +00:00
Jean-Philippe Lang
d996643540 adjusted the attachment date column width on pdf issue export to avoid overlapping in japanese
git-svn-id: http://redmine.rubyforge.org/svn/trunk@302 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-05 19:00:16 +00:00
Jean-Philippe Lang
074a4a6e0e fixed #9005: administration-menu doesn't work with prefix-url
git-svn-id: http://redmine.rubyforge.org/svn/trunk@289 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-03 17:35:11 +00:00
Jean-Philippe Lang
a6248cba19 added missing field_is_in_roadmap key in lang files
git-svn-id: http://redmine.rubyforge.org/svn/trunk@288 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-03 10:22:38 +00:00
Jean-Philippe Lang
6a875eb691 fix for #8973: Export feature(to csv/pdf) doesn't work in Japanese
csv and pdf encoding are know defined for each language (general_csv_encoding and general_pdf_encoding keys in lang files)
added SJIS font for japanese pdf exports

git-svn-id: http://redmine.rubyforge.org/svn/trunk@287 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-03-01 19:49:04 +00:00
Jean-Philippe Lang
83c96d4f3e search engine improvements and simple test
git-svn-id: http://redmine.rubyforge.org/svn/trunk@285 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-28 22:35:22 +00:00
Jean-Philippe Lang
1fcc9e977f updated supported language count in test (now 5)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@284 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-28 22:32:45 +00:00
Jean-Philippe Lang
c56b95ed68 patch #8936: Properties changes in a diff are showing as modifications to files
git-svn-id: http://redmine.rubyforge.org/svn/trunk@283 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-28 19:33:07 +00:00
Jean-Philippe Lang
bb3a5bcfd7 patch #8937: Show filename above diff to aid reading multi-file diffs
git-svn-id: http://redmine.rubyforge.org/svn/trunk@282 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-28 19:26:53 +00:00
Jean-Philippe Lang
35678a1c09 brackets removed around "View all changes" on issues/show
git-svn-id: http://redmine.rubyforge.org/svn/trunk@281 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-27 22:07:42 +00:00
Jean-Philippe Lang
c622ad0b50 #8911 Textile formatting for issue notes
git-svn-id: http://redmine.rubyforge.org/svn/trunk@280 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-27 22:07:01 +00:00
Jean-Philippe Lang
75324e4859 added a simple search engine. left to do:
- full content search (only subject/titles for now)
- pagination
- results presentation improvement

git-svn-id: http://redmine.rubyforge.org/svn/trunk@279 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-27 21:03:15 +00:00
Jean-Philippe Lang
93f07c78d6 japanese translation added (thanks to Satoru Kurashiki)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@278 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-27 17:58:59 +00:00
Jean-Philippe Lang
59a619ebbb fixed #8915: crash when adding a user with a wrong length password
git-svn-id: http://redmine.rubyforge.org/svn/trunk@277 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-27 17:26:25 +00:00
Jean-Philippe Lang
77938cc11e fixed: no diff display with one line files [#8883]
git-svn-id: http://redmine.rubyforge.org/svn/trunk@276 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-26 21:32:16 +00:00
Jean-Philippe Lang
ae998984a0 fixed: unable to update repository url
git-svn-id: http://redmine.rubyforge.org/svn/trunk@275 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-26 19:20:18 +00:00
Jean-Philippe Lang
2e31311e3c "#id" patterns are turned into links to issues in descriptions and commit messages
git-svn-id: http://redmine.rubyforge.org/svn/trunk@274 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-25 19:40:57 +00:00
Jean-Philippe Lang
32782a7f9f added back database adapter name on admin/info
git-svn-id: http://redmine.rubyforge.org/svn/trunk@262 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-20 20:17:34 +00:00
Jean-Philippe Lang
4f2d74e25f fixed: error when clicking "add" with no block selected on my/page_layout
git-svn-id: http://redmine.rubyforge.org/svn/trunk@261 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-02-18 20:20:17 +00:00
1271 changed files with 93387 additions and 17143 deletions

33
app/apis/sys_api.rb Normal file
View File

@@ -0,0 +1,33 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class AWSProjectWithRepository < ActionWebService::Struct
member :id, :int
member :identifier, :string
member :name, :string
member :is_public, :bool
member :repository, Repository
end
class SysApi < ActionWebService::API::Base
api_method :projects_with_repository_enabled,
:expects => [],
:returns => [[AWSProjectWithRepository]]
api_method :repository_created,
:expects => [:string, :string, :string],
:returns => [:int]
end

View File

@@ -1,131 +1,194 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class AccountController < ApplicationController
layout 'base'
helper :custom_fields
include CustomFieldsHelper
# prevents login action to be filtered by check_if_login_required application scope filter
skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register]
before_filter :require_login, :only => :logout
# Show user's account
def show
@user = User.find(params[:id])
@custom_values = @user.custom_values.find(:all, :include => :custom_field)
rescue ActiveRecord::RecordNotFound
render_404
end
# Login request and validation
def login
if request.get?
# Logout user
self.logged_in_user = nil
else
# Authenticate user
user = User.try_to_login(params[:login], params[:password])
if user
self.logged_in_user = user
redirect_back_or_default :controller => 'my', :action => 'page'
else
flash.now[:notice] = l(:notice_account_invalid_creditentials)
end
end
end
# Log out current user and redirect to welcome page
def logout
self.logged_in_user = nil
redirect_to :controller => 'welcome'
end
# Enable user to choose a new password
def lost_password
redirect_to :controller => 'welcome' and return unless Setting.lost_password?
if params[:token]
@token = Token.find_by_action_and_value("recovery", params[:token])
redirect_to :controller => 'welcome' and return unless @token and !@token.expired?
@user = @token.user
if request.post?
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
if @user.save
@token.destroy
flash[:notice] = l(:notice_account_password_updated)
redirect_to :action => 'login'
return
end
end
render :template => "account/password_recovery"
return
else
if request.post?
user = User.find_by_mail(params[:mail])
# user not found in db
flash.now[:notice] = l(:notice_account_unknown_email) and return unless user
# user uses an external authentification
flash.now[:notice] = l(:notice_can_t_change_password) and return if user.auth_source_id
# create a new token for password recovery
token = Token.new(:user => user, :action => "recovery")
if token.save
Mailer.deliver_lost_password(token)
flash[:notice] = l(:notice_account_lost_email_sent)
redirect_to :action => 'login'
return
end
end
end
end
# User self-registration
def register
redirect_to :controller => 'welcome' and return unless Setting.self_registration?
if params[:token]
token = Token.find_by_action_and_value("register", params[:token])
redirect_to :controller => 'welcome' and return unless token and !token.expired?
user = token.user
redirect_to :controller => 'welcome' and return unless user.status == User::STATUS_REGISTERED
user.status = User::STATUS_ACTIVE
if user.save
token.destroy
flash[:notice] = l(:notice_account_activated)
redirect_to :action => 'login'
return
end
else
if request.get?
@user = User.new(:language => Setting.default_language)
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
else
@user = User.new(params[:user])
@user.admin = false
@user.login = params[:user][:login]
@user.status = User::STATUS_REGISTERED
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
token = Token.new(:user => @user, :action => "register")
if @user.save and token.save
Mailer.deliver_register(token)
flash[:notice] = l(:notice_account_register_done)
redirect_to :controller => 'welcome' and return
end
end
end
end
# Redmine - project management software
# Copyright (C) 2006-2008 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.
class AccountController < ApplicationController
helper :custom_fields
include CustomFieldsHelper
# prevents login action to be filtered by check_if_login_required application scope filter
skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register, :activate]
# Show user's account
def show
@user = User.active.find(params[:id])
@custom_values = @user.custom_values
# show only public projects and private projects that the logged in user is also a member of
@memberships = @user.memberships.select do |membership|
membership.project.is_public? || (User.current.member_of?(membership.project))
end
events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 10)
@events_by_day = events.group_by(&:event_date)
rescue ActiveRecord::RecordNotFound
render_404
end
# Login request and validation
def login
if request.get?
# Logout user
self.logged_user = nil
else
# Authenticate user
user = User.try_to_login(params[:username], params[:password])
if user.nil?
# Invalid credentials
flash.now[:error] = l(:notice_account_invalid_creditentials)
elsif user.new_record?
# Onthefly creation failed, display the registration form to fill/fix attributes
@user = user
session[:auth_source_registration] = {:login => user.login, :auth_source_id => user.auth_source_id }
render :action => 'register'
else
# Valid user
self.logged_user = user
# generate a key and set cookie if autologin
if params[:autologin] && Setting.autologin?
token = Token.create(:user => user, :action => 'autologin')
cookies[:autologin] = { :value => token.value, :expires => 1.year.from_now }
end
redirect_back_or_default :controller => 'my', :action => 'page'
end
end
end
# Log out current user and redirect to welcome page
def logout
cookies.delete :autologin
Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin']) if User.current.logged?
self.logged_user = nil
redirect_to home_url
end
# Enable user to choose a new password
def lost_password
redirect_to(home_url) && return unless Setting.lost_password?
if params[:token]
@token = Token.find_by_action_and_value("recovery", params[:token])
redirect_to(home_url) && return unless @token and !@token.expired?
@user = @token.user
if request.post?
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
if @user.save
@token.destroy
flash[:notice] = l(:notice_account_password_updated)
redirect_to :action => 'login'
return
end
end
render :template => "account/password_recovery"
return
else
if request.post?
user = User.find_by_mail(params[:mail])
# user not found in db
flash.now[:error] = l(:notice_account_unknown_email) and return unless user
# user uses an external authentification
flash.now[:error] = l(:notice_can_t_change_password) and return if user.auth_source_id
# create a new token for password recovery
token = Token.new(:user => user, :action => "recovery")
if token.save
Mailer.deliver_lost_password(token)
flash[:notice] = l(:notice_account_lost_email_sent)
redirect_to :action => 'login'
return
end
end
end
end
# User self-registration
def register
redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
if request.get?
session[:auth_source_registration] = nil
@user = User.new(:language => Setting.default_language)
else
@user = User.new(params[:user])
@user.admin = false
@user.status = User::STATUS_REGISTERED
if session[:auth_source_registration]
@user.status = User::STATUS_ACTIVE
@user.login = session[:auth_source_registration][:login]
@user.auth_source_id = session[:auth_source_registration][:auth_source_id]
if @user.save
session[:auth_source_registration] = nil
self.logged_user = @user
flash[:notice] = l(:notice_account_activated)
redirect_to :controller => 'my', :action => 'account'
end
else
@user.login = params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
case Setting.self_registration
when '1'
# Email activation
token = Token.new(:user => @user, :action => "register")
if @user.save and token.save
Mailer.deliver_register(token)
flash[:notice] = l(:notice_account_register_done)
redirect_to :action => 'login'
end
when '3'
# Automatic activation
@user.status = User::STATUS_ACTIVE
if @user.save
self.logged_user = @user
flash[:notice] = l(:notice_account_activated)
redirect_to :controller => 'my', :action => 'account'
end
else
# Manual activation by the administrator
if @user.save
# Sends an email to the administrators
Mailer.deliver_account_activation_request(@user)
flash[:notice] = l(:notice_account_pending)
redirect_to :action => 'login'
end
end
end
end
end
# Token based account activation
def activate
redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
token = Token.find_by_action_and_value('register', params[:token])
redirect_to(home_url) && return unless token and !token.expired?
user = token.user
redirect_to(home_url) && return unless user.status == User::STATUS_REGISTERED
user.status = User::STATUS_ACTIVE
if user.save
token.destroy
flash[:notice] = l(:notice_account_activated)
end
redirect_to :action => 'login'
end
private
def logged_user=(user)
if user && user.is_a?(User)
User.current = user
session[:user_id] = user.id
else
User.current = User.anonymous
session[:user_id] = nil
end
end
end

View File

@@ -1,55 +1,93 @@
# redMine - project management software
# Copyright (C) 2006 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.
class AdminController < ApplicationController
layout 'base'
before_filter :require_admin
helper :sort
include SortHelper
def index
end
def projects
sort_init 'name', 'asc'
sort_update
@project_count = Project.count
@project_pages = Paginator.new self, @project_count,
15,
params['page']
@projects = Project.find :all, :order => sort_clause,
:limit => @project_pages.items_per_page,
:offset => @project_pages.current.offset
render :action => "projects", :layout => false if request.xhr?
end
def mail_options
@actions = Permission.find(:all, :conditions => ["mail_option=?", true]) || []
if request.post?
@actions.each { |a|
a.mail_enabled = (params[:action_ids] || []).include? a.id.to_s
a.save
}
flash.now[:notice] = l(:notice_successful_update)
end
end
def info
end
# redMine - project management software
# Copyright (C) 2006 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.
class AdminController < ApplicationController
before_filter :require_admin
helper :sort
include SortHelper
def index
@no_configuration_data = Redmine::DefaultData::Loader::no_data?
end
def projects
sort_init 'name', 'asc'
sort_update %w(name is_public created_on)
@status = params[:status] ? params[:status].to_i : 1
c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status])
unless params[:name].blank?
name = "%#{params[:name].strip.downcase}%"
c << ["LOWER(identifier) LIKE ? OR LOWER(name) LIKE ?", name, name]
end
@project_count = Project.count(:conditions => c.conditions)
@project_pages = Paginator.new self, @project_count,
per_page_option,
params['page']
@projects = Project.find :all, :order => sort_clause,
:conditions => c.conditions,
:limit => @project_pages.items_per_page,
:offset => @project_pages.current.offset
render :action => "projects", :layout => false if request.xhr?
end
def plugins
@plugins = Redmine::Plugin.all
end
# Loads the default configuration
# (roles, trackers, statuses, workflow, enumerations)
def default_configuration
if request.post?
begin
Redmine::DefaultData::Loader::load(params[:lang])
flash[:notice] = l(:notice_default_data_loaded)
rescue Exception => e
flash[:error] = l(:error_can_t_load_default_data, e.message)
end
end
redirect_to :action => 'index'
end
def test_email
raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
# Force ActionMailer to raise delivery errors so we can catch it
ActionMailer::Base.raise_delivery_errors = true
begin
@test = Mailer.deliver_test(User.current)
flash[:notice] = l(:notice_email_sent, User.current.mail)
rescue Exception => e
flash[:error] = l(:notice_email_error, e.message)
end
ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
redirect_to :controller => 'settings', :action => 'edit', :tab => 'notifications'
end
def info
@db_adapter_name = ActiveRecord::Base.connection.adapter_name
@flags = {
:default_admin_changed => User.find(:first, :conditions => ["login=? and hashed_password=?", 'admin', User.hash_password('admin')]).nil?,
:file_repository_writable => File.writable?(Attachment.storage_path),
:plugin_assets_writable => File.writable?(Engines.public_directory),
:rmagick_available => Object.const_defined?(:Magick)
}
end
end

View File

@@ -1,132 +1,234 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class ApplicationController < ActionController::Base
before_filter :check_if_login_required, :set_localization
def logged_in_user=(user)
@logged_in_user = user
session[:user_id] = (user ? user.id : nil)
end
def logged_in_user
if session[:user_id]
@logged_in_user ||= User.find(session[:user_id])
else
nil
end
end
# check if login is globally required to access the application
def check_if_login_required
require_login if Setting.login_required?
end
def set_localization
lang = begin
if self.logged_in_user and self.logged_in_user.language and !self.logged_in_user.language.empty? and GLoc.valid_languages.include? self.logged_in_user.language.to_sym
self.logged_in_user.language
elsif request.env['HTTP_ACCEPT_LANGUAGE']
accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first
if accept_lang and !accept_lang.empty? and GLoc.valid_languages.include? accept_lang.to_sym
accept_lang
end
end
rescue
nil
end || Setting.default_language
set_language_if_valid(lang)
end
def require_login
unless self.logged_in_user
store_location
redirect_to :controller => "account", :action => "login"
return false
end
true
end
def require_admin
return unless require_login
unless self.logged_in_user.admin?
render :nothing => true, :status => 403
return false
end
true
end
# authorizes the user for the requested action.
def authorize(ctrl = params[:controller], action = params[:action])
# check if action is allowed on public projects
if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ ctrl, action ]
return true
end
# if action is not public, force login
return unless require_login
# admin is always authorized
return true if self.logged_in_user.admin?
# if not admin, check membership permission
@user_membership ||= Member.find(:first, :conditions => ["user_id=? and project_id=?", self.logged_in_user.id, @project.id])
if @user_membership and Permission.allowed_to_role( "%s/%s" % [ ctrl, action ], @user_membership.role_id )
return true
end
render :nothing => true, :status => 403
false
end
# store current uri in session.
# return to this location by calling redirect_back_or_default
def store_location
session[:return_to_params] = params
# redMine - project management software
# Copyright (C) 2006-2007 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 'uri'
require 'cgi'
class ApplicationController < ActionController::Base
layout 'base'
before_filter :user_setup, :check_if_login_required, :set_localization
filter_parameter_logging :password
include Redmine::MenuManager::MenuController
helper Redmine::MenuManager::MenuHelper
REDMINE_SUPPORTED_SCM.each do |scm|
require_dependency "repository/#{scm.underscore}"
end
def current_role
@current_role ||= User.current.role_for_project(@project)
end
def user_setup
# Check the settings cache for each request
Setting.check_cache
# Find the current user
User.current = find_current_user
end
# Returns the current user or nil if no user is logged in
def find_current_user
if session[:user_id]
# existing session
(User.active.find(session[:user_id]) rescue nil)
elsif cookies[:autologin] && Setting.autologin?
# auto-login feature
User.find_by_autologin_key(cookies[:autologin])
elsif params[:key] && accept_key_auth_actions.include?(params[:action])
# RSS key authentication
User.find_by_rss_key(params[:key])
end
end
# check if login is globally required to access the application
def check_if_login_required
# no check needed if user is already logged in
return true if User.current.logged?
require_login if Setting.login_required?
end
def set_localization
User.current.language = nil unless User.current.logged?
lang = begin
if !User.current.language.blank? && GLoc.valid_language?(User.current.language)
User.current.language
elsif request.env['HTTP_ACCEPT_LANGUAGE']
accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
if !accept_lang.blank? && (GLoc.valid_language?(accept_lang) || GLoc.valid_language?(accept_lang = accept_lang.split('-').first))
User.current.language = accept_lang
end
end
rescue
nil
end || Setting.default_language
set_language_if_valid(lang)
end
def require_login
if !User.current.logged?
redirect_to :controller => "account", :action => "login", :back_url => url_for(params)
return false
end
true
end
# move to the last store_location call or to the passed default one
def redirect_back_or_default(default)
if session[:return_to_params].nil?
redirect_to default
else
redirect_to session[:return_to_params]
session[:return_to_params] = nil
def require_admin
return unless require_login
if !User.current.admin?
render_403
return false
end
end
def render_404
@html_title = "404"
render :template => "common/404", :layout => true, :status => 404
return false
true
end
# qvalues http header parser
# code taken from webrick
def parse_qvalues(value)
tmp = []
if value
parts = value.split(/,\s*/)
parts.each {|part|
if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
val = m[1]
q = (m[2] or 1).to_f
tmp.push([val, q])
end
}
tmp = tmp.sort_by{|val, q| -q}
tmp.collect!{|val, q| val}
end
return tmp
end
end
def deny_access
User.current.logged? ? render_403 : require_login
end
# Authorize the user for the requested action
def authorize(ctrl = params[:controller], action = params[:action])
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project)
allowed ? true : deny_access
end
# make sure that the user is a member of the project (or admin) if project is private
# used as a before_filter for actions that do not require any particular permission on the project
def check_project_privacy
if @project && @project.active?
if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
true
else
User.current.logged? ? render_403 : require_login
end
else
@project = nil
render_404
false
end
end
def redirect_back_or_default(default)
back_url = CGI.unescape(params[:back_url].to_s)
if !back_url.blank?
begin
uri = URI.parse(back_url)
# 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)})
redirect_to(back_url) and return
end
rescue URI::InvalidURIError
# redirect to default
end
end
redirect_to default
end
def render_403
@project = nil
render :template => "common/403", :layout => !request.xhr?, :status => 403
return false
end
def render_404
render :template => "common/404", :layout => !request.xhr?, :status => 404
return false
end
def render_error(msg)
flash.now[:error] = msg
render :nothing => true, :layout => !request.xhr?, :status => 500
end
def render_feed(items, options={})
@items = items || []
@items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
@items = @items.slice(0, Setting.feeds_limit.to_i)
@title = options[:title] || Setting.app_title
render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
end
def self.accept_key_auth(*actions)
actions = actions.flatten.map(&:to_s)
write_inheritable_attribute('accept_key_auth_actions', actions)
end
def accept_key_auth_actions
self.class.read_inheritable_attribute('accept_key_auth_actions') || []
end
# TODO: move to model
def attach_files(obj, attachments)
attached = []
unsaved = []
if attachments && attachments.is_a?(Hash)
attachments.each_value do |attachment|
file = attachment['file']
next unless file && file.size > 0
a = Attachment.create(:container => obj,
:file => file,
:description => attachment['description'].to_s.strip,
:author => User.current)
a.new_record? ? (unsaved << a) : (attached << a)
end
if unsaved.any?
flash[:warning] = l(:warning_attachments_not_saved, unsaved.size)
end
end
attached
end
# Returns the number of objects that should be displayed
# on the paginated list
def per_page_option
per_page = nil
if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
per_page = params[:per_page].to_s.to_i
session[:per_page] = per_page
elsif session[:per_page]
per_page = session[:per_page]
else
per_page = Setting.per_page_options_array.first || 25
end
per_page
end
# qvalues http header parser
# code taken from webrick
def parse_qvalues(value)
tmp = []
if value
parts = value.split(/,\s*/)
parts.each {|part|
if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
val = m[1]
q = (m[2] or 1).to_f
tmp.push([val, q])
end
}
tmp = tmp.sort_by{|val, q| -q}
tmp.collect!{|val, q| val}
end
return tmp
end
# Returns a string that can be used as filename value in Content-Disposition header
def filename_for_content_disposition(name)
request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
end
end

View File

@@ -0,0 +1,74 @@
# Redmine - project management software
# Copyright (C) 2006-2008 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.
class AttachmentsController < ApplicationController
before_filter :find_project
before_filter :read_authorize, :except => :destroy
before_filter :delete_authorize, :only => :destroy
verify :method => :post, :only => :destroy
def show
if @attachment.is_diff?
@diff = File.new(@attachment.diskfile, "rb").read
render :action => 'diff'
elsif @attachment.is_text?
@content = File.new(@attachment.diskfile, "rb").read
render :action => 'file'
elsif
download
end
end
def download
if @attachment.container.is_a?(Version) || @attachment.container.is_a?(Project)
@attachment.increment_download
end
# images are sent inline
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
:type => @attachment.content_type,
:disposition => (@attachment.image? ? 'inline' : 'attachment')
end
def destroy
# Make sure association callbacks are called
@attachment.container.attachments.delete(@attachment)
redirect_to :back
rescue ::ActionController::RedirectBackError
redirect_to :controller => 'projects', :action => 'show', :id => @project
end
private
def find_project
@attachment = Attachment.find(params[:id])
# Show 404 if the filename in the url is wrong
raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename
@project = @attachment.project
rescue ActiveRecord::RecordNotFound
render_404
end
def read_authorize
@attachment.visible? ? true : deny_access
end
def delete_authorize
@attachment.deletable? ? true : deny_access
end
end

View File

@@ -16,7 +16,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class AuthSourcesController < ApplicationController
layout 'base'
before_filter :require_admin
def index
@@ -65,10 +64,10 @@ class AuthSourcesController < ApplicationController
@auth_method = AuthSource.find(params[:id])
begin
@auth_method.test_connection
flash[:notice] = l(:notice_successful_connection)
rescue => text
flash[:notice] = text
flash[:error] = "Unable to connect (#{text})"
end
flash[:notice] ||= l(:notice_successful_connection)
redirect_to :action => 'list'
end

View File

@@ -0,0 +1,87 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class BoardsController < ApplicationController
before_filter :find_project, :authorize
helper :messages
include MessagesHelper
helper :sort
include SortHelper
helper :watchers
include WatchersHelper
def index
@boards = @project.boards
# show the board if there is only one
if @boards.size == 1
@board = @boards.first
show
end
end
def show
sort_init 'updated_on', 'desc'
sort_update 'created_on' => "#{Message.table_name}.created_on",
'replies' => "#{Message.table_name}.replies_count",
'updated_on' => "#{Message.table_name}.updated_on"
@topic_count = @board.topics.count
@topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
@topics = @board.topics.find :all, :order => ["#{Message.table_name}.sticky DESC", sort_clause].compact.join(', '),
:include => [:author, {:last_reply => :author}],
:limit => @topic_pages.items_per_page,
:offset => @topic_pages.current.offset
render :action => 'show', :layout => !request.xhr?
end
verify :method => :post, :only => [ :destroy ], :redirect_to => { :action => :index }
def new
@board = Board.new(params[:board])
@board.project = @project
if request.post? && @board.save
flash[:notice] = l(:notice_successful_create)
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'boards'
end
end
def edit
if request.post? && @board.update_attributes(params[:board])
case params[:position]
when 'highest'; @board.move_to_top
when 'higher'; @board.move_higher
when 'lower'; @board.move_lower
when 'lowest'; @board.move_to_bottom
end if params[:position]
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'boards'
end
end
def destroy
@board.destroy
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'boards'
end
private
def find_project
@project = Project.find(params[:project_id])
@board = @project.boards.find(params[:id]) if params[:id]
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -1,23 +1,22 @@
# redMine - project management software
# Copyright (C) 2006 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.
class CustomFieldsController < ApplicationController
layout 'base'
before_filter :require_admin
# redMine - project management software
# Copyright (C) 2006 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.
class CustomFieldsController < ApplicationController
before_filter :require_admin
def index
list
@@ -25,48 +24,65 @@ class CustomFieldsController < ApplicationController
end
def list
@custom_fields_by_type = CustomField.find(:all).group_by {|f| f.type.to_s }
@tab = params[:tab] || 'IssueCustomField'
@custom_fields_by_type = CustomField.find(:all).group_by {|f| f.class.name }
@tab = params[:tab] || 'IssueCustomField'
render :action => "list", :layout => false if request.xhr?
end
def new
case params[:type]
when "IssueCustomField"
@custom_field = IssueCustomField.new(params[:custom_field])
@custom_field.trackers = Tracker.find(params[:tracker_ids]) if params[:tracker_ids]
when "UserCustomField"
@custom_field = UserCustomField.new(params[:custom_field])
when "ProjectCustomField"
@custom_field = ProjectCustomField.new(params[:custom_field])
else
redirect_to :action => 'list'
return
end
if request.post? and @custom_field.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list', :tab => @custom_field.type
end
@trackers = Tracker.find(:all, :order => 'position')
end
def edit
@custom_field = CustomField.find(params[:id])
if request.post? and @custom_field.update_attributes(params[:custom_field])
if @custom_field.is_a? IssueCustomField
@custom_field.trackers = params[:tracker_ids] ? Tracker.find(params[:tracker_ids]) : []
end
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list', :tab => @custom_field.type
end
@trackers = Tracker.find(:all, :order => 'position')
end
def new
case params[:type]
when "IssueCustomField"
@custom_field = IssueCustomField.new(params[:custom_field])
@custom_field.trackers = Tracker.find(params[:tracker_ids]) if params[:tracker_ids]
when "UserCustomField"
@custom_field = UserCustomField.new(params[:custom_field])
when "ProjectCustomField"
@custom_field = ProjectCustomField.new(params[:custom_field])
when "TimeEntryCustomField"
@custom_field = TimeEntryCustomField.new(params[:custom_field])
else
redirect_to :action => 'list'
return
end
if request.post? and @custom_field.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list', :tab => @custom_field.class.name
end
@trackers = Tracker.find(:all, :order => 'position')
end
def edit
@custom_field = CustomField.find(params[:id])
if request.post? and @custom_field.update_attributes(params[:custom_field])
if @custom_field.is_a? IssueCustomField
@custom_field.trackers = params[:tracker_ids] ? Tracker.find(params[:tracker_ids]) : []
end
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list', :tab => @custom_field.class.name
end
@trackers = Tracker.find(:all, :order => 'position')
end
def move
@custom_field = CustomField.find(params[:id])
case params[:position]
when 'highest'
@custom_field.move_to_top
when 'higher'
@custom_field.move_higher
when 'lower'
@custom_field.move_lower
when 'lowest'
@custom_field.move_to_bottom
end if params[:position]
redirect_to :action => 'list', :tab => @custom_field.class.name
end
def destroy
@custom_field = CustomField.find(params[:id]).destroy
redirect_to :action => 'list', :tab => @custom_field.type
rescue
flash[:notice] = "Unable to delete custom field"
@custom_field = CustomField.find(params[:id]).destroy
redirect_to :action => 'list', :tab => @custom_field.class.name
rescue
flash[:error] = "Unable to delete custom field"
redirect_to :action => 'list'
end
end
end

View File

@@ -1,71 +1,88 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class DocumentsController < ApplicationController
layout 'base'
before_filter :find_project, :authorize
# redMine - project management software
# Copyright (C) 2006-2007 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.
def show
class DocumentsController < ApplicationController
before_filter :find_project, :only => [:index, :new]
before_filter :find_document, :except => [:index, :new]
before_filter :authorize
helper :attachments
def index
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
documents = @project.documents.find :all, :include => [:attachments, :category]
case @sort_by
when 'date'
@grouped = documents.group_by {|d| d.created_on.to_date }
when 'title'
@grouped = documents.group_by {|d| d.title.first.upcase}
when 'author'
@grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
else
@grouped = documents.group_by(&:category)
end
@document = @project.documents.build
render :layout => false if request.xhr?
end
def show
@attachments = @document.attachments.find(:all, :order => "created_on DESC")
end
def edit
def new
@document = @project.documents.build(params[:document])
if request.post? and @document.save
attach_files(@document, params[:attachments])
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_document_added(@document) if Setting.notified_events.include?('document_added')
redirect_to :action => 'index', :project_id => @project
end
end
def edit
@categories = Enumeration::get_values('DCAT')
if request.post? and @document.update_attributes(params[:document])
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'show', :id => @document
end
end
end
def destroy
@document.destroy
redirect_to :controller => 'projects', :action => 'list_documents', :id => @project
end
def download
@attachment = @document.attachments.find(params[:attachment_id])
@attachment.increment_download
send_file @attachment.diskfile, :filename => @attachment.filename
rescue
render_404
end
def add_attachment
# Save the attachments
@attachments = []
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @document, :file => file, :author => logged_in_user)
@attachments << a unless a.new_record?
} if params[:attachments] and params[:attachments].is_a? Array
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
redirect_to :action => 'show', :id => @document
end
def destroy_attachment
@document.attachments.find(params[:attachment_id]).destroy
redirect_to :action => 'show', :id => @document
redirect_to :controller => 'documents', :action => 'index', :project_id => @project
end
def add_attachment
attachments = attach_files(@document, params[:attachments])
Mailer.deliver_attachments_added(attachments) if !attachments.empty? && Setting.notified_events.include?('document_added')
redirect_to :action => 'show', :id => @document
end
private
def find_project
@project = Project.find(params[:project_id])
rescue ActiveRecord::RecordNotFound
render_404
end
def find_document
@document = Document.find(params[:id])
@project = @document.project
rescue ActiveRecord::RecordNotFound
render_404
end
private
def find_project
@document = Document.find(params[:id])
@project = @document.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -1,23 +1,22 @@
# redMine - project management software
# Copyright (C) 2006 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.
class EnumerationsController < ApplicationController
layout 'base'
before_filter :require_admin
# redMine - project management software
# Copyright (C) 2006 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.
class EnumerationsController < ApplicationController
before_filter :require_admin
def index
list
@@ -59,12 +58,36 @@ class EnumerationsController < ApplicationController
end
end
def move
@enumeration = Enumeration.find(params[:id])
case params[:position]
when 'highest'
@enumeration.move_to_top
when 'higher'
@enumeration.move_higher
when 'lower'
@enumeration.move_lower
when 'lowest'
@enumeration.move_to_bottom
end if params[:position]
redirect_to :action => 'index'
end
def destroy
Enumeration.find(params[:id]).destroy
flash[:notice] = l(:notice_successful_delete)
redirect_to :action => 'list'
rescue
flash[:notice] = "Unable to delete enumeration"
redirect_to :action => 'list'
@enumeration = Enumeration.find(params[:id])
if !@enumeration.in_use?
# No associated objects
@enumeration.destroy
redirect_to :action => 'index'
elsif params[:reassign_to_id]
if reassign_to = Enumeration.find_by_opt_and_id(@enumeration.opt, params[:reassign_to_id])
@enumeration.destroy(reassign_to)
redirect_to :action => 'index'
end
end
@enumerations = Enumeration.get_values(@enumeration.opt) - [@enumeration]
#rescue
# flash[:error] = 'Unable to delete enumeration'
# redirect_to :action => 'index'
end
end

View File

@@ -1,47 +0,0 @@
# redMine - project management software
# Copyright (C) 2006 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.
class HelpController < ApplicationController
skip_before_filter :check_if_login_required
before_filter :load_help_config
# displays help page for the requested controller/action
def index
# select help page to display
if params[:ctrl] and @help_config['pages'][params[:ctrl]]
if params[:page] and @help_config['pages'][params[:ctrl]][params[:page]]
template = @help_config['pages'][params[:ctrl]][params[:page]]
else
template = @help_config['pages'][params[:ctrl]]['index']
end
end
# choose language according to available help translations
lang = (@help_config['langs'].include? current_language.to_s) ? current_language.to_s : @help_config['langs'].first
if template
redirect_to "/manual/#{lang}/#{template}"
else
redirect_to "/manual/#{lang}/index.html"
end
end
private
def load_help_config
@help_config = YAML::load(File.open("#{RAILS_ROOT}/config/help.yml"))
end
end

View File

@@ -1,24 +1,26 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
class IssueCategoriesController < ApplicationController
layout 'base'
before_filter :find_project, :authorize
menu_item :settings
before_filter :find_project, :authorize
verify :method => :post, :only => :destroy
def edit
if request.post? and @category.update_attributes(params[:category])
flash[:notice] = l(:notice_successful_update)
@@ -27,18 +29,24 @@ class IssueCategoriesController < ApplicationController
end
def destroy
@category.destroy
redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project
rescue
flash[:notice] = "Categorie can't be deleted"
redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project
end
@issue_count = @category.issues.size
if @issue_count == 0
# No issue assigned to this category
@category.destroy
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories'
elsif params[:todo]
reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id]) if params[:todo] == 'reassign'
@category.destroy(reassign_to)
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories'
end
@categories = @project.issue_categories - [@category]
end
private
def find_project
@category = IssueCategory.find(params[:id])
@project = @category.project
rescue ActiveRecord::RecordNotFound
render_404
end
private
def find_project
@category = IssueCategory.find(params[:id])
@project = @category.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -0,0 +1,58 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class IssueRelationsController < ApplicationController
before_filter :find_project, :authorize
def new
@relation = IssueRelation.new(params[:relation])
@relation.issue_from = @issue
@relation.save if request.post?
respond_to do |format|
format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
format.js do
render :update do |page|
page.replace_html "relations", :partial => 'issues/relations'
if @relation.errors.empty?
page << "$('relation_delay').value = ''"
page << "$('relation_issue_to_id').value = ''"
end
end
end
end
end
def destroy
relation = IssueRelation.find(params[:id])
if request.post? && @issue.relations.include?(relation)
relation.destroy
@issue.reload
end
respond_to do |format|
format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
format.js { render(:update) {|page| page.replace_html "relations", :partial => 'issues/relations'} }
end
end
private
def find_project
@issue = Issue.find(params[:issue_id])
@project = @issue.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -1,34 +1,33 @@
# redMine - project management software
# Copyright (C) 2006 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.
class IssueStatusesController < ApplicationController
layout 'base'
before_filter :require_admin
verify :method => :post, :only => [ :destroy, :create, :update, :move ],
:redirect_to => { :action => :list }
# redMine - project management software
# Copyright (C) 2006 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.
class IssueStatusesController < ApplicationController
before_filter :require_admin
verify :method => :post, :only => [ :destroy, :create, :update, :move ],
:redirect_to => { :action => :list }
def index
list
render :action => 'list' unless request.xhr?
end
def list
@issue_status_pages, @issue_statuses = paginate :issue_statuses, :per_page => 25, :order => "position"
@issue_status_pages, @issue_statuses = paginate :issue_statuses, :per_page => 25, :order => "position"
render :action => "list", :layout => false if request.xhr?
end
@@ -58,28 +57,28 @@ class IssueStatusesController < ApplicationController
else
render :action => 'edit'
end
end
def move
@issue_status = IssueStatus.find(params[:id])
case params[:position]
when 'highest'
@issue_status.move_to_top
when 'higher'
@issue_status.move_higher
when 'lower'
@issue_status.move_lower
when 'lowest'
@issue_status.move_to_bottom
end if params[:position]
redirect_to :action => 'list'
end
def move
@issue_status = IssueStatus.find(params[:id])
case params[:position]
when 'highest'
@issue_status.move_to_top
when 'higher'
@issue_status.move_higher
when 'lower'
@issue_status.move_lower
when 'lowest'
@issue_status.move_to_bottom
end if params[:position]
redirect_to :action => 'list'
end
def destroy
IssueStatus.find(params[:id]).destroy
redirect_to :action => 'list'
rescue
flash[:notice] = "Unable to delete issue status"
redirect_to :action => 'list'
rescue
flash[:error] = "Unable to delete issue status"
redirect_to :action => 'list'
end
end

View File

@@ -1,149 +1,487 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class IssuesController < ApplicationController
layout 'base', :except => :export_pdf
before_filter :find_project, :authorize
helper :custom_fields
include CustomFieldsHelper
helper :ifpdf
include IfpdfHelper
# Redmine - project management software
# Copyright (C) 2006-2008 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.
class IssuesController < ApplicationController
menu_item :new_issue, :only => :new
before_filter :find_issue, :only => [:show, :edit, :reply]
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
before_filter :find_project, :only => [:new, :update_form, :preview]
before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu]
before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
accept_key_auth :index, :changes
helper :journals
helper :projects
include ProjectsHelper
helper :custom_fields
include CustomFieldsHelper
helper :issue_relations
include IssueRelationsHelper
helper :watchers
include WatchersHelper
helper :attachments
include AttachmentsHelper
helper :queries
helper :sort
include SortHelper
include IssuesHelper
helper :timelog
include Redmine::Export::PDF
def index
retrieve_query
sort_init 'id', 'desc'
sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h}))
if @query.valid?
limit = per_page_option
respond_to do |format|
format.html { }
format.atom { }
format.csv { limit = Setting.issues_export_limit.to_i }
format.pdf { limit = Setting.issues_export_limit.to_i }
end
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, limit, params['page']
@issues = Issue.find :all, :order => sort_clause,
:include => [ :assigned_to, :status, :tracker, :project, :priority, :category, :fixed_version ],
:conditions => @query.statement,
:limit => limit,
:offset => @issue_pages.current.offset
respond_to do |format|
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
format.pdf { send_data(issues_to_pdf(@issues, @project), :type => 'application/pdf', :filename => 'export.pdf') }
end
else
# Send html if the query is not valid
render(:template => 'issues/index.rhtml', :layout => !request.xhr?)
end
rescue ActiveRecord::RecordNotFound
render_404
end
def changes
retrieve_query
sort_init 'id', 'desc'
sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h}))
if @query.valid?
@journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
:conditions => @query.statement,
:limit => 25,
:order => "#{Journal.table_name}.created_on DESC"
end
@title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
render :layout => false, :content_type => 'application/atom+xml'
rescue ActiveRecord::RecordNotFound
render_404
end
def show
@status_options = @issue.status.workflows.find(:all, :order => 'position', :include => :new_status, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
@custom_values = @issue.custom_values.find(:all, :include => :custom_field)
@journals_count = @issue.journals.count
@journals = @issue.journals.find(:all, :include => [:user, :details], :limit => 15, :order => "journals.created_on desc")
end
def history
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "journals.created_on desc")
@journals_count = @journals.length
end
def export_pdf
@custom_values = @issue.custom_values.find(:all, :include => :custom_field)
@options_for_rfpdf ||= {}
@options_for_rfpdf[:file_name] = "#{@project.name}_#{@issue.long_id}.pdf"
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
@journals.each_with_index {|j,i| j.indice = i+1}
@journals.reverse! if User.current.wants_comments_in_reverse_order?
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
@priorities = Enumeration::get_values('IPRI')
@time_entry = TimeEntry.new
respond_to do |format|
format.html { render :template => 'issues/show.rhtml' }
format.atom { render :action => 'changes', :layout => false, :content_type => 'application/atom+xml' }
format.pdf { send_data(issue_to_pdf(@issue), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") }
end
end
def edit
@priorities = Enumeration::get_values('IPRI')
if request.get?
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
else
begin
@issue.init_journal(self.logged_in_user)
# Retrieve custom fields and values
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
@issue.custom_values = @custom_values
@issue.attributes = params[:issue]
if @issue.save
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'show', :id => @issue
end
rescue ActiveRecord::StaleObjectError
# Optimistic locking exception
flash[:notice] = l(:notice_locking_conflict)
end
end
end
def add_note
unless params[:notes].empty?
journal = @issue.init_journal(self.logged_in_user, params[:notes])
#@history = @issue.histories.build(params[:history])
#@history.author_id = self.logged_in_user.id if self.logged_in_user
#@history.status = @issue.status
if @issue.save
flash[:notice] = l(:notice_successful_update)
Mailer.deliver_issue_edit(journal) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
redirect_to :action => 'show', :id => @issue
return
end
end
show
render :action => 'show'
end
def change_status
#@history = @issue.histories.build(params[:history])
@status_options = @issue.status.workflows.find(:all, :order => 'position', :include => :new_status, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
@new_status = IssueStatus.find(params[:new_status_id])
if params[:confirm]
begin
#@history.author_id = self.logged_in_user.id if self.logged_in_user
#@issue.status = @history.status
#@issue.fixed_version_id = (params[:issue][:fixed_version_id])
#@issue.assigned_to_id = (params[:issue][:assigned_to_id])
#@issue.done_ratio = (params[:issue][:done_ratio])
#@issue.lock_version = (params[:issue][:lock_version])
journal = @issue.init_journal(self.logged_in_user, params[:notes])
@issue.status = @new_status
if @issue.update_attributes(params[:issue])
flash[:notice] = l(:notice_successful_update)
Mailer.deliver_issue_edit(journal) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
redirect_to :action => 'show', :id => @issue
end
rescue ActiveRecord::StaleObjectError
# Optimistic locking exception
flash[:notice] = l(:notice_locking_conflict)
end
end
@assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user }
# Add a new issue
# The new issue will be created from an existing one if copy_from parameter is given
def new
@issue = Issue.new
@issue.copy_from(params[:copy_from]) if params[:copy_from]
@issue.project = @project
# Tracker must be set before custom field values
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
if @issue.tracker.nil?
flash.now[:error] = 'No tracker is associated to this project. Please check the Project settings.'
render :nothing => true, :layout => true
return
end
if params[:issue].is_a?(Hash)
@issue.attributes = params[:issue]
@issue.watcher_user_ids = params[:issue]['watcher_user_ids'] if User.current.allowed_to?(:add_issue_watchers, @project)
end
@issue.author = User.current
default_status = IssueStatus.default
unless default_status
flash.now[:error] = 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
render :nothing => true, :layout => true
return
end
@issue.status = default_status
@allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)).uniq
if request.get? || request.xhr?
@issue.start_date ||= Date.today
else
requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
# Check that the user is allowed to apply the requested status
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
if @issue.save
attach_files(@issue, params[:attachments])
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
redirect_to(params[:continue] ? { :action => 'new', :tracker_id => @issue.tracker } :
{ :action => 'show', :id => @issue })
return
end
end
@priorities = Enumeration::get_values('IPRI')
render :layout => !request.xhr?
end
# Attributes that can be updated on workflow transition (without :edit permission)
# TODO: make it configurable (at least per role)
UPDATABLE_ATTRS_ON_TRANSITION = %w(status_id assigned_to_id fixed_version_id done_ratio) unless const_defined?(:UPDATABLE_ATTRS_ON_TRANSITION)
def edit
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
@priorities = Enumeration::get_values('IPRI')
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
@time_entry = TimeEntry.new
@notes = params[:notes]
journal = @issue.init_journal(User.current, @notes)
# User can change issue attributes only if he has :edit permission or if a workflow transition is allowed
if (@edit_allowed || !@allowed_statuses.empty?) && params[:issue]
attrs = params[:issue].dup
attrs.delete_if {|k,v| !UPDATABLE_ATTRS_ON_TRANSITION.include?(k) } unless @edit_allowed
attrs.delete(:status_id) unless @allowed_statuses.detect {|s| s.id.to_s == attrs[:status_id].to_s}
@issue.attributes = attrs
end
if request.post?
@time_entry = TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
@time_entry.attributes = params[:time_entry]
attachments = attach_files(@issue, params[:attachments])
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
call_hook(:controller_issues_edit_before_save, { :params => params, :issue => @issue, :time_entry => @time_entry, :journal => journal})
if (@time_entry.hours.nil? || @time_entry.valid?) && @issue.save
# Log spend time
if User.current.allowed_to?(:log_time, @project)
@time_entry.save
end
if !journal.new_record?
# Only send notification if something was actually changed
flash[:notice] = l(:notice_successful_update)
Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
end
redirect_to(params[:back_to] || {:action => 'show', :id => @issue})
end
end
rescue ActiveRecord::StaleObjectError
# Optimistic locking exception
flash.now[:error] = l(:notice_locking_conflict)
end
def reply
journal = Journal.find(params[:journal_id]) if params[:journal_id]
if journal
user = journal.user
text = journal.notes
else
user = @issue.author
text = @issue.description
end
content = "#{ll(Setting.default_language, :text_user_wrote, user)}\\n> "
content << text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub('"', '\"').gsub(/(\r?\n|\r\n?)/, "\\n> ") + "\\n\\n"
render(:update) { |page|
page.<< "$('notes').value = \"#{content}\";"
page.show 'update'
page << "Form.Element.focus('notes');"
page << "Element.scrollTo('update');"
page << "$('notes').scrollTop = $('notes').scrollHeight - $('notes').clientHeight;"
}
end
# Bulk edit a set of issues
def bulk_edit
if request.post?
status = params[:status_id].blank? ? nil : IssueStatus.find_by_id(params[:status_id])
priority = params[:priority_id].blank? ? nil : Enumeration.find_by_id(params[:priority_id])
assigned_to = (params[:assigned_to_id].blank? || params[:assigned_to_id] == 'none') ? nil : User.find_by_id(params[:assigned_to_id])
category = (params[:category_id].blank? || params[:category_id] == 'none') ? nil : @project.issue_categories.find_by_id(params[:category_id])
fixed_version = (params[:fixed_version_id].blank? || params[:fixed_version_id] == 'none') ? nil : @project.versions.find_by_id(params[:fixed_version_id])
unsaved_issue_ids = []
@issues.each do |issue|
journal = issue.init_journal(User.current, params[:notes])
issue.priority = priority if priority
issue.assigned_to = assigned_to if assigned_to || params[:assigned_to_id] == 'none'
issue.category = category if category || params[:category_id] == 'none'
issue.fixed_version = fixed_version if fixed_version || params[:fixed_version_id] == 'none'
issue.start_date = params[:start_date] unless params[:start_date].blank?
issue.due_date = params[:due_date] unless params[:due_date].blank?
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
# Don't save any change to the issue if the user is not authorized to apply the requested status
if (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
# Send notification for each issue (if changed)
Mailer.deliver_issue_edit(journal) if journal.details.any? && Setting.notified_events.include?('issue_updated')
else
# Keep unsaved issue ids to display them in flash error
unsaved_issue_ids << issue.id
end
end
if unsaved_issue_ids.empty?
flash[:notice] = l(:notice_successful_update) unless @issues.empty?
else
flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, @issues.size, '#' + unsaved_issue_ids.join(', #'))
end
redirect_to(params[:back_to] || {:controller => 'issues', :action => 'index', :project_id => @project})
return
end
# Find potential statuses the user could be allowed to switch issues to
@available_statuses = Workflow.find(:all, :include => :new_status,
:conditions => {:role_id => current_role.id}).collect(&:new_status).compact.uniq.sort
end
def move
@allowed_projects = []
# find projects to which the user is allowed to move the issue
if User.current.admin?
# admin is allowed to move issues to any active (visible) project
@allowed_projects = Project.find(:all, :conditions => Project.visible_by(User.current), :order => 'name')
else
User.current.memberships.each {|m| @allowed_projects << m.project if m.role.allowed_to?(:move_issues)}
end
@target_project = @allowed_projects.detect {|p| p.id.to_s == params[:new_project_id]} if params[:new_project_id]
@target_project ||= @project
@trackers = @target_project.trackers
if request.post?
new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
unsaved_issue_ids = []
@issues.each do |issue|
issue.init_journal(User.current)
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker)
end
if unsaved_issue_ids.empty?
flash[:notice] = l(:notice_successful_update) unless @issues.empty?
else
flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, @issues.size, '#' + unsaved_issue_ids.join(', #'))
end
redirect_to :controller => 'issues', :action => 'index', :project_id => @project
return
end
render :layout => false if request.xhr?
end
def destroy
@issue.destroy
redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
end
def add_attachment
# Save the attachments
@attachments = []
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user)
@attachments << a unless a.new_record?
} if params[:attachments] and params[:attachments].is_a? Array
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
redirect_to :action => 'show', :id => @issue
end
def destroy_attachment
@issue.attachments.find(params[:attachment_id]).destroy
redirect_to :action => 'show', :id => @issue
end
# Send the file in stream mode
def download
@attachment = @issue.attachments.find(params[:attachment_id])
send_file @attachment.diskfile, :filename => @attachment.filename
rescue
render_404
end
private
def find_project
@issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
@project = @issue.project
@html_title = "#{@project.name} - #{@issue.tracker.name} ##{@issue.id}"
rescue ActiveRecord::RecordNotFound
render_404
end
@hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
if @hours > 0
case params[:todo]
when 'destroy'
# nothing to do
when 'nullify'
TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues])
when 'reassign'
reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
if reassign_to.nil?
flash.now[:error] = l(:error_issue_not_found_in_project)
return
else
TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues])
end
else
# display the destroy form
return
end
end
@issues.each(&:destroy)
redirect_to :action => 'index', :project_id => @project
end
def gantt
@gantt = Redmine::Helpers::Gantt.new(params)
retrieve_query
if @query.valid?
events = []
# Issues that have start and due dates
events += Issue.find(:all,
:order => "start_date, due_date",
:include => [:tracker, :status, :assigned_to, :priority, :project],
:conditions => ["(#{@query.statement}) AND (((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null)", @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to]
)
# Issues that don't have a due date but that are assigned to a version with a date
events += Issue.find(:all,
:order => "start_date, effective_date",
:include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version],
:conditions => ["(#{@query.statement}) AND (((start_date>=? and start_date<=?) or (effective_date>=? and effective_date<=?) or (start_date<? and effective_date>?)) and start_date is not null and due_date is null and effective_date is not null)", @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to]
)
# Versions
events += Version.find(:all, :include => :project,
:conditions => ["(#{@query.project_statement}) AND effective_date BETWEEN ? AND ?", @gantt.date_from, @gantt.date_to])
@gantt.events = events
end
respond_to do |format|
format.html { render :template => "issues/gantt.rhtml", :layout => !request.xhr? }
format.png { send_data(@gantt.to_image, :disposition => 'inline', :type => 'image/png', :filename => "#{@project.identifier}-gantt.png") } if @gantt.respond_to?('to_image')
format.pdf { send_data(gantt_to_pdf(@gantt, @project), :type => 'application/pdf', :filename => "#{@project.nil? ? '' : "#{@project.identifier}-" }gantt.pdf") }
end
end
def calendar
if params[:year] and params[:year].to_i > 1900
@year = params[:year].to_i
if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
@month = params[:month].to_i
end
end
@year ||= Date.today.year
@month ||= Date.today.month
@calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month)
retrieve_query
if @query.valid?
events = []
events += Issue.find(:all,
:include => [:tracker, :status, :assigned_to, :priority, :project],
:conditions => ["(#{@query.statement}) AND ((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
)
events += Version.find(:all, :include => :project,
:conditions => ["(#{@query.project_statement}) AND effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
@calendar.events = events
end
render :layout => false if request.xhr?
end
def context_menu
@issues = Issue.find_all_by_id(params[:ids], :include => :project)
if (@issues.size == 1)
@issue = @issues.first
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
end
projects = @issues.collect(&:project).compact.uniq
@project = projects.first if projects.size == 1
@can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
:log_time => (@project && User.current.allowed_to?(:log_time, @project)),
:update => (@project && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && @allowed_statuses && !@allowed_statuses.empty?))),
:move => (@project && User.current.allowed_to?(:move_issues, @project)),
:copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
:delete => (@project && User.current.allowed_to?(:delete_issues, @project))
}
if @project
@assignables = @project.assignable_users
@assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
end
@priorities = Enumeration.get_values('IPRI').reverse
@statuses = IssueStatus.find(:all, :order => 'position')
@back = request.env['HTTP_REFERER']
render :layout => false
end
def update_form
@issue = Issue.new(params[:issue])
render :action => :new, :layout => false
end
def preview
@issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank?
@attachements = @issue.attachments if @issue
@text = params[:notes] || (params[:issue] ? params[:issue][:description] : nil)
render :partial => 'common/preview'
end
private
def find_issue
@issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
@project = @issue.project
rescue ActiveRecord::RecordNotFound
render_404
end
# Filter for bulk operations
def find_issues
@issues = Issue.find_all_by_id(params[:id] || params[:ids])
raise ActiveRecord::RecordNotFound if @issues.empty?
projects = @issues.collect(&:project).compact.uniq
if projects.size == 1
@project = projects.first
else
# TODO: let users bulk edit/move/destroy issues from different projects
render_error 'Can not bulk edit/move/destroy issues from different projects' and return false
end
rescue ActiveRecord::RecordNotFound
render_404
end
def find_project
@project = Project.find(params[:project_id])
rescue ActiveRecord::RecordNotFound
render_404
end
def find_optional_project
@project = Project.find(params[:project_id]) unless params[:project_id].blank?
allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @project, :global => true)
allowed ? true : deny_access
rescue ActiveRecord::RecordNotFound
render_404
end
# Retrieve query from session or build a new query
def retrieve_query
if !params[:query_id].blank?
cond = "project_id IS NULL"
cond << " OR project_id = #{@project.id}" if @project
@query = Query.find(params[:query_id], :conditions => cond)
@query.project = @project
session[:query] = {:id => @query.id, :project_id => @query.project_id}
else
if params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
# Give it a name, required to be valid
@query = Query.new(:name => "_")
@query.project = @project
if params[:fields] and params[:fields].is_a? Array
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end
else
@query.available_filters.keys.each do |field|
@query.add_short_filter(field, params[field]) if params[field]
end
end
session[:query] = {:project_id => @query.project_id, :filters => @query.filters}
else
@query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
@query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters])
@query.project = @project
end
end
end
end

View File

@@ -0,0 +1,41 @@
# redMine - project management software
# Copyright (C) 2006-2008 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.
class JournalsController < ApplicationController
before_filter :find_journal
def edit
if request.post?
@journal.update_attributes(:notes => params[:notes]) if params[:notes]
@journal.destroy if @journal.details.empty? && @journal.notes.blank?
call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params})
respond_to do |format|
format.html { redirect_to :controller => 'issues', :action => 'show', :id => @journal.journalized_id }
format.js { render :action => 'update' }
end
end
end
private
def find_journal
@journal = Journal.find(params[:id])
render_403 and return false unless @journal.editable_by?(User.current)
@project = @journal.journalized.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -1,53 +1,44 @@
# redMine - project management software
# Copyright (C) 2006 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 'iconv'
module IfpdfHelper
class IFPDF < FPDF
attr_accessor :footer_date
def initialize
super
SetCreator("redMine #{Redmine::VERSION}")
end
def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
@ic ||= Iconv.new('ISO-8859-1', 'UTF-8')
txt = begin
@ic.iconv(txt)
rescue
txt
end
super w,h,txt,border,ln,align,fill,link
end
def Footer
SetFont('Helvetica', 'I', 8)
SetY(-15)
SetX(15)
Cell(0, 5, @footer_date, 0, 0, 'L')
SetY(-15)
SetX(-30)
Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
end
# redMine - project management software
# Copyright (C) 2006-2008 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.
class MailHandlerController < ActionController::Base
before_filter :check_credential
verify :method => :post,
:only => :index,
:render => { :nothing => true, :status => 405 }
# Submits an incoming email to MailHandler
def index
options = params.dup
email = options.delete(:email)
if MailHandler.receive(email, options)
render :nothing => true, :status => :created
else
render :nothing => true, :status => :unprocessable_entity
end
end
end
private
def check_credential
User.current = nil
unless Setting.mail_handler_api_enabled? && params[:key] == Setting.mail_handler_api_key
render :nothing => true, :status => 403
end
end
end

View File

@@ -1,42 +1,61 @@
# redMine - project management software
# Copyright (C) 2006 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.
class MembersController < ApplicationController
layout 'base'
before_filter :find_project, :authorize
# redMine - project management software
# Copyright (C) 2006 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.
def edit
if request.post? and @member.update_attributes(params[:member])
flash[:notice] = l(:notice_successful_update)
redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project
class MembersController < ApplicationController
before_filter :find_member, :except => :new
before_filter :find_project, :only => :new
before_filter :authorize
def new
@project.members << Member.new(params[:member]) if request.post?
respond_to do |format|
format.html { redirect_to :action => 'settings', :tab => 'members', :id => @project }
format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
end
end
def edit
if request.post? and @member.update_attributes(params[:member])
respond_to do |format|
format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
end
end
end
def destroy
@member.destroy
flash[:notice] = l(:notice_successful_delete)
redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project
end
private
def find_project
@member = Member.find(params[:id])
@project = @member.project
rescue ActiveRecord::RecordNotFound
render_404
@member.destroy
respond_to do |format|
format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
end
end
private
def find_project
@project = Project.find(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
def find_member
@member = Member.find(params[:id])
@project = @member.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -0,0 +1,125 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class MessagesController < ApplicationController
menu_item :boards
before_filter :find_board, :only => [:new, :preview]
before_filter :find_message, :except => [:new, :preview]
before_filter :authorize, :except => [:preview, :edit, :destroy]
verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show }
verify :xhr => true, :only => :quote
helper :watchers
helper :attachments
include AttachmentsHelper
# Show a topic and its replies
def show
@replies = @topic.children.find(:all, :include => [:author, :attachments, {:board => :project}])
@replies.reverse! if User.current.wants_comments_in_reverse_order?
@reply = Message.new(:subject => "RE: #{@message.subject}")
render :action => "show", :layout => false if request.xhr?
end
# Create a new topic
def new
@message = Message.new(params[:message])
@message.author = User.current
@message.board = @board
if params[:message] && User.current.allowed_to?(:edit_messages, @project)
@message.locked = params[:message]['locked']
@message.sticky = params[:message]['sticky']
end
if request.post? && @message.save
attach_files(@message, params[:attachments])
redirect_to :action => 'show', :id => @message
end
end
# Reply to a topic
def reply
@reply = Message.new(params[:reply])
@reply.author = User.current
@reply.board = @board
@topic.children << @reply
if !@reply.new_record?
attach_files(@reply, params[:attachments])
end
redirect_to :action => 'show', :id => @topic
end
# Edit a message
def edit
render_403 and return false unless @message.editable_by?(User.current)
if params[:message]
@message.locked = params[:message]['locked']
@message.sticky = params[:message]['sticky']
end
if request.post? && @message.update_attributes(params[:message])
attach_files(@message, params[:attachments])
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'show', :id => @topic
end
end
# Delete a messages
def destroy
render_403 and return false unless @message.destroyable_by?(User.current)
@message.destroy
redirect_to @message.parent.nil? ?
{ :controller => 'boards', :action => 'show', :project_id => @project, :id => @board } :
{ :action => 'show', :id => @message.parent }
end
def quote
user = @message.author
text = @message.content
content = "#{ll(Setting.default_language, :text_user_wrote, user)}\\n> "
content << text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub('"', '\"').gsub(/(\r?\n|\r\n?)/, "\\n> ") + "\\n\\n"
render(:update) { |page|
page.<< "$('message_content').value = \"#{content}\";"
page.show 'reply'
page << "Form.Element.focus('message_content');"
page << "Element.scrollTo('reply');"
page << "$('message_content').scrollTop = $('message_content').scrollHeight - $('message_content').clientHeight;"
}
end
def preview
message = @board.messages.find_by_id(params[:id])
@attachements = message.attachments if message
@text = (params[:message] || params[:reply])[:content]
render :partial => 'common/preview'
end
private
def find_message
find_board
@message = @board.messages.find(params[:id], :include => :parent)
@topic = @message.root
rescue ActiveRecord::RecordNotFound
render_404
end
def find_board
@board = Board.find(params[:board_id], :include => :project)
@project = @board.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -16,14 +16,17 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class MyController < ApplicationController
layout 'base'
before_filter :require_login
helper :issues
BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
'issuesreportedbyme' => :label_reported_issues,
'issueswatched' => :label_watched_issues,
'news' => :label_news_latest,
'calendar' => :label_calendar,
'documents' => :label_document_plural
'documents' => :label_document_plural,
'timelog' => :label_spent_time
}.freeze
DEFAULT_LAYOUT = { 'left' => ['issuesassignedtome'],
@@ -41,44 +44,65 @@ class MyController < ApplicationController
# Show user's page
def page
@user = self.logged_in_user
@user = User.current
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
end
# Edit user's account
def account
@user = self.logged_in_user
@user = User.current
@pref = @user.pref
@user.attributes = params[:user]
@user.pref.attributes = params[:pref]
if request.post? and @user.save and @user.pref.save
set_localization
flash.now[:notice] = l(:notice_account_updated)
self.logged_in_user.reload
end
end
# Change user's password
def change_password
@user = self.logged_in_user
flash[:notice] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id
if @user.check_password?(params[:password])
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
if request.post?
@user.attributes = params[:user]
@user.mail_notification = (params[:notification_option] == 'all')
@user.pref.attributes = params[:pref]
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
if @user.save
flash[:notice] = l(:notice_account_password_updated)
else
render :action => 'account'
@user.pref.save
@user.notified_project_ids = (params[:notification_option] == 'selected' ? params[:notified_project_ids] : [])
set_language_if_valid @user.language
flash[:notice] = l(:notice_account_updated)
redirect_to :action => 'account'
return
end
else
flash[:notice] = l(:notice_account_wrong_password)
end
@notification_options = [[l(:label_user_mail_option_all), 'all'],
[l(:label_user_mail_option_none), 'none']]
# Only users that belong to more than 1 project can select projects for which they are notified
# Note that @user.membership.size would fail since AR ignores :include association option when doing a count
@notification_options.insert 1, [l(:label_user_mail_option_selected), 'selected'] if @user.memberships.length > 1
@notification_option = @user.mail_notification? ? 'all' : (@user.notified_projects_ids.empty? ? 'none' : 'selected')
end
# Manage user's password
def password
@user = User.current
flash[:error] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id
if request.post?
if @user.check_password?(params[:password])
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
if @user.save
flash[:notice] = l(:notice_account_password_updated)
redirect_to :action => 'account'
end
else
flash[:error] = l(:notice_account_wrong_password)
end
end
end
# Create a new feeds key
def reset_rss_key
if request.post? && User.current.rss_token
User.current.rss_token.destroy
flash[:notice] = l(:notice_feeds_access_key_reseted)
end
redirect_to :action => 'account'
end
# User's page layout configuration
def page_layout
@user = self.logged_in_user
@user = User.current
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup
session[:page_layout] = @blocks
%w(top left right).each {|f| session[:page_layout][f] ||= [] }
@@ -90,8 +114,9 @@ class MyController < ApplicationController
# The block is added on top of the page
# params[:block] : id of the block to add
def add_block
@user = self.logged_in_user
block = params[:block]
render(:nothing => true) and return unless block && (BLOCKS.keys.include? block)
@user = User.current
# remove if already present in a group
%w(top left right).each {|f| (session[:page_layout][f] ||= []).delete block }
# add it on top
@@ -126,7 +151,7 @@ class MyController < ApplicationController
# Save user's page layout
def page_layout_save
@user = self.logged_in_user
@user = User.current
@user.pref[:my_page_layout] = session[:page_layout] if session[:page_layout]
@user.pref.save
session[:page_layout] = nil

View File

@@ -1,60 +1,108 @@
# redMine - project management software
# Copyright (C) 2006 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.
class NewsController < ApplicationController
layout 'base'
before_filter :find_project, :authorize
# redMine - project management software
# Copyright (C) 2006 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.
class NewsController < ApplicationController
before_filter :find_news, :except => [:new, :index, :preview]
before_filter :find_project, :only => [:new, :preview]
before_filter :authorize, :except => [:index, :preview]
before_filter :find_optional_project, :only => :index
accept_key_auth :index
def index
@news_pages, @newss = paginate :news,
:per_page => 10,
:conditions => (@project ? {:project_id => @project.id} : Project.visible_by(User.current)),
:include => [:author, :project],
:order => "#{News.table_name}.created_on DESC"
respond_to do |format|
format.html { render :layout => false if request.xhr? }
format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
end
end
def show
@comments = @news.comments
@comments.reverse! if User.current.wants_comments_in_reverse_order?
end
def new
@news = News.new(:project => @project, :author => User.current)
if request.post?
@news.attributes = params[:news]
if @news.save
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_news_added(@news) if Setting.notified_events.include?('news_added')
redirect_to :controller => 'news', :action => 'index', :project_id => @project
end
end
end
def edit
if request.post? and @news.update_attributes(params[:news])
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'show', :id => @news
end
end
def add_comment
@comment = Comment.new(params[:comment])
@comment.author = logged_in_user
if @news.comments << @comment
flash[:notice] = l(:label_comment_added)
redirect_to :action => 'show', :id => @news
else
render :action => 'show'
end
end
def destroy_comment
@news.comments.find(params[:comment_id]).destroy
redirect_to :action => 'show', :id => @news
end
def add_comment
@comment = Comment.new(params[:comment])
@comment.author = User.current
if @news.comments << @comment
flash[:notice] = l(:label_comment_added)
redirect_to :action => 'show', :id => @news
else
render :action => 'show'
end
end
def destroy_comment
@news.comments.find(params[:comment_id]).destroy
redirect_to :action => 'show', :id => @news
end
def destroy
@news.destroy
redirect_to :controller => 'projects', :action => 'list_news', :id => @project
end
private
def find_project
@news = News.find(params[:id])
@project = @news.project
rescue ActiveRecord::RecordNotFound
render_404
end
redirect_to :action => 'index', :project_id => @project
end
def preview
@text = (params[:news] ? params[:news][:description] : nil)
render :partial => 'common/preview'
end
private
def find_news
@news = News.find(params[:id])
@project = @news.project
rescue ActiveRecord::RecordNotFound
render_404
end
def find_project
@project = Project.find(params[:project_id])
rescue ActiveRecord::RecordNotFound
render_404
end
def find_optional_project
return true unless params[:project_id]
@project = Project.find(params[:project_id])
authorize
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -1,578 +1,296 @@
# redMine - project management software
# Copyright (C) 2006-2007 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 'csv'
class ProjectsController < ApplicationController
layout 'base'
before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
before_filter :require_admin, :only => [ :add, :destroy ]
helper :sort
include SortHelper
helper :custom_fields
include CustomFieldsHelper
helper :ifpdf
include IfpdfHelper
helper IssuesHelper
helper :queries
include QueriesHelper
# redMine - project management software
# Copyright (C) 2006-2007 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.
class ProjectsController < ApplicationController
menu_item :overview
menu_item :activity, :only => :activity
menu_item :roadmap, :only => :roadmap
menu_item :files, :only => [:list_files, :add_file]
menu_item :settings, :only => :settings
menu_item :issues, :only => [:changelog]
before_filter :find_project, :except => [ :index, :list, :add, :activity ]
before_filter :find_optional_project, :only => :activity
before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy, :activity ]
before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ]
accept_key_auth :activity
helper :sort
include SortHelper
helper :custom_fields
include CustomFieldsHelper
helper :issues
helper IssuesHelper
helper :queries
include QueriesHelper
helper :repositories
include RepositoriesHelper
include ProjectsHelper
# Lists visible projects
def index
list
render :action => 'list' unless request.xhr?
projects = Project.find :all,
:conditions => Project.visible_by(User.current),
:include => :parent
respond_to do |format|
format.html {
@project_tree = projects.group_by {|p| p.parent || p}
@project_tree.keys.each {|p| @project_tree[p] -= [p]}
}
format.atom {
render_feed(projects.sort_by(&:created_on).reverse.slice(0, Setting.feeds_limit.to_i),
:title => "#{Setting.app_title}: #{l(:label_project_latest)}")
}
end
end
# Lists public projects
def list
sort_init 'name', 'asc'
sort_update
@project_count = Project.count(:all, :conditions => ["is_public=?", true])
@project_pages = Paginator.new self, @project_count,
15,
params['page']
@projects = Project.find :all, :order => sort_clause,
:conditions => ["is_public=?", true],
:limit => @project_pages.items_per_page,
:offset => @project_pages.current.offset
render :action => "list", :layout => false if request.xhr?
end
# Add a new project
def add
@custom_fields = IssueCustomField.find(:all)
@root_projects = Project.find(:all, :conditions => "parent_id is null")
@project = Project.new(params[:project])
if request.get?
@custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
else
@project.custom_fields = CustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
@custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
@project.custom_values = @custom_values
if params[:repository_enabled] && params[:repository_enabled] == "1"
@project.repository = Repository.new
@project.repository.attributes = params[:repository]
end
def add
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
@trackers = Tracker.all
@root_projects = Project.find(:all,
:conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
:order => 'name')
@project = Project.new(params[:project])
if request.get?
@project.identifier = Project.next_identifier if Setting.sequential_project_identifiers?
@project.trackers = Tracker.all
@project.is_public = Setting.default_projects_public?
@project.enabled_module_names = Redmine::AccessControl.available_project_modules
else
@project.enabled_module_names = params[:enabled_modules]
if @project.save
flash[:notice] = l(:notice_successful_create)
redirect_to :controller => 'admin', :action => 'projects'
end
end
end
# Show @project
def show
@custom_values = @project.custom_values.find(:all, :include => :custom_field)
@members = @project.members.find(:all, :include => [:user, :role])
@subprojects = @project.children if @project.children.size > 0
@news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
@trackers = Tracker.find(:all, :order => 'position')
@open_issues_by_tracker = Issue.count(:group => :tracker, :joins => "INNER JOIN issue_statuses ON issue_statuses.id = issues.status_id", :conditions => ["project_id=? and issue_statuses.is_closed=?", @project.id, false])
@total_issues_by_tracker = Issue.count(:group => :tracker, :conditions => ["project_id=?", @project.id])
redirect_to :controller => 'admin', :action => 'projects'
end
end
end
def settings
@root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
@custom_fields = IssueCustomField.find(:all)
@issue_category ||= IssueCategory.new
@member ||= @project.members.new
@roles = Role.find(:all, :order => 'position')
@users = User.find_active(:all) - @project.users
@custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
end
# Edit @project
def edit
if request.post?
@project.custom_fields = IssueCustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
if params[:custom_fields]
@custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
@project.custom_values = @custom_values
end
if params[:repository_enabled]
case params[:repository_enabled]
when "0"
@project.repository = nil
when "1"
@project.repository ||= Repository.new
@project.repository.attributes = params[:repository]
end
end
@project.attributes = params[:project]
# Show @project
def show
if params[:jump]
# try to redirect to the requested menu item
redirect_to_project_menu_item(@project, params[:jump]) && return
end
@members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
@subprojects = @project.children.find(:all, :conditions => Project.visible_by(User.current))
@news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
@trackers = @project.rolled_up_trackers
cond = @project.project_condition(Setting.display_subprojects_issues?)
Issue.visible_by(User.current) do
@open_issues_by_tracker = Issue.count(:group => :tracker,
:include => [:project, :status, :tracker],
:conditions => ["(#{cond}) AND #{IssueStatus.table_name}.is_closed=?", false])
@total_issues_by_tracker = Issue.count(:group => :tracker,
:include => [:project, :status, :tracker],
:conditions => cond)
end
TimeEntry.visible_by(User.current) do
@total_hours = TimeEntry.sum(:hours,
:include => :project,
:conditions => cond).to_f
end
@key = User.current.rss_key
end
def settings
@root_projects = Project.find(:all,
:conditions => ["parent_id IS NULL AND status = #{Project::STATUS_ACTIVE} AND id <> ?", @project.id],
:order => 'name')
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
@issue_category ||= IssueCategory.new
@member ||= @project.members.new
@trackers = Tracker.all
@repository ||= @project.repository
@wiki ||= @project.wiki
end
# Edit @project
def edit
if request.post?
@project.attributes = params[:project]
if @project.save
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'settings', :id => @project
else
settings
render :action => 'settings'
end
redirect_to :action => 'settings', :id => @project
else
settings
render :action => 'settings'
end
end
end
end
def modules
@project.enabled_module_names = params[:enabled_modules]
redirect_to :action => 'settings', :id => @project, :tab => 'modules'
end
def archive
@project.archive if request.post? && @project.active?
redirect_to :controller => 'admin', :action => 'projects'
end
def unarchive
@project.unarchive if request.post? && !@project.active?
redirect_to :controller => 'admin', :action => 'projects'
end
# Delete @project
def destroy
def destroy
@project_to_destroy = @project
if request.post? and params[:confirm]
@project.destroy
redirect_to :controller => 'admin', :action => 'projects'
@project_to_destroy.destroy
redirect_to :controller => 'admin', :action => 'projects'
end
end
# Add a new issue category to @project
def add_issue_category
if request.post?
@issue_category = @project.issue_categories.build(params[:issue_category])
if @issue_category.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'settings', :tab => 'categories', :id => @project
else
settings
render :action => 'settings'
end
end
end
# Add a new version to @project
def add_version
@version = @project.versions.build(params[:version])
if request.post? and @version.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'settings', :tab => 'versions', :id => @project
end
end
# Add a new member to @project
def add_member
@member = @project.members.build(params[:member])
if request.post?
if @member.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'settings', :tab => 'members', :id => @project
else
settings
render :action => 'settings'
end
end
end
# Show members list of @project
def list_members
@members = @project.members.find(:all)
end
# Add a new document to @project
def add_document
@categories = Enumeration::get_values('DCAT')
@document = @project.documents.build(params[:document])
if request.post? and @document.save
# Save the attachments
params[:attachments].each { |a|
Attachment.create(:container => @document, :file => a, :author => logged_in_user) unless a.size == 0
} if params[:attachments] and params[:attachments].is_a? Array
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_document_add(@document) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
redirect_to :action => 'list_documents', :id => @project
end
end
# Show documents list of @project
def list_documents
@documents = @project.documents.find :all, :include => :category
end
# Add a new issue to @project
def add_issue
@tracker = Tracker.find(params[:tracker_id])
@priorities = Enumeration::get_values('IPRI')
@issue = Issue.new(:project => @project, :tracker => @tracker)
if request.get?
@issue.start_date = Date.today
@custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
else
@issue.attributes = params[:issue]
@issue.author_id = self.logged_in_user.id if self.logged_in_user
# Multiple file upload
@attachments = []
params[:attachments].each { |a|
@attachments << Attachment.new(:container => @issue, :file => a, :author => logged_in_user) unless a.size == 0
} if params[:attachments] and params[:attachments].is_a? Array
@custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
@issue.custom_values = @custom_values
if @issue.save
@attachments.each(&:save)
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
redirect_to :action => 'list_issues', :id => @project
end
end
end
# Show filtered/sorted issues list of @project
def list_issues
sort_init 'issues.id', 'desc'
sort_update
retrieve_query
@results_per_page_options = [ 15, 25, 50, 100 ]
if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
@results_per_page = params[:per_page].to_i
session[:results_per_page] = @results_per_page
else
@results_per_page = session[:results_per_page] || 25
end
if @query.valid?
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, @results_per_page, params['page']
@issues = Issue.find :all, :order => sort_clause,
:include => [ :author, :status, :tracker, :project, :priority ],
:conditions => @query.statement,
:limit => @issue_pages.items_per_page,
:offset => @issue_pages.current.offset
end
@trackers = Tracker.find :all, :order => 'position'
render :layout => false if request.xhr?
end
# Export filtered/sorted issues list to CSV
def export_issues_csv
sort_init 'issues.id', 'desc'
sort_update
retrieve_query
render :action => 'list_issues' and return unless @query.valid?
@issues = Issue.find :all, :order => sort_clause,
:include => [ :author, :status, :tracker, :priority, {:custom_values => :custom_field} ],
:conditions => @query.statement,
:limit => Setting.issues_export_limit
ic = Iconv.new('ISO-8859-1', 'UTF-8')
export = StringIO.new
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
# csv header fields
headers = [ "#", l(:field_status),
l(:field_tracker),
l(:field_priority),
l(:field_subject),
l(:field_author),
l(:field_start_date),
l(:field_due_date),
l(:field_done_ratio),
l(:field_created_on),
l(:field_updated_on)
]
for custom_field in @project.all_custom_fields
headers << custom_field.name
end
csv << headers.collect {|c| ic.iconv(c) }
# csv lines
@issues.each do |issue|
fields = [issue.id, issue.status.name,
issue.tracker.name,
issue.priority.name,
issue.subject,
issue.author.display_name,
issue.start_date ? l_date(issue.start_date) : nil,
issue.due_date ? l_date(issue.due_date) : nil,
issue.done_ratio,
l_datetime(issue.created_on),
l_datetime(issue.updated_on)
]
for custom_field in @project.all_custom_fields
fields << (show_value issue.custom_value_for(custom_field))
end
csv << fields.collect {|c| ic.iconv(c.to_s) }
end
end
export.rewind
send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
end
# Export filtered/sorted issues to PDF
def export_issues_pdf
sort_init 'issues.id', 'desc'
sort_update
retrieve_query
render :action => 'list_issues' and return unless @query.valid?
@issues = Issue.find :all, :order => sort_clause,
:include => [ :author, :status, :tracker, :priority ],
:conditions => @query.statement,
:limit => Setting.issues_export_limit
@options_for_rfpdf ||= {}
@options_for_rfpdf[:file_name] = "export.pdf"
render :layout => false
end
def move_issues
@issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
redirect_to :action => 'list_issues', :id => @project and return unless @issues
@projects = []
# find projects to which the user is allowed to move the issue
@logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role_id)}
# issue can be moved to any tracker
@trackers = Tracker.find(:all)
if request.post? and params[:new_project_id] and params[:new_tracker_id]
new_project = Project.find(params[:new_project_id])
new_tracker = Tracker.find(params[:new_tracker_id])
@issues.each { |i|
# project dependent properties
unless i.project_id == new_project.id
i.category = nil
i.fixed_version = nil
end
# move the issue
i.project = new_project
i.tracker = new_tracker
i.save
}
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list_issues', :id => @project
end
end
def add_query
@query = Query.new(params[:query])
@query.project = @project
@query.user = logged_in_user
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end if params[:fields]
if request.post? and @query.save
flash[:notice] = l(:notice_successful_create)
redirect_to :controller => 'reports', :action => 'issue_report', :id => @project
end
render :layout => false if request.xhr?
end
# Add a news to @project
def add_news
@news = News.new(:project => @project)
if request.post?
@news.attributes = params[:news]
@news.author_id = self.logged_in_user.id if self.logged_in_user
if @news.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list_news', :id => @project
end
end
end
# Show news list of @project
def list_news
@news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
render :action => "list_news", :layout => false if request.xhr?
end
def add_file
if request.post?
@version = @project.versions.find_by_id(params[:version_id])
# Save the attachments
@attachments = []
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @version, :file => file, :author => logged_in_user)
@attachments << a unless a.new_record?
} if params[:attachments] and params[:attachments].is_a? Array
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
end
@versions = @project.versions
end
def list_files
@versions = @project.versions
end
# Show changelog for @project
def changelog
@trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position')
if request.get?
@selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
else
@selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
end
@selected_tracker_ids ||= []
@fixed_issues = @project.issues.find(:all,
:include => [ :fixed_version, :status, :tracker ],
:conditions => [ "issue_statuses.is_closed=? and issues.tracker_id in (#{@selected_tracker_ids.join(',')}) and issues.fixed_version_id is not null", true],
:order => "versions.effective_date DESC, issues.id DESC"
) unless @selected_tracker_ids.empty?
@fixed_issues ||= []
end
def roadmap
@trackers = Tracker.find(:all, :conditions => ["is_in_roadmap=?", true], :order => 'position')
if request.get?
@selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
else
@selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
end
@selected_tracker_ids ||= []
@versions = @project.versions.find(:all,
:conditions => [ "versions.effective_date>?", Date.today],
:order => "versions.effective_date ASC"
)
end
def activity
if params[:year] and params[:year].to_i > 1900
@year = params[:year].to_i
if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
@month = params[:month].to_i
end
end
@year ||= Date.today.year
@month ||= Date.today.month
@date_from = Date.civil(@year, @month, 1)
@date_to = (@date_from >> 1)-1
@events_by_day = {}
unless params[:show_issues] == "0"
@project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on>=? and issues.created_on<=?", @date_from, @date_to] ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_issues = 1
end
unless params[:show_news] == "0"
@project.news.find(:all, :conditions => ["news.created_on>=? and news.created_on<=?", @date_from, @date_to], :include => :author ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_news = 1
end
unless params[:show_files] == "0"
Attachment.find(:all, :select => "attachments.*", :joins => "LEFT JOIN versions ON versions.id = attachments.container_id", :conditions => ["attachments.container_type='Version' and versions.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to], :include => :author ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_files = 1
end
unless params[:show_documents] == "0"
@project.documents.find(:all, :conditions => ["documents.created_on>=? and documents.created_on<=?", @date_from, @date_to] ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
Attachment.find(:all, :select => "attachments.*", :joins => "LEFT JOIN documents ON documents.id = attachments.container_id", :conditions => ["attachments.container_type='Document' and documents.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to], :include => :author ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_documents = 1
end
render :layout => false if request.xhr?
end
def calendar
if params[:year] and params[:year].to_i > 1900
@year = params[:year].to_i
if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
@month = params[:month].to_i
end
end
@year ||= Date.today.year
@month ||= Date.today.month
@date_from = Date.civil(@year, @month, 1)
@date_to = (@date_from >> 1)-1
# start on monday
@date_from = @date_from - (@date_from.cwday-1)
# finish on sunday
@date_to = @date_to + (7-@date_to.cwday)
@issues = @project.issues.find(:all, :include => [:tracker, :status, :assigned_to, :priority], :conditions => ["((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", @date_from, @date_to, @date_from, @date_to])
render :layout => false if request.xhr?
end
def gantt
if params[:year] and params[:year].to_i >0
@year_from = params[:year].to_i
if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12
@month_from = params[:month].to_i
else
@month_from = 1
end
else
@month_from ||= (Date.today << 1).month
@year_from ||= (Date.today << 1).year
end
@zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2
@months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6
@date_from = Date.civil(@year_from, @month_from, 1)
@date_to = (@date_from >> @months) - 1
@issues = @project.issues.find(:all, :order => "start_date, due_date", :include => [:tracker, :status, :assigned_to, :priority], :conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null)", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to])
if params[:output]=='pdf'
@options_for_rfpdf ||= {}
@options_for_rfpdf[:file_name] = "gantt.pdf"
render :template => "projects/gantt.rfpdf", :layout => false
else
render :template => "projects/gantt.rhtml"
end
end
private
# Find project of id params[:id]
# if not found, redirect to project list
# Used as a before_filter
def find_project
@project = Project.find(params[:id])
@html_title = @project.name
# hide project in layout
@project = nil
end
# Add a new issue category to @project
def add_issue_category
@category = @project.issue_categories.build(params[:category])
if request.post? and @category.save
respond_to do |format|
format.html do
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'settings', :tab => 'categories', :id => @project
end
format.js do
# IE doesn't support the replace_html rjs method for select box options
render(:update) {|page| page.replace "issue_category_id",
content_tag('select', '<option></option>' + options_from_collection_for_select(@project.issue_categories, 'id', 'name', @category.id), :id => 'issue_category_id', :name => 'issue[category_id]')
}
end
end
end
end
# Add a new version to @project
def add_version
@version = @project.versions.build(params[:version])
if request.post? and @version.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'settings', :tab => 'versions', :id => @project
end
end
def add_file
if request.post?
container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id]))
attachments = attach_files(container, params[:attachments])
if !attachments.empty? && Setting.notified_events.include?('file_added')
Mailer.deliver_attachments_added(attachments)
end
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
return
end
@versions = @project.versions.sort
end
def list_files
sort_init 'filename', 'asc'
sort_update 'filename' => "#{Attachment.table_name}.filename",
'created_on' => "#{Attachment.table_name}.created_on",
'size' => "#{Attachment.table_name}.filesize",
'downloads' => "#{Attachment.table_name}.downloads"
@containers = [ Project.find(@project.id, :include => :attachments, :order => sort_clause)]
@containers += @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse
render :layout => !request.xhr?
end
# Show changelog for @project
def changelog
@trackers = @project.trackers.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position')
retrieve_selected_tracker_ids(@trackers)
@versions = @project.versions.sort
end
def roadmap
@trackers = @project.trackers.find(:all, :conditions => ["is_in_roadmap=?", true])
retrieve_selected_tracker_ids(@trackers)
@versions = @project.versions.sort
@versions = @versions.select {|v| !v.completed? } unless params[:completed]
end
def activity
@days = Setting.activity_days_default.to_i
if params[:from]
begin; @date_to = params[:from].to_date + 1; rescue; end
end
@date_to ||= Date.today + 1
@date_from = @date_to - @days
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
@author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id]))
@activity = Redmine::Activity::Fetcher.new(User.current, :project => @project,
:with_subprojects => @with_subprojects,
:author => @author)
@activity.scope_select {|t| !params["show_#{t}"].nil?}
@activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty?
events = @activity.events(@date_from, @date_to)
respond_to do |format|
format.html {
@events_by_day = events.group_by(&:event_date)
render :layout => false if request.xhr?
}
format.atom {
title = l(:label_activity)
if @author
title = @author.name
elsif @activity.scope.size == 1
title = l("label_#{@activity.scope.first.singularize}_plural")
end
render_feed(events, :title => "#{@project || Setting.app_title}: #{title}")
}
end
rescue ActiveRecord::RecordNotFound
render_404
end
# Retrieve query from session or build a new query
def retrieve_query
if params[:query_id]
@query = @project.queries.find(params[:query_id])
session[:query] = @query
else
if params[:set_filter] or !session[:query] or session[:query].project_id != @project.id
# Give it a name, required to be valid
@query = Query.new(:name => "_")
@query.project = @project
if params[:fields] and params[:fields].is_a? Array
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end
else
@query.available_filters.keys.each do |field|
@query.add_short_filter(field, params[field]) if params[field]
end
end
session[:query] = @query
else
@query = session[:query]
end
end
end
render_404
end
private
# Find project of id params[:id]
# if not found, redirect to project list
# Used as a before_filter
def find_project
@project = Project.find(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
def find_optional_project
return true unless params[:id]
@project = Project.find(params[:id])
authorize
rescue ActiveRecord::RecordNotFound
render_404
end
def retrieve_selected_tracker_ids(selectable_trackers)
if ids = params[:tracker_ids]
@selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
else
@selected_tracker_ids = selectable_trackers.collect {|t| t.id.to_s }
end
end
end

View File

@@ -1,5 +1,5 @@
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
# Copyright (C) 2006-2007 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
@@ -16,9 +16,29 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class QueriesController < ApplicationController
layout 'base'
before_filter :require_login, :find_query
menu_item :issues
before_filter :find_query, :except => :new
before_filter :find_optional_project, :only => :new
def new
@query = Query.new(params[:query])
@query.project = params[:query_is_for_all] ? nil : @project
@query.user = User.current
@query.is_public = false unless (@query.project && current_role.allowed_to?(:manage_public_queries)) || User.current.admin?
@query.column_names = nil if params[:default_columns]
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end if params[:fields]
if request.post? && params[:confirm] && @query.save
flash[:notice] = l(:notice_successful_create)
redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
return
end
render :layout => false if request.xhr?
end
def edit
if request.post?
@query.filters = {}
@@ -26,25 +46,34 @@ class QueriesController < ApplicationController
@query.add_filter(field, params[:operators][field], params[:values][field])
end if params[:fields]
@query.attributes = params[:query]
@query.project = nil if params[:query_is_for_all]
@query.is_public = false unless (@query.project && current_role.allowed_to?(:manage_public_queries)) || User.current.admin?
@query.column_names = nil if params[:default_columns]
if @query.save
flash[:notice] = l(:notice_successful_update)
redirect_to :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => @query
redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
end
end
end
def destroy
@query.destroy if request.post?
redirect_to :controller => 'reports', :action => 'issue_report', :id => @project
redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1
end
private
def find_query
@query = Query.find(params[:id])
@project = @query.project
# check if user is allowed to manage queries (same permission as add_query)
authorize('projects', 'add_query')
render_403 unless @query.editable_by?(User.current)
rescue ActiveRecord::RecordNotFound
render_404
end
def find_optional_project
@project = Project.find(params[:project_id]) if params[:project_id]
User.current.allowed_to?(:save_queries, @project, :global => true)
rescue ActiveRecord::RecordNotFound
render_404
end

View File

@@ -1,167 +1,236 @@
# redMine - project management software
# Copyright (C) 2006 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.
class ReportsController < ApplicationController
layout 'base'
before_filter :find_project, :authorize
def issue_report
@statuses = IssueStatus.find(:all, :order => 'position')
case params[:detail]
when "tracker"
@field = "tracker_id"
@rows = Tracker.find :all, :order => 'position'
@data = issues_by_tracker
@report_title = l(:field_tracker)
render :template => "reports/issue_report_details"
when "priority"
@field = "priority_id"
@rows = Enumeration::get_values('IPRI')
@data = issues_by_priority
@report_title = l(:field_priority)
render :template => "reports/issue_report_details"
when "category"
@field = "category_id"
@rows = @project.issue_categories
@data = issues_by_category
@report_title = l(:field_category)
render :template => "reports/issue_report_details"
when "author"
@field = "author_id"
@rows = @project.members.collect { |m| m.user }
@data = issues_by_author
@report_title = l(:field_author)
render :template => "reports/issue_report_details"
else
@queries = @project.queries.find :all, :conditions => ["is_public=? or user_id=?", true, (logged_in_user ? logged_in_user.id : 0)]
@trackers = Tracker.find(:all, :order => 'position')
@priorities = Enumeration::get_values('IPRI')
@categories = @project.issue_categories
@authors = @project.members.collect { |m| m.user }
issues_by_tracker
issues_by_priority
issues_by_category
issues_by_author
render :template => "reports/issue_report"
end
end
def delays
@trackers = Tracker.find(:all)
if request.get?
@selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
else
@selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
end
@selected_tracker_ids ||= []
@raw =
ActiveRecord::Base.connection.select_all("SELECT datediff( a.created_on, b.created_on ) as delay, count(a.id) as total
FROM issue_histories a, issue_histories b, issues i
WHERE a.status_id =5
AND a.issue_id = b.issue_id
AND a.issue_id = i.id
AND i.tracker_id in (#{@selected_tracker_ids.join(',')})
AND b.id = (
SELECT min( c.id )
FROM issue_histories c
WHERE b.issue_id = c.issue_id )
GROUP BY delay") unless @selected_tracker_ids.empty?
@raw ||=[]
@x_from = 0
@x_to = 0
@y_from = 0
@y_to = 0
@sum_total = 0
@sum_delay = 0
@raw.each do |r|
@x_to = [r['delay'].to_i, @x_to].max
@y_to = [r['total'].to_i, @y_to].max
@sum_total = @sum_total + r['total'].to_i
@sum_delay = @sum_delay + r['total'].to_i * r['delay'].to_i
end
end
private
# Find project of id params[:id]
def find_project
@project = Project.find(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
def issues_by_tracker
@issues_by_tracker ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
t.id as tracker_id,
count(i.id) as total
from
issues i, issue_statuses s, trackers t
where
i.status_id=s.id
and i.tracker_id=t.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, t.id")
end
def issues_by_priority
@issues_by_priority ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
p.id as priority_id,
count(i.id) as total
from
issues i, issue_statuses s, enumerations p
where
i.status_id=s.id
and i.priority_id=p.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, p.id")
end
def issues_by_category
@issues_by_category ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
c.id as category_id,
count(i.id) as total
from
issues i, issue_statuses s, issue_categories c
where
i.status_id=s.id
and i.category_id=c.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, c.id")
end
def issues_by_author
@issues_by_author ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
a.id as author_id,
count(i.id) as total
from
issues i, issue_statuses s, users a
where
i.status_id=s.id
and i.author_id=a.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, a.id")
# redMine - project management software
# Copyright (C) 2006 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.
class ReportsController < ApplicationController
menu_item :issues
before_filter :find_project, :authorize
def issue_report
@statuses = IssueStatus.find(:all, :order => 'position')
case params[:detail]
when "tracker"
@field = "tracker_id"
@rows = @project.trackers
@data = issues_by_tracker
@report_title = l(:field_tracker)
render :template => "reports/issue_report_details"
when "version"
@field = "fixed_version_id"
@rows = @project.versions.sort
@data = issues_by_version
@report_title = l(:field_version)
render :template => "reports/issue_report_details"
when "priority"
@field = "priority_id"
@rows = Enumeration::get_values('IPRI')
@data = issues_by_priority
@report_title = l(:field_priority)
render :template => "reports/issue_report_details"
when "category"
@field = "category_id"
@rows = @project.issue_categories
@data = issues_by_category
@report_title = l(:field_category)
render :template => "reports/issue_report_details"
when "assigned_to"
@field = "assigned_to_id"
@rows = @project.members.collect { |m| m.user }
@data = issues_by_assigned_to
@report_title = l(:field_assigned_to)
render :template => "reports/issue_report_details"
when "author"
@field = "author_id"
@rows = @project.members.collect { |m| m.user }
@data = issues_by_author
@report_title = l(:field_author)
render :template => "reports/issue_report_details"
when "subproject"
@field = "project_id"
@rows = @project.active_children
@data = issues_by_subproject
@report_title = l(:field_subproject)
render :template => "reports/issue_report_details"
else
@trackers = @project.trackers
@versions = @project.versions.sort
@priorities = Enumeration::get_values('IPRI')
@categories = @project.issue_categories
@assignees = @project.members.collect { |m| m.user }
@authors = @project.members.collect { |m| m.user }
@subprojects = @project.active_children
issues_by_tracker
issues_by_version
issues_by_priority
issues_by_category
issues_by_assigned_to
issues_by_author
issues_by_subproject
render :template => "reports/issue_report"
end
end
def delays
@trackers = Tracker.find(:all)
if request.get?
@selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
else
@selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
end
@selected_tracker_ids ||= []
@raw =
ActiveRecord::Base.connection.select_all("SELECT datediff( a.created_on, b.created_on ) as delay, count(a.id) as total
FROM issue_histories a, issue_histories b, issues i
WHERE a.status_id =5
AND a.issue_id = b.issue_id
AND a.issue_id = i.id
AND i.tracker_id in (#{@selected_tracker_ids.join(',')})
AND b.id = (
SELECT min( c.id )
FROM issue_histories c
WHERE b.issue_id = c.issue_id )
GROUP BY delay") unless @selected_tracker_ids.empty?
@raw ||=[]
@x_from = 0
@x_to = 0
@y_from = 0
@y_to = 0
@sum_total = 0
@sum_delay = 0
@raw.each do |r|
@x_to = [r['delay'].to_i, @x_to].max
@y_to = [r['total'].to_i, @y_to].max
@sum_total = @sum_total + r['total'].to_i
@sum_delay = @sum_delay + r['total'].to_i * r['delay'].to_i
end
end
private
# Find project of id params[:id]
def find_project
@project = Project.find(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
def issues_by_tracker
@issues_by_tracker ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
t.id as tracker_id,
count(i.id) as total
from
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{Tracker.table_name} t
where
i.status_id=s.id
and i.tracker_id=t.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, t.id")
end
def issues_by_version
@issues_by_version ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
v.id as fixed_version_id,
count(i.id) as total
from
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{Version.table_name} v
where
i.status_id=s.id
and i.fixed_version_id=v.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, v.id")
end
def issues_by_priority
@issues_by_priority ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
p.id as priority_id,
count(i.id) as total
from
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{Enumeration.table_name} p
where
i.status_id=s.id
and i.priority_id=p.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, p.id")
end
def issues_by_category
@issues_by_category ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
c.id as category_id,
count(i.id) as total
from
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{IssueCategory.table_name} c
where
i.status_id=s.id
and i.category_id=c.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, c.id")
end
def issues_by_assigned_to
@issues_by_assigned_to ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
a.id as assigned_to_id,
count(i.id) as total
from
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{User.table_name} a
where
i.status_id=s.id
and i.assigned_to_id=a.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, a.id")
end
def issues_by_author
@issues_by_author ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
a.id as author_id,
count(i.id) as total
from
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{User.table_name} a
where
i.status_id=s.id
and i.author_id=a.id
and i.project_id=#{@project.id}
group by s.id, s.is_closed, a.id")
end
def issues_by_subproject
@issues_by_subproject ||=
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
i.project_id as project_id,
count(i.id) as total
from
#{Issue.table_name} i, #{IssueStatus.table_name} s
where
i.status_id=s.id
and i.project_id IN (#{@project.active_children.collect{|p| p.id}.join(',')})
group by s.id, s.is_closed, i.project_id") if @project.active_children.any?
@issues_by_subproject ||= []
end
end

View File

@@ -1,5 +1,5 @@
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
# Copyright (C) 2006-2007 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
@@ -15,60 +15,314 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class RepositoriesController < ApplicationController
layout 'base'
before_filter :find_project, :authorize
require 'SVG/Graph/Bar'
require 'SVG/Graph/BarHorizontal'
require 'digest/sha1'
def show
@entries = @repository.scm.entries('')
show_error and return unless @entries
@latest_revision = @entries.revisions.latest
class ChangesetNotFound < Exception; end
class InvalidRevisionParam < Exception; end
class RepositoriesController < ApplicationController
menu_item :repository
before_filter :find_repository, :except => :edit
before_filter :find_project, :only => :edit
before_filter :authorize
accept_key_auth :revisions
rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
def edit
@repository = @project.repository
if !@repository
@repository = Repository.factory(params[:repository_scm])
@repository.project = @project if @repository
end
if request.post? && @repository
@repository.attributes = params[:repository]
@repository.save
end
render(:update) {|page| page.replace_html "tab-content-repository", :partial => 'projects/settings/repository'}
end
def browse
@entries = @repository.scm.entries(@path, @rev)
show_error and return unless @entries
end
def revisions
@entry = @repository.scm.entry(@path, @rev)
@revisions = @repository.scm.revisions(@path, @rev)
show_error and return unless @entry && @revisions
end
def entry
if 'raw' == params[:format]
content = @repository.scm.cat(@path, @rev)
show_error and return unless content
send_data content, :filename => @path.split('/').last
def committers
@committers = @repository.committers
@users = @project.users
additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
@users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
@users.compact!
@users.sort!
if request.post? && params[:committers].is_a?(Hash)
# Build a hash with repository usernames as keys and corresponding user ids as values
@repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h}
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'committers', :id => @project
end
end
def destroy
@repository.destroy
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
end
def show
# check if new revisions have been committed in the repository
@repository.fetch_changesets if Setting.autofetch_changesets?
# root entries
@entries = @repository.entries('', @rev)
# latest changesets
@changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
show_error_not_found unless @entries || @changesets.any?
end
def browse
@entries = @repository.entries(@path, @rev)
if request.xhr?
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
else
show_error_not_found and return unless @entries
@properties = @repository.properties(@path, @rev)
render :action => 'browse'
end
end
def changes
@entry = @repository.entry(@path, @rev)
show_error_not_found and return unless @entry
@changesets = @repository.changesets_for_path(@path)
@properties = @repository.properties(@path, @rev)
end
def revisions
@changeset_count = @repository.changesets.count
@changeset_pages = Paginator.new self, @changeset_count,
per_page_option,
params['page']
@changesets = @repository.changesets.find(:all,
:limit => @changeset_pages.items_per_page,
:offset => @changeset_pages.current.offset,
:include => :user)
respond_to do |format|
format.html { render :layout => false if request.xhr? }
format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
end
end
def entry
@entry = @repository.entry(@path, @rev)
show_error_not_found and return unless @entry
# If the entry is a dir, show the browser
browse and return if @entry.is_dir?
@content = @repository.cat(@path, @rev)
show_error_not_found and return unless @content
if 'raw' == params[:format] || @content.is_binary_data?
# Force the download if it's a binary file
send_data @content, :filename => @path.split('/').last
else
# Prevent empty lines when displaying a file with Windows style eol
@content.gsub!("\r\n", "\n")
end
end
def annotate
@entry = @repository.entry(@path, @rev)
show_error_not_found and return unless @entry
@annotate = @repository.scm.annotate(@path, @rev)
render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
end
def revision
@revisions = @repository.scm.revisions '', @rev, @rev, :with_paths => true
show_error and return unless @revisions
@revision = @revisions.first
@changeset = @repository.changesets.find_by_revision(@rev)
raise ChangesetNotFound unless @changeset
respond_to do |format|
format.html
format.js {render :layout => false}
end
rescue ChangesetNotFound
show_error_not_found
end
def diff
@rev_to = params[:rev_to] || (@rev-1)
@diff = @repository.scm.diff(params[:path], @rev, @rev_to)
show_error and return unless @diff
if params[:format] == 'diff'
@diff = @repository.diff(@path, @rev, @rev_to)
show_error_not_found and return unless @diff
filename = "changeset_r#{@rev}"
filename << "_r#{@rev_to}" if @rev_to
send_data @diff.join, :filename => "#{filename}.diff",
:type => 'text/x-patch',
:disposition => 'attachment'
else
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
# Save diff type as user preference
if User.current.logged? && @diff_type != User.current.pref[:diff_type]
User.current.pref[:diff_type] = @diff_type
User.current.preference.save
end
@cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
unless read_fragment(@cache_key)
@diff = @repository.diff(@path, @rev, @rev_to)
show_error_not_found unless @diff
end
end
end
def stats
end
def graph
data = nil
case params[:graph]
when "commits_per_month"
data = graph_commits_per_month(@repository)
when "commits_per_author"
data = graph_commits_per_author(@repository)
end
if data
headers["Content-Type"] = "image/svg+xml"
send_data(data, :type => "image/svg+xml", :disposition => "inline")
else
render_404
end
end
private
def find_project
@project = Project.find(params[:id])
@repository = @project.repository
@path = params[:path].squeeze('/').gsub(/^\//, '') if params[:path]
@path ||= ''
@rev = params[:rev].to_i if params[:rev] and params[:rev].to_i > 0
rescue ActiveRecord::RecordNotFound
render_404
end
REV_PARAM_RE = %r{^[a-f0-9]*$}
def find_repository
@project = Project.find(params[:id])
@repository = @project.repository
render_404 and return false unless @repository
@path = params[:path].join('/') unless params[:path].nil?
@path ||= ''
@rev = params[:rev]
@rev_to = params[:rev_to]
raise InvalidRevisionParam unless @rev.to_s.match(REV_PARAM_RE) && @rev.to_s.match(REV_PARAM_RE)
rescue ActiveRecord::RecordNotFound
render_404
rescue InvalidRevisionParam
show_error_not_found
end
def show_error
flash.now[:notice] = l(:notice_scm_error)
render :nothing => true, :layout => true
def show_error_not_found
render_error l(:error_scm_not_found)
end
# Handler for Redmine::Scm::Adapters::CommandFailed exception
def show_error_command_failed(exception)
render_error l(:error_scm_command_failed, exception.message)
end
def graph_commits_per_month(repository)
@date_to = Date.today
@date_from = @date_to << 11
@date_from = Date.civil(@date_from.year, @date_from.month, 1)
commits_by_day = repository.changesets.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
commits_by_month = [0] * 12
commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last }
changes_by_day = repository.changes.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
changes_by_month = [0] * 12
changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last }
fields = []
month_names = l(:actionview_datehelper_select_month_names_abbr).split(',')
12.times {|m| fields << month_names[((Date.today.month - 1 - m) % 12)]}
graph = SVG::Graph::Bar.new(
:height => 300,
:width => 800,
:fields => fields.reverse,
:stack => :side,
:scale_integers => true,
:step_x_labels => 2,
:show_data_values => false,
:graph_title => l(:label_commits_per_month),
:show_graph_title => true
)
graph.add_data(
:data => commits_by_month[0..11].reverse,
:title => l(:label_revision_plural)
)
graph.add_data(
:data => changes_by_month[0..11].reverse,
:title => l(:label_change_plural)
)
graph.burn
end
def graph_commits_per_author(repository)
commits_by_author = repository.changesets.count(:all, :group => :committer)
commits_by_author.sort! {|x, y| x.last <=> y.last}
changes_by_author = repository.changes.count(:all, :group => :committer)
h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
fields = commits_by_author.collect {|r| r.first}
commits_data = commits_by_author.collect {|r| r.last}
changes_data = commits_by_author.collect {|r| h[r.first] || 0}
fields = fields + [""]*(10 - fields.length) if fields.length<10
commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
# Remove email adress in usernames
fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
graph = SVG::Graph::BarHorizontal.new(
:height => 400,
:width => 800,
:fields => fields,
:stack => :side,
:scale_integers => true,
:show_data_values => false,
:rotate_y_labels => false,
:graph_title => l(:label_commits_per_author),
:show_graph_title => true
)
graph.add_data(
:data => commits_data,
:title => l(:label_revision_plural)
)
graph.add_data(
:data => changes_data,
:title => l(:label_change_plural)
)
graph.burn
end
end
class Date
def months_ago(date = Date.today)
(date.year - self.year)*12 + (date.month - self.month)
end
def weeks_ago(date = Date.today)
(date.year - self.year)*52 + (date.cweek - self.cweek)
end
end
class String
def with_leading_slash
starts_with?('/') ? self : "/#{self}"
end
end

View File

@@ -1,26 +1,25 @@
# redMine - project management software
# Copyright (C) 2006 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.
class RolesController < ApplicationController
layout 'base'
before_filter :require_admin
verify :method => :post, :only => [ :destroy, :move ],
:redirect_to => { :action => :list }
# redMine - project management software
# Copyright (C) 2006 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.
class RolesController < ApplicationController
before_filter :require_admin
verify :method => :post, :only => [ :destroy, :move ],
:redirect_to => { :action => :list }
def index
list
@@ -28,75 +27,68 @@ class RolesController < ApplicationController
end
def list
@role_pages, @roles = paginate :roles, :per_page => 10, :order => "position"
@role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position'
render :action => "list", :layout => false if request.xhr?
end
def new
@role = Role.new(params[:role])
if request.post?
@role.permissions = Permission.find(params[:permission_ids]) if params[:permission_ids]
if @role.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list'
end
# Prefills the form with 'Non member' role permissions
@role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
if request.post? && @role.save
# workflow copy
if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
@role.workflows.copy(copy_from)
end
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list'
end
@permissions = Permission.find(:all, :conditions => ["is_public=?", false], :order => 'sort ASC')
@permissions = @role.setable_permissions
@roles = Role.find :all, :order => 'builtin, position'
end
def edit
@role = Role.find(params[:id])
@role = Role.find(params[:id])
if request.post? and @role.update_attributes(params[:role])
@role.permissions = Permission.find(params[:permission_ids] || [])
Permission.allowed_to_role_expired
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list'
end
@permissions = Permission.find(:all, :conditions => ["is_public=?", false], :order => 'sort ASC')
@permissions = @role.setable_permissions
end
def destroy
@role = Role.find(params[:id])
unless @role.members.empty?
flash[:notice] = 'Some members have this role. Can\'t delete it.'
else
@role.destroy
end
@role = Role.find(params[:id])
@role.destroy
redirect_to :action => 'list'
end
def move
@role = Role.find(params[:id])
case params[:position]
when 'highest'
@role.move_to_top
when 'higher'
@role.move_higher
when 'lower'
@role.move_lower
when 'lowest'
@role.move_to_bottom
end if params[:position]
redirect_to :action => 'list'
end
def workflow
@role = Role.find_by_id(params[:role_id])
@tracker = Tracker.find_by_id(params[:tracker_id])
if request.post?
Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
(params[:issue_status] || []).each { |old, news|
news.each { |new|
@role.workflows.build(:tracker_id => @tracker.id, :old_status_id => old, :new_status_id => new)
}
}
if @role.save
flash[:notice] = l(:notice_successful_update)
end
end
@roles = Role.find(:all, :order => 'position')
@trackers = Tracker.find(:all, :order => 'position')
@statuses = IssueStatus.find(:all, :include => :workflows, :order => 'position')
rescue
flash[:error] = 'This role is in use and can not be deleted.'
redirect_to :action => 'index'
end
def move
@role = Role.find(params[:id])
case params[:position]
when 'highest'
@role.move_to_top
when 'higher'
@role.move_higher
when 'lower'
@role.move_lower
when 'lowest'
@role.move_to_bottom
end if params[:position]
redirect_to :action => 'list'
end
def report
@roles = Role.find(:all, :order => 'builtin, position')
@permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
if request.post?
@roles.each do |role|
role.permissions = params[:permissions][role.id.to_s]
role.save
end
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list'
end
end
end

View File

@@ -0,0 +1,116 @@
# redMine - project management software
# Copyright (C) 2006 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.
class SearchController < ApplicationController
before_filter :find_optional_project
helper :messages
include MessagesHelper
def index
@question = params[:q] || ""
@question.strip!
@all_words = params[:all_words] || (params[:submit] ? false : true)
@titles_only = !params[:titles_only].nil?
projects_to_search =
case params[:scope]
when 'all'
nil
when 'my_projects'
User.current.memberships.collect(&:project)
when 'subprojects'
@project ? ([ @project ] + @project.active_children) : nil
else
@project
end
offset = nil
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
# quick jump to an issue
if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(User.current))
redirect_to :controller => "issues", :action => "show", :id => $1
return
end
@object_types = %w(issues news documents changesets wiki_pages messages projects)
if projects_to_search.is_a? Project
# don't search projects
@object_types.delete('projects')
# only show what the user is allowed to view
@object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
end
@scope = @object_types.select {|t| params[t]}
@scope = @object_types if @scope.empty?
# extract tokens from the question
# eg. hello "bye bye" => ["hello", "bye bye"]
@tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
# tokens must be at least 3 character long
@tokens = @tokens.uniq.select {|w| w.length > 2 }
if !@tokens.empty?
# no more than 5 tokens to search for
@tokens.slice! 5..-1 if @tokens.size > 5
# strings used in sql like statement
like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}
@results = []
@results_by_type = Hash.new {|h,k| h[k] = 0}
limit = 10
@scope.each do |s|
r, c = s.singularize.camelcase.constantize.search(like_tokens, projects_to_search,
:all_words => @all_words,
:titles_only => @titles_only,
:limit => (limit+1),
:offset => offset,
:before => params[:previous].nil?)
@results += r
@results_by_type[s] += c
end
@results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
if params[:previous].nil?
@pagination_previous_date = @results[0].event_datetime if offset && @results[0]
if @results.size > limit
@pagination_next_date = @results[limit-1].event_datetime
@results = @results[0, limit]
end
else
@pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
if @results.size > limit
@pagination_previous_date = @results[-(limit)].event_datetime
@results = @results[-(limit), limit]
end
end
else
@question = ""
end
render :layout => false if request.xhr?
end
private
def find_optional_project
return true unless params[:id]
@project = Project.find(params[:id])
check_project_privacy
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -5,29 +5,55 @@
# 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.
class SettingsController < ApplicationController
layout 'base'
before_filter :require_admin
def index
edit
render :action => 'edit'
end
def edit
if request.post? and params[:settings] and params[:settings].is_a? Hash
params[:settings].each { |name, value| Setting[name] = value }
redirect_to :action => 'edit' and return
@notifiables = %w(issue_added issue_updated news_added document_added file_added message_posted)
if request.post? && params[:settings] && params[:settings].is_a?(Hash)
settings = (params[:settings] || {}).dup.symbolize_keys
settings.each do |name, value|
# remove blank values in array settings
value.delete_if {|v| v.blank? } if value.is_a?(Array)
Setting[name] = value
end
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'edit', :tab => params[:tab]
return
end
@options = {}
@options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
@deliveries = ActionMailer::Base.perform_deliveries
@guessed_host_and_path = request.host_with_port.dup
@guessed_host_and_path << ('/'+ request.relative_url_root.gsub(%r{^\/}, '')) unless request.relative_url_root.blank?
end
def plugin
@plugin = Redmine::Plugin.find(params[:id])
if request.post?
Setting["plugin_#{@plugin.id}"] = params[:settings]
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'plugin', :id => @plugin.id
end
@partial = @plugin.settings[:partial]
@settings = Setting["plugin_#{@plugin.id}"]
rescue Redmine::PluginNotFound
render_404
end
end

View File

@@ -0,0 +1,46 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class SysController < ActionController::Base
wsdl_service_name 'Sys'
web_service_api SysApi
web_service_scaffold :invoke
before_invocation :check_enabled
# Returns the projects list, with their repositories
def projects_with_repository_enabled
Project.has_module(:repository).find(:all, :include => :repository, :order => 'identifier')
end
# Registers a repository for the given project identifier
def repository_created(identifier, vendor, url)
project = Project.find_by_identifier(identifier)
# Do not create the repository if the project has already one
return 0 unless project && project.repository.nil?
logger.debug "Repository for #{project.name} was created"
repository = Repository.factory(vendor, :project => project, :url => url)
repository.save
repository.id || 0
end
protected
def check_enabled(name, args)
Setting.sys_api_enabled?
end
end

View File

@@ -0,0 +1,290 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class TimelogController < ApplicationController
menu_item :issues
before_filter :find_project, :authorize, :only => [:edit, :destroy]
before_filter :find_optional_project, :only => [:report, :details]
verify :method => :post, :only => :destroy, :redirect_to => { :action => :details }
helper :sort
include SortHelper
helper :issues
include TimelogHelper
helper :custom_fields
include CustomFieldsHelper
def report
@available_criterias = { 'project' => {:sql => "#{TimeEntry.table_name}.project_id",
:klass => Project,
:label => :label_project},
'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
:klass => Version,
:label => :label_version},
'category' => {:sql => "#{Issue.table_name}.category_id",
:klass => IssueCategory,
:label => :field_category},
'member' => {:sql => "#{TimeEntry.table_name}.user_id",
:klass => User,
:label => :label_member},
'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
:klass => Tracker,
:label => :label_tracker},
'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
:klass => Enumeration,
:label => :label_activity},
'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
:klass => Issue,
:label => :label_issue}
}
# Add list and boolean custom fields as available criterias
custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
@available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)",
:format => cf.field_format,
:label => cf.name}
end if @project
# Add list and boolean time entry custom fields
TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
@available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
:format => cf.field_format,
:label => cf.name}
end
@criterias = params[:criterias] || []
@criterias = @criterias.select{|criteria| @available_criterias.has_key? criteria}
@criterias.uniq!
@criterias = @criterias[0,3]
@columns = (params[:columns] && %w(year month week day).include?(params[:columns])) ? params[:columns] : 'month'
retrieve_date_range
unless @criterias.empty?
sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
sql_group_by = @criterias.collect{|criteria| @available_criterias[criteria][:sql]}.join(', ')
sql = "SELECT #{sql_select}, tyear, tmonth, tweek, spent_on, SUM(hours) AS hours"
sql << " FROM #{TimeEntry.table_name}"
sql << " LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id"
sql << " WHERE"
sql << " (%s) AND" % @project.project_condition(Setting.display_subprojects_issues?) if @project
sql << " (%s) AND" % Project.allowed_to_condition(User.current, :view_time_entries)
sql << " (spent_on BETWEEN '%s' AND '%s')" % [ActiveRecord::Base.connection.quoted_date(@from.to_time), ActiveRecord::Base.connection.quoted_date(@to.to_time)]
sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek, spent_on"
@hours = ActiveRecord::Base.connection.select_all(sql)
@hours.each do |row|
case @columns
when 'year'
row['year'] = row['tyear']
when 'month'
row['month'] = "#{row['tyear']}-#{row['tmonth']}"
when 'week'
row['week'] = "#{row['tyear']}-#{row['tweek']}"
when 'day'
row['day'] = "#{row['spent_on']}"
end
end
@total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
@periods = []
# Date#at_beginning_of_ not supported in Rails 1.2.x
date_from = @from.to_time
# 100 columns max
while date_from <= @to.to_time && @periods.length < 100
case @columns
when 'year'
@periods << "#{date_from.year}"
date_from = (date_from + 1.year).at_beginning_of_year
when 'month'
@periods << "#{date_from.year}-#{date_from.month}"
date_from = (date_from + 1.month).at_beginning_of_month
when 'week'
@periods << "#{date_from.year}-#{date_from.to_date.cweek}"
date_from = (date_from + 7.day).at_beginning_of_week
when 'day'
@periods << "#{date_from.to_date}"
date_from = date_from + 1.day
end
end
end
respond_to do |format|
format.html { render :layout => !request.xhr? }
format.csv { send_data(report_to_csv(@criterias, @periods, @hours).read, :type => 'text/csv; header=present', :filename => 'timelog.csv') }
end
end
def details
sort_init 'spent_on', 'desc'
sort_update 'spent_on' => 'spent_on',
'user' => 'user_id',
'activity' => 'activity_id',
'project' => "#{Project.table_name}.name",
'issue' => 'issue_id',
'hours' => 'hours'
cond = ARCondition.new
if @project.nil?
cond << Project.allowed_to_condition(User.current, :view_time_entries)
elsif @issue.nil?
cond << @project.project_condition(Setting.display_subprojects_issues?)
else
cond << ["#{TimeEntry.table_name}.issue_id = ?", @issue.id]
end
retrieve_date_range
cond << ['spent_on BETWEEN ? AND ?', @from, @to]
TimeEntry.visible_by(User.current) do
respond_to do |format|
format.html {
# Paginate results
@entry_count = TimeEntry.count(:include => :project, :conditions => cond.conditions)
@entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
@entries = TimeEntry.find(:all,
:include => [:project, :activity, :user, {:issue => :tracker}],
:conditions => cond.conditions,
:order => sort_clause,
:limit => @entry_pages.items_per_page,
:offset => @entry_pages.current.offset)
@total_hours = TimeEntry.sum(:hours, :include => :project, :conditions => cond.conditions).to_f
render :layout => !request.xhr?
}
format.atom {
entries = TimeEntry.find(:all,
:include => [:project, :activity, :user, {:issue => :tracker}],
:conditions => cond.conditions,
:order => "#{TimeEntry.table_name}.created_on DESC",
:limit => Setting.feeds_limit.to_i)
render_feed(entries, :title => l(:label_spent_time))
}
format.csv {
# Export all entries
@entries = TimeEntry.find(:all,
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
:conditions => cond.conditions,
:order => sort_clause)
send_data(entries_to_csv(@entries).read, :type => 'text/csv; header=present', :filename => 'timelog.csv')
}
end
end
end
def edit
render_403 and return if @time_entry && !@time_entry.editable_by?(User.current)
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
@time_entry.attributes = params[:time_entry]
if request.post? and @time_entry.save
flash[:notice] = l(:notice_successful_update)
redirect_back_or_default :action => 'details', :project_id => @time_entry.project
return
end
end
def destroy
render_404 and return unless @time_entry
render_403 and return unless @time_entry.editable_by?(User.current)
@time_entry.destroy
flash[:notice] = l(:notice_successful_delete)
redirect_to :back
rescue ::ActionController::RedirectBackError
redirect_to :action => 'details', :project_id => @time_entry.project
end
private
def find_project
if params[:id]
@time_entry = TimeEntry.find(params[:id])
@project = @time_entry.project
elsif params[:issue_id]
@issue = Issue.find(params[:issue_id])
@project = @issue.project
elsif params[:project_id]
@project = Project.find(params[:project_id])
else
render_404
return false
end
rescue ActiveRecord::RecordNotFound
render_404
end
def find_optional_project
if !params[:issue_id].blank?
@issue = Issue.find(params[:issue_id])
@project = @issue.project
elsif !params[:project_id].blank?
@project = Project.find(params[:project_id])
end
deny_access unless User.current.allowed_to?(:view_time_entries, @project, :global => true)
end
# Retrieves the date range based on predefined ranges or specific from/to param dates
def retrieve_date_range
@free_period = false
@from, @to = nil, nil
if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
case params[:period].to_s
when 'today'
@from = @to = Date.today
when 'yesterday'
@from = @to = Date.today - 1
when 'current_week'
@from = Date.today - (Date.today.cwday - 1)%7
@to = @from + 6
when 'last_week'
@from = Date.today - 7 - (Date.today.cwday - 1)%7
@to = @from + 6
when '7_days'
@from = Date.today - 7
@to = Date.today
when 'current_month'
@from = Date.civil(Date.today.year, Date.today.month, 1)
@to = (@from >> 1) - 1
when 'last_month'
@from = Date.civil(Date.today.year, Date.today.month, 1) << 1
@to = (@from >> 1) - 1
when '30_days'
@from = Date.today - 30
@to = Date.today
when 'current_year'
@from = Date.civil(Date.today.year, 1, 1)
@to = Date.civil(Date.today.year, 12, 31)
end
elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
@free_period = true
else
# default
end
@from, @to = @to, @from if @from && @to && @from > @to
@from ||= (TimeEntry.minimum(:spent_on, :include => :project, :conditions => Project.allowed_to_condition(User.current, :view_time_entries)) || Date.today) - 1
@to ||= (TimeEntry.maximum(:spent_on, :include => :project, :conditions => Project.allowed_to_condition(User.current, :view_time_entries)) || Date.today)
end
end

View File

@@ -1,23 +1,22 @@
# redMine - project management software
# Copyright (C) 2006 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.
class TrackersController < ApplicationController
layout 'base'
before_filter :require_admin
# redMine - project management software
# Copyright (C) 2006 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.
class TrackersController < ApplicationController
before_filter :require_admin
def index
list
@@ -28,16 +27,21 @@ class TrackersController < ApplicationController
verify :method => :post, :only => [ :destroy, :move ], :redirect_to => { :action => :list }
def list
@tracker_pages, @trackers = paginate :trackers, :per_page => 10, :order => 'position'
@tracker_pages, @trackers = paginate :trackers, :per_page => 10, :order => 'position'
render :action => "list", :layout => false if request.xhr?
end
def new
@tracker = Tracker.new(params[:tracker])
if request.post? and @tracker.save
# workflow copy
if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
@tracker.workflows.copy(copy_from)
end
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list'
end
@trackers = Tracker.find :all, :order => 'position'
end
def edit
@@ -47,28 +51,28 @@ class TrackersController < ApplicationController
redirect_to :action => 'list'
end
end
def move
@tracker = Tracker.find(params[:id])
case params[:position]
when 'highest'
@tracker.move_to_top
when 'higher'
@tracker.move_higher
when 'lower'
@tracker.move_lower
when 'lowest'
@tracker.move_to_bottom
end if params[:position]
redirect_to :action => 'list'
end
def move
@tracker = Tracker.find(params[:id])
case params[:position]
when 'highest'
@tracker.move_to_top
when 'higher'
@tracker.move_higher
when 'lower'
@tracker.move_lower
when 'lowest'
@tracker.move_to_bottom
end if params[:position]
redirect_to :action => 'list'
end
def destroy
@tracker = Tracker.find(params[:id])
unless @tracker.issues.empty?
flash[:notice] = "This tracker contains issues and can\'t be deleted."
else
@tracker.destroy
@tracker = Tracker.find(params[:id])
unless @tracker.issues.empty?
flash[:error] = "This tracker contains issues and can\'t be deleted."
else
@tracker.destroy
end
redirect_to :action => 'list'
end

View File

@@ -1,113 +1,108 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class UsersController < ApplicationController
layout 'base'
before_filter :require_admin
helper :sort
include SortHelper
helper :custom_fields
include CustomFieldsHelper
# redMine - project management software
# Copyright (C) 2006-2007 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.
class UsersController < ApplicationController
before_filter :require_admin
helper :sort
include SortHelper
helper :custom_fields
include CustomFieldsHelper
def index
list
render :action => 'list' unless request.xhr?
end
def list
sort_init 'login', 'asc'
sort_update
@user_count = User.count
@user_pages = Paginator.new self, @user_count,
15,
params['page']
@users = User.find :all,:order => sort_clause,
:limit => @user_pages.items_per_page,
:offset => @user_pages.current.offset
def list
sort_init 'login', 'asc'
sort_update %w(login firstname lastname mail admin created_on last_login_on)
@status = params[:status] ? params[:status].to_i : 1
c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status])
unless params[:name].blank?
name = "%#{params[:name].strip.downcase}%"
c << ["LOWER(login) LIKE ? OR LOWER(firstname) LIKE ? OR LOWER(lastname) LIKE ?", name, name, name]
end
@user_count = User.count(:conditions => c.conditions)
@user_pages = Paginator.new self, @user_count,
per_page_option,
params['page']
@users = User.find :all,:order => sort_clause,
:conditions => c.conditions,
:limit => @user_pages.items_per_page,
:offset => @user_pages.current.offset
render :action => "list", :layout => false if request.xhr?
end
def add
if request.get?
@user = User.new(:language => Setting.default_language)
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
if request.get?
@user = User.new(:language => Setting.default_language)
else
@user = User.new(params[:user])
@user.admin = params[:user][:admin] || false
@user.login = params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
@user = User.new(params[:user])
@user.admin = params[:user][:admin] || false
@user.login = params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id
if @user.save
Mailer.deliver_account_information(@user, params[:password]) if params[:send_information]
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list'
end
end
end
end
@auth_sources = AuthSource.find(:all)
end
def edit
@user = User.find(params[:id])
if request.get?
@custom_values = UserCustomField.find(:all).collect { |x| @user.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
else
@user.admin = params[:user][:admin] if params[:user][:admin]
@user.login = params[:user][:login] if params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty? or @user.auth_source_id
if params[:custom_fields]
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
end
if @user.update_attributes(params[:user])
if request.post?
@user.admin = params[:user][:admin] if params[:user][:admin]
@user.login = params[:user][:login] if params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty? or @user.auth_source_id
@user.attributes = params[:user]
# Was the account actived ? (do it before User#save clears the change)
was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE])
if @user.save
Mailer.deliver_account_activated(@user) if was_activated
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list'
end
# Give a string to redirect_to otherwise it would use status param as the response code
redirect_to(url_for(:action => 'list', :status => params[:status], :page => params[:page]))
end
end
@auth_sources = AuthSource.find(:all)
@roles = Role.find(:all, :order => 'position')
@projects = Project.find(:all) - @user.projects
@membership ||= Member.new
end
def edit_membership
@user = User.find(params[:id])
@membership = params[:membership_id] ? Member.find(params[:membership_id]) : Member.new(:user => @user)
@membership.attributes = params[:membership]
if request.post? and @membership.save
flash[:notice] = l(:notice_successful_update)
end
redirect_to :action => 'edit', :id => @user and return
end
def destroy_membership
@user = User.find(params[:id])
if request.post? and Member.find(params[:membership_id]).destroy
flash[:notice] = l(:notice_successful_update)
end
redirect_to :action => 'edit', :id => @user and return
@auth_sources = AuthSource.find(:all)
@roles = Role.find_all_givable
@projects = Project.find(:all, :order => 'name', :conditions => "status=#{Project::STATUS_ACTIVE}") - @user.projects
@membership ||= Member.new
@memberships = @user.memberships
end
def edit_membership
@user = User.find(params[:id])
@membership = params[:membership_id] ? Member.find(params[:membership_id]) : Member.new(:user => @user)
@membership.attributes = params[:membership]
@membership.save if request.post?
redirect_to :action => 'edit', :id => @user, :tab => 'memberships'
end
def destroy_membership
@user = User.find(params[:id])
Member.find(params[:membership_id]).destroy if request.post?
redirect_to :action => 'edit', :id => @user, :tab => 'memberships'
end
def destroy
User.find(params[:id]).destroy
redirect_to :action => 'list'
rescue
flash[:notice] = "Unable to delete user"
redirect_to :action => 'list'
end
end

View File

@@ -1,24 +1,27 @@
# redMine - project management software
# Copyright (C) 2006 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.
class VersionsController < ApplicationController
layout 'base'
before_filter :find_project, :authorize
# redMine - project management software
# Copyright (C) 2006 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.
class VersionsController < ApplicationController
menu_item :roadmap
before_filter :find_project, :authorize
def show
end
def edit
if request.post? and @version.update_attributes(params[:version])
flash[:notice] = l(:notice_successful_update)
@@ -26,33 +29,26 @@ class VersionsController < ApplicationController
end
end
def destroy
def destroy
@version.destroy
redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
rescue
flash[:notice] = "Unable to delete version"
redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
end
def download
@attachment = @version.attachments.find(params[:attachment_id])
@attachment.increment_download
send_file @attachment.diskfile, :filename => @attachment.filename
rescue
render_404
end
def destroy_file
@version.attachments.find(params[:attachment_id]).destroy
flash[:notice] = l(:notice_successful_delete)
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
end
private
def find_project
@version = Version.find(params[:id])
@project = @version.project
rescue ActiveRecord::RecordNotFound
render_404
redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
rescue
flash[:error] = l(:notice_unable_delete_version)
redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
end
def status_by
respond_to do |format|
format.html { render :action => 'show' }
format.js { render(:update) {|page| page.replace_html 'status_by', render_issue_status_by(@version, params[:status_by])} }
end
end
private
def find_project
@version = Version.find(params[:id])
@project = @version.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -0,0 +1,70 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class WatchersController < ApplicationController
before_filter :find_project
before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch]
before_filter :authorize, :only => :new
verify :method => :post,
:only => [ :watch, :unwatch ],
:render => { :nothing => true, :status => :method_not_allowed }
def watch
set_watcher(User.current, true)
end
def unwatch
set_watcher(User.current, false)
end
def new
@watcher = Watcher.new(params[:watcher])
@watcher.watchable = @watched
@watcher.save if request.post?
respond_to do |format|
format.html { redirect_to :back }
format.js do
render :update do |page|
page.replace_html 'watchers', :partial => 'watchers/watchers', :locals => {:watched => @watched}
end
end
end
rescue ::ActionController::RedirectBackError
render :text => 'Watcher added.', :layout => true
end
private
def find_project
klass = Object.const_get(params[:object_type].camelcase)
return false unless klass.respond_to?('watched_by')
@watched = klass.find(params[:object_id])
@project = @watched.project
rescue
render_404
end
def set_watcher(user, watching)
@watched.set_watcher(user, watching)
respond_to do |format|
format.html { redirect_to :back }
format.js { render(:update) {|page| page.replace_html 'watcher', watcher_link(@watched, user)} }
end
rescue ::ActionController::RedirectBackError
render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true
end
end

View File

@@ -1,25 +1,24 @@
# redMine - project management software
# Copyright (C) 2006 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.
class WelcomeController < ApplicationController
layout 'base'
def index
@news = News.latest logged_in_user
@projects = Project.latest logged_in_user
# redMine - project management software
# Copyright (C) 2006 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.
class WelcomeController < ApplicationController
def index
@news = News.latest User.current
@projects = Project.latest User.current
end
end

View File

@@ -0,0 +1,211 @@
# redMine - project management software
# Copyright (C) 2006-2007 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 'diff'
class WikiController < ApplicationController
before_filter :find_wiki, :authorize
before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
verify :method => :post, :only => [:destroy, :protect], :redirect_to => { :action => :index }
helper :attachments
include AttachmentsHelper
# display a page (in editing mode if it doesn't exist)
def index
page_title = params[:page]
@page = @wiki.find_or_new_page(page_title)
if @page.new_record?
if User.current.allowed_to?(:edit_wiki_pages, @project)
edit
render :action => 'edit'
else
render_404
end
return
end
if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
# Redirects user to the current version if he's not allowed to view previous versions
redirect_to :version => nil
return
end
@content = @page.content_for_version(params[:version])
if params[:export] == 'html'
export = render_to_string :action => 'export', :layout => false
send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
return
elsif params[:export] == 'txt'
send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
return
end
@editable = editable?
render :action => 'show'
end
# edit an existing page or a new one
def edit
@page = @wiki.find_or_new_page(params[:page])
return render_403 unless editable?
@page.content = WikiContent.new(:page => @page) if @page.new_record?
@content = @page.content_for_version(params[:version])
@content.text = initial_page_content(@page) if @content.text.blank?
# don't keep previous comment
@content.comments = nil
if request.get?
# To prevent StaleObjectError exception when reverting to a previous version
@content.version = @page.content.version
else
if !@page.new_record? && @content.text == params[:content][:text]
# don't save if text wasn't changed
redirect_to :action => 'index', :id => @project, :page => @page.title
return
end
#@content.text = params[:content][:text]
#@content.comments = params[:content][:comments]
@content.attributes = params[:content]
@content.author = User.current
# if page is new @page.save will also save content, but not if page isn't a new record
if (@page.new_record? ? @page.save : @content.save)
redirect_to :action => 'index', :id => @project, :page => @page.title
end
end
rescue ActiveRecord::StaleObjectError
# Optimistic locking exception
flash[:error] = l(:notice_locking_conflict)
end
# rename a page
def rename
return render_403 unless editable?
@page.redirect_existing_links = true
# used to display the *original* title if some AR validation errors occur
@original_title = @page.pretty_title
if request.post? && @page.update_attributes(params[:wiki_page])
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'index', :id => @project, :page => @page.title
end
end
def protect
@page.update_attribute :protected, params[:protected]
redirect_to :action => 'index', :id => @project, :page => @page.title
end
# show page history
def history
@version_count = @page.content.versions.count
@version_pages = Paginator.new self, @version_count, per_page_option, params['p']
# don't load text
@versions = @page.content.versions.find :all,
:select => "id, author_id, comments, updated_on, version",
:order => 'version DESC',
:limit => @version_pages.items_per_page + 1,
:offset => @version_pages.current.offset
render :layout => false if request.xhr?
end
def diff
@diff = @page.diff(params[:version], params[:version_from])
render_404 unless @diff
end
def annotate
@annotate = @page.annotate(params[:version])
render_404 unless @annotate
end
# remove a wiki page and its history
def destroy
return render_403 unless editable?
@page.destroy
redirect_to :action => 'special', :id => @project, :page => 'Page_index'
end
# display special pages
def special
page_title = params[:page].downcase
case page_title
# show pages index, sorted by title
when 'page_index', 'date_index'
# eager load information about last updates, without loading text
@pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
:joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
:order => 'title'
@pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
@pages_by_parent_id = @pages.group_by(&:parent_id)
# export wiki to a single html file
when 'export'
@pages = @wiki.pages.find :all, :order => 'title'
export = render_to_string :action => 'export_multiple', :layout => false
send_data(export, :type => 'text/html', :filename => "wiki.html")
return
else
# requested special page doesn't exist, redirect to default page
redirect_to :action => 'index', :id => @project, :page => nil and return
end
render :action => "special_#{page_title}"
end
def preview
page = @wiki.find_page(params[:page])
# page is nil when previewing a new page
return render_403 unless page.nil? || editable?(page)
if page
@attachements = page.attachments
@previewed = page.content
end
@text = params[:content][:text]
render :partial => 'common/preview'
end
def add_attachment
return render_403 unless editable?
attach_files(@page, params[:attachments])
redirect_to :action => 'index', :page => @page.title
end
private
def find_wiki
@project = Project.find(params[:id])
@wiki = @project.wiki
render_404 unless @wiki
rescue ActiveRecord::RecordNotFound
render_404
end
# Finds the requested page and returns a 404 error if it doesn't exist
def find_existing_page
@page = @wiki.find_page(params[:page])
render_404 if @page.nil?
end
# Returns true if the current user is allowed to edit the page, otherwise false
def editable?(page = @page)
page.editable_by?(User.current)
end
# Returns the default content of a new wiki page
def initial_page_content(page)
helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
extend helper unless self.instance_of?(helper)
helper.instance_method(:initial_page_content).bind(self).call(page)
end
end

View File

@@ -0,0 +1,44 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class WikisController < ApplicationController
menu_item :settings
before_filter :find_project, :authorize
# Create or update a project's wiki
def edit
@wiki = @project.wiki || Wiki.new(:project => @project)
@wiki.attributes = params[:wiki]
@wiki.save if request.post?
render(:update) {|page| page.replace_html "tab-content-wiki", :partial => 'projects/settings/wiki'}
end
# Delete a project's wiki
def destroy
if request.post? && params[:confirm] && @project.wiki
@project.wiki.destroy
redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'wiki'
end
end
private
def find_project
@project = Project.find(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@@ -0,0 +1,45 @@
# Redmine - project management software
# Copyright (C) 2006-2008 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.
class WorkflowsController < ApplicationController
before_filter :require_admin
def index
@workflow_counts = Workflow.count_by_tracker_and_role
end
def edit
@role = Role.find_by_id(params[:role_id])
@tracker = Tracker.find_by_id(params[:tracker_id])
if request.post?
Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
(params[:issue_status] || []).each { |old, news|
news.each { |new|
@role.workflows.build(:tracker_id => @tracker.id, :old_status_id => old, :new_status_id => new)
}
}
if @role.save
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'edit', :role_id => @role, :tracker_id => @tracker
end
end
@roles = Role.find(:all, :order => 'builtin, position')
@trackers = Tracker.find(:all, :order => 'position')
@statuses = IssueStatus.find(:all, :order => 'position')
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module AccountHelper
end

View File

@@ -1,19 +1,23 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module AdminHelper
def project_status_options_for_select(selected)
options_for_select([[l(:label_all), ''],
[l(:status_active), 1]], selected)
end
end

View File

@@ -1,193 +1,627 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
module ApplicationHelper
# Return current logged in user or nil
def loggedin?
@logged_in_user
end
# Return true if user is logged in and is admin, otherwise false
def admin_loggedin?
@logged_in_user and @logged_in_user.admin?
end
# Return true if user is authorized for controller/action, otherwise false
def authorize_for(controller, action)
# check if action is allowed on public projects
if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ controller, action ]
return true
end
# check if user is authorized
if @logged_in_user and (@logged_in_user.admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], @logged_in_user.role_for_project(@project.id) ) )
return true
end
return false
end
# Display a link if user is authorized
def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action])
end
# Display a link to user's account page
def link_to_user(user)
link_to user.display_name, :controller => 'account', :action => 'show', :id => user
end
def image_to_function(name, function, html_options = {})
html_options.symbolize_keys!
tag(:input, html_options.merge({
:type => "image", :src => image_path(name),
:onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
}))
end
def format_date(date)
l_date(date) if date
end
def format_time(time)
l_datetime(time) if time
end
def day_name(day)
l(:general_day_names).split(',')[day-1]
end
def month_name(month)
l(:actionview_datehelper_select_month_names).split(',')[month-1]
end
def pagination_links_full(paginator, options={}, html_options={})
html = ''
html << link_to_remote(('&#171; ' + l(:label_previous)),
{:update => "content", :url => { :page => paginator.current.previous }},
{:href => url_for(:action => 'list', :params => params.merge({:page => paginator.current.previous}))}) + ' ' if paginator.current.previous
html << (pagination_links_each(paginator, options) do |n|
link_to_remote(n.to_s,
{:url => {:action => 'list', :params => params.merge({:page => n})}, :update => 'content'},
{:href => url_for(:action => 'list', :params => params.merge({:page => n}))})
end || '')
html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
{:update => "content", :url => { :page => paginator.current.next }},
{:href => url_for(:action => 'list', :params => params.merge({:page => paginator.current.next}))}) if paginator.current.next
html
end
def textilizable(text)
(Setting.text_formatting == 'textile') && (ActionView::Helpers::TextHelper.method_defined? "textilize") ? RedCloth.new(h(text)).to_html : simple_format(auto_link(h(text)))
end
def error_messages_for(object_name, options = {})
options = options.symbolize_keys
object = instance_variable_get("@#{object_name}")
if object && !object.errors.empty?
# build full_messages here with controller current language
full_messages = []
object.errors.each do |attr, msg|
next if msg.nil?
if attr == "base"
full_messages << l(msg)
else
full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
end
end
# retrieve custom values error messages
if object.errors[:custom_values]
object.custom_values.each do |v|
v.errors.each do |attr, msg|
next if msg.nil?
full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
end
end
end
content_tag("div",
content_tag(
options[:header_tag] || "h2", lwr(:gui_validation_error, full_messages.length) + " :"
) +
content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
"id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
)
else
""
end
end
def lang_options_for_select(blank=true)
(blank ? [["(auto)", ""]] : []) +
(GLoc.valid_languages.sort {|x,y| x.to_s <=> y.to_s }).collect {|lang| [ l_lang_name(lang.to_s, lang), lang.to_s]}
end
def label_tag_for(name, option_tags = nil, options = {})
label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
content_tag("label", label_text)
end
def labelled_tabular_form_for(name, object, options, &proc)
options[:html] ||= {}
options[:html].store :class, "tabular"
form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
end
def check_all_links(form_name)
link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
" | " +
link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
end
def calendar_for(field_id)
image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
end
# redMine - project management software
# Copyright (C) 2006-2007 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 'coderay'
require 'coderay/helpers/file_type'
require 'forwardable'
require 'cgi'
module ApplicationHelper
include Redmine::WikiFormatting::Macros::Definitions
include GravatarHelper::PublicMethods
extend Forwardable
def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
def current_role
@current_role ||= User.current.role_for_project(@project)
end
# Return true if user is authorized for controller/action, otherwise false
def authorize_for(controller, action)
User.current.allowed_to?({:controller => controller, :action => action}, @project)
end
# Display a link if user is authorized
def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
end
# Display a link to remote if user is authorized
def link_to_remote_if_authorized(name, options = {}, html_options = nil)
url = options[:url] || {}
link_to_remote(name, options, html_options) if authorize_for(url[:controller] || params[:controller], url[:action])
end
# Display a link to user's account page
def link_to_user(user, options={})
(user && !user.anonymous?) ? link_to(user.name(options[:format]), :controller => 'account', :action => 'show', :id => user) : 'Anonymous'
end
def link_to_issue(issue, options={})
options[:class] ||= ''
options[:class] << ' issue'
options[:class] << ' closed' if issue.closed?
link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
end
# Generates a link to an attachment.
# Options:
# * :text - Link text (default to attachment filename)
# * :download - Force download (default: false)
def link_to_attachment(attachment, options={})
text = options.delete(:text) || attachment.filename
action = options.delete(:download) ? 'download' : 'show'
link_to(h(text), {:controller => 'attachments', :action => action, :id => attachment, :filename => attachment.filename }, options)
end
def toggle_link(name, id, options={})
onclick = "Element.toggle('#{id}'); "
onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
onclick << "return false;"
link_to(name, "#", :onclick => onclick)
end
def image_to_function(name, function, html_options = {})
html_options.symbolize_keys!
tag(:input, html_options.merge({
:type => "image", :src => image_path(name),
:onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
}))
end
def prompt_to_remote(name, text, param, url, html_options = {})
html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
link_to name, {}, html_options
end
def format_date(date)
return nil unless date
# "Setting.date_format.size < 2" is a temporary fix (content of date_format setting changed)
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
date.strftime(@date_format)
end
def format_time(time, include_date = true)
return nil unless time
time = time.to_time if time.is_a?(String)
zone = User.current.time_zone
local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
@time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
end
def format_activity_title(text)
h(truncate_single_line(text, 100))
end
def format_activity_day(date)
date == Date.today ? l(:label_today).titleize : format_date(date)
end
def format_activity_description(text)
h(truncate(text.to_s, 250).gsub(%r{<(pre|code)>.*$}m, '...'))
end
def distance_of_date_in_words(from_date, to_date = 0)
from_date = from_date.to_date if from_date.respond_to?(:to_date)
to_date = to_date.to_date if to_date.respond_to?(:to_date)
distance_in_days = (to_date - from_date).abs
lwr(:actionview_datehelper_time_in_words_day, distance_in_days)
end
def due_date_distance_in_words(date)
if date
l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date))
end
end
def render_page_hierarchy(pages, node=nil)
content = ''
if pages[node]
content << "<ul class=\"pages-hierarchy\">\n"
pages[node].each do |page|
content << "<li>"
content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'index', :id => page.project, :page => page.title},
:title => (page.respond_to?(:updated_on) ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
content << "\n" + render_page_hierarchy(pages, page.id) if pages[page.id]
content << "</li>\n"
end
content << "</ul>\n"
end
content
end
# Renders flash messages
def render_flash_messages
s = ''
flash.each do |k,v|
s << content_tag('div', v, :class => "flash #{k}")
end
s
end
# Truncates and returns the string as a single line
def truncate_single_line(string, *args)
truncate(string, *args).gsub(%r{[\r\n]+}m, ' ')
end
def html_hours(text)
text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
end
def authoring(created, author, options={})
time_tag = @project.nil? ? content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created)) :
link_to(distance_of_time_in_words(Time.now, created),
{:controller => 'projects', :action => 'activity', :id => @project, :from => created.to_date},
:title => format_time(created))
author_tag = (author.is_a?(User) && !author.anonymous?) ? link_to(h(author), :controller => 'account', :action => 'show', :id => author) : h(author || 'Anonymous')
l(options[:label] || :label_added_time_by, author_tag, time_tag)
end
def l_or_humanize(s, options={})
k = "#{options[:prefix]}#{s}".to_sym
l_has_string?(k) ? l(k) : s.to_s.humanize
end
def day_name(day)
l(:general_day_names).split(',')[day-1]
end
def month_name(month)
l(:actionview_datehelper_select_month_names).split(',')[month-1]
end
def syntax_highlight(name, content)
type = CodeRay::FileType[name]
type ? CodeRay.scan(content, type).html : h(content)
end
def to_path_param(path)
path.to_s.split(%r{[/\\]}).select {|p| !p.blank?}
end
def pagination_links_full(paginator, count=nil, options={})
page_param = options.delete(:page_param) || :page
url_param = params.dup
# don't reuse params if filters are present
url_param.clear if url_param.has_key?(:set_filter)
html = ''
html << link_to_remote(('&#171; ' + l(:label_previous)),
{:update => 'content',
:url => url_param.merge(page_param => paginator.current.previous),
:complete => 'window.scrollTo(0,0)'},
{:href => url_for(:params => url_param.merge(page_param => paginator.current.previous))}) + ' ' if paginator.current.previous
html << (pagination_links_each(paginator, options) do |n|
link_to_remote(n.to_s,
{:url => {:params => url_param.merge(page_param => n)},
:update => 'content',
:complete => 'window.scrollTo(0,0)'},
{:href => url_for(:params => url_param.merge(page_param => n))})
end || '')
html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
{:update => 'content',
:url => url_param.merge(page_param => paginator.current.next),
:complete => 'window.scrollTo(0,0)'},
{:href => url_for(:params => url_param.merge(page_param => paginator.current.next))}) if paginator.current.next
unless count.nil?
html << [" (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})", per_page_links(paginator.items_per_page)].compact.join(' | ')
end
html
end
def per_page_links(selected=nil)
url_param = params.dup
url_param.clear if url_param.has_key?(:set_filter)
links = Setting.per_page_options_array.collect do |n|
n == selected ? n : link_to_remote(n, {:update => "content", :url => params.dup.merge(:per_page => n)},
{:href => url_for(url_param.merge(:per_page => n))})
end
links.size > 1 ? l(:label_display_per_page, links.join(', ')) : nil
end
def breadcrumb(*args)
elements = args.flatten
elements.any? ? content_tag('p', args.join(' &#187; ') + ' &#187; ', :class => 'breadcrumb') : nil
end
def html_title(*args)
if args.empty?
title = []
title << @project.name if @project
title += @html_title if @html_title
title << Setting.app_title
title.compact.join(' - ')
else
@html_title ||= []
@html_title += args
end
end
def accesskey(s)
Redmine::AccessKeys.key_for s
end
# Formats text according to system settings.
# 2 ways to call this method:
# * with a String: textilizable(text, options)
# * with an object and one of its attribute: textilizable(issue, :description, options)
def textilizable(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
case args.size
when 1
obj = options[:object]
text = args.shift
when 2
obj = args.shift
text = obj.send(args.shift).to_s
else
raise ArgumentError, 'invalid arguments to textilizable'
end
return '' if text.blank?
only_path = options.delete(:only_path) == false ? false : true
# when using an image link, try to use an attachment, if possible
attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
if attachments
attachments = attachments.sort_by(&:created_on).reverse
text = text.gsub(/!((\<|\=|\>)?(\([^\)]+\))?(\[[^\]]+\])?(\{[^\}]+\})?)(\S+\.(bmp|gif|jpg|jpeg|png))!/i) do |m|
style = $1
filename = $6.downcase
# search for the picture in attachments
if found = attachments.detect { |att| att.filename.downcase == filename }
image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found
desc = found.description.to_s.gsub(/^([^\(\)]*).*$/, "\\1")
alt = desc.blank? ? nil : "(#{desc})"
"!#{style}#{image_url}#{alt}!"
else
m
end
end
end
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text) { |macro, args| exec_macro(macro, obj, args) }
# different methods for formatting wiki links
case options[:wiki_links]
when :local
# used for local links to html files
format_wiki_link = Proc.new {|project, title, anchor| "#{title}.html" }
when :anchor
# used for single-file wiki export
format_wiki_link = Proc.new {|project, title, anchor| "##{title}" }
else
format_wiki_link = Proc.new {|project, title, anchor| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title, :anchor => anchor) }
end
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
# Wiki links
#
# Examples:
# [[mypage]]
# [[mypage|mytext]]
# wiki links can refer other project wikis, using project name or identifier:
# [[project:]] -> wiki starting page
# [[project:|mytext]]
# [[project:mypage]]
# [[project:mypage|mytext]]
text = text.gsub(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
link_project = project
esc, all, page, title = $1, $2, $3, $5
if esc.nil?
if page =~ /^([^\:]+)\:(.*)$/
link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
page = $2
title ||= $1 if page.blank?
end
if link_project && link_project.wiki
# extract anchor
anchor = nil
if page =~ /^(.+?)\#(.+)$/
page, anchor = $1, $2
end
# check if page exists
wiki_page = link_project.wiki.find_page(page)
link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page), anchor),
:class => ('wiki-page' + (wiki_page ? '' : ' new')))
else
# project or wiki doesn't exist
title || page
end
else
all
end
end
# Redmine links
#
# Examples:
# Issues:
# #52 -> Link to issue #52
# Changesets:
# r52 -> Link to revision 52
# commit:a85130f -> Link to scmid starting with a85130f
# Documents:
# document#17 -> Link to document with id 17
# document:Greetings -> Link to the document with title "Greetings"
# document:"Some document" -> Link to the document with title "Some document"
# Versions:
# version#3 -> Link to version with id 3
# version:1.0.0 -> Link to version named "1.0.0"
# version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
# Attachments:
# attachment:file.zip -> Link to the attachment of the current object named file.zip
# Source files:
# source:some/file -> Link to the file located at /some/file in the project's repository
# source:some/file@52 -> Link to the file's revision 52
# source:some/file#L120 -> Link to line 120 of the file
# source:some/file@52#L120 -> Link to line 120 of the file's revision 52
# export:some/file -> Force the download of the file
# Forum messages:
# message#1218 -> Link to message with id 1218
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|\s|<|$)}) do |m|
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
link = nil
if esc.nil?
if prefix.nil? && sep == 'r'
if project && (changeset = project.changesets.find_by_revision(oid))
link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid},
:class => 'changeset',
:title => truncate_single_line(changeset.comments, 100))
end
elsif sep == '#'
oid = oid.to_i
case prefix
when nil
if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
:class => (issue.closed? ? 'issue closed' : 'issue'),
:title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
link = content_tag('del', link) if issue.closed?
end
when 'document'
if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
:class => 'document'
end
when 'version'
if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
:class => 'version'
end
when 'message'
if message = Message.find_by_id(oid, :include => [:parent, {:board => :project}], :conditions => Project.visible_by(User.current))
link = link_to h(truncate(message.subject, 60)), {:only_path => only_path,
:controller => 'messages',
:action => 'show',
:board_id => message.board,
:id => message.root,
:anchor => (message.parent ? "message-#{message.id}" : nil)},
:class => 'message'
end
end
elsif sep == ':'
# removes the double quotes if any
name = oid.gsub(%r{^"(.*)"$}, "\\1")
case prefix
when 'document'
if project && document = project.documents.find_by_title(name)
link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
:class => 'document'
end
when 'version'
if project && version = project.versions.find_by_name(name)
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
:class => 'version'
end
when 'commit'
if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
:class => 'changeset',
:title => truncate_single_line(changeset.comments, 100)
end
when 'source', 'export'
if project && project.repository
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
path, rev, anchor = $1, $3, $5
link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project,
:path => to_path_param(path),
:rev => rev,
:anchor => anchor,
:format => (prefix == 'export' ? 'raw' : nil)},
:class => (prefix == 'export' ? 'source download' : 'source')
end
when 'attachment'
if attachments && attachment = attachments.detect {|a| a.filename == name }
link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
:class => 'attachment'
end
end
end
end
leading + (link || "#{prefix}#{sep}#{oid}")
end
text
end
# Same as Rails' simple_format helper without using paragraphs
def simple_format_without_paragraph(text)
text.to_s.
gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
end
def error_messages_for(object_name, options = {})
options = options.symbolize_keys
object = instance_variable_get("@#{object_name}")
if object && !object.errors.empty?
# build full_messages here with controller current language
full_messages = []
object.errors.each do |attr, msg|
next if msg.nil?
msg = [msg] unless msg.is_a?(Array)
if attr == "base"
full_messages << l(*msg)
else
full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(*msg) unless attr == "custom_values"
end
end
# retrieve custom values error messages
if object.errors[:custom_values]
object.custom_values.each do |v|
v.errors.each do |attr, msg|
next if msg.nil?
msg = [msg] unless msg.is_a?(Array)
full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(*msg)
end
end
end
content_tag("div",
content_tag(
options[:header_tag] || "span", lwr(:gui_validation_error, full_messages.length) + ":"
) +
content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
"id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
)
else
""
end
end
def lang_options_for_select(blank=true)
(blank ? [["(auto)", ""]] : []) +
GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
end
def label_tag_for(name, option_tags = nil, options = {})
label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
content_tag("label", label_text)
end
def labelled_tabular_form_for(name, object, options, &proc)
options[:html] ||= {}
options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
end
def back_url_hidden_field_tag
back_url = params[:back_url] || request.env['HTTP_REFERER']
back_url = CGI.unescape(back_url.to_s)
hidden_field_tag('back_url', CGI.escape(back_url)) unless back_url.blank?
end
def check_all_links(form_name)
link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
" | " +
link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
end
def progress_bar(pcts, options={})
pcts = [pcts, pcts] unless pcts.is_a?(Array)
pcts[1] = pcts[1] - pcts[0]
pcts << (100 - pcts[1] - pcts[0])
width = options[:width] || '100px;'
legend = options[:legend] || ''
content_tag('table',
content_tag('tr',
(pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0].floor}%;", :class => 'closed') : '') +
(pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1].floor}%;", :class => 'done') : '') +
(pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2].floor}%;", :class => 'todo') : '')
), :class => 'progress', :style => "width: #{width};") +
content_tag('p', legend, :class => 'pourcent')
end
def context_menu_link(name, url, options={})
options[:class] ||= ''
if options.delete(:selected)
options[:class] << ' icon-checked disabled'
options[:disabled] = true
end
if options.delete(:disabled)
options.delete(:method)
options.delete(:confirm)
options.delete(:onclick)
options[:class] << ' disabled'
url = '#'
end
link_to name, url, options
end
def calendar_for(field_id)
include_calendar_headers_tags
image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
end
def include_calendar_headers_tags
unless @calendar_headers_tags_included
@calendar_headers_tags_included = true
content_for :header_tags do
javascript_include_tag('calendar/calendar') +
javascript_include_tag("calendar/lang/calendar-#{current_language}.js") +
javascript_include_tag('calendar/calendar-setup') +
stylesheet_link_tag('calendar')
end
end
end
def content_for(name, content = nil, &block)
@has_content ||= {}
@has_content[name] = true
super(name, content, &block)
end
def has_content?(name)
(@has_content && @has_content[name]) || false
end
# Returns the avatar image tag for the given +user+ if avatars are enabled
# +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
def avatar(user, options = { })
if Setting.gravatar_enabled?
email = nil
if user.respond_to?(:mail)
email = user.mail
elsif user.to_s =~ %r{<(.+?)>}
email = $1
end
return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil
end
end
private
def wiki_helper
helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
extend helper
return self
end
end
class TabularFormBuilder < ActionView::Helpers::FormBuilder
include GLoc
def initialize(object_name, object, template, options, proc)
set_language_if_valid options.delete(:lang)
@object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
end
(field_helpers - %w(radio_button hidden_field) + %w(date_select)).each do |selector|
src = <<-END_SRC
def #{selector}(field, options = {})
return super if options.delete :no_label
label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
label = @template.content_tag("label", label_text,
:class => (@object && @object.errors[field] ? "error" : nil),
:for => (@object_name.to_s + "_" + field.to_s))
label + super
end
END_SRC
class_eval src, __FILE__, __LINE__
end
def select(field, choices, options = {}, html_options = {})
label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
label = @template.content_tag("label", label_text,
:class => (@object && @object.errors[field] ? "error" : nil),
:for => (@object_name.to_s + "_" + field.to_s))
label + super
end
end

View File

@@ -0,0 +1,34 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
module AttachmentsHelper
# Displays view/delete links to the attachments of the given object
# Options:
# :author -- author names are not displayed if set to false
def link_to_attachments(container, options = {})
options.assert_valid_keys(:author)
if container.attachments.any?
options = {:deletable => container.attachments_deletable?, :author => true}.merge(options)
render :partial => 'attachments/links', :locals => {:attachments => container.attachments, :options => options}
end
end
def to_utf8(str)
str
end
end

View File

@@ -1,5 +1,5 @@
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
# Copyright (C) 2006-2007 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
@@ -15,5 +15,5 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module FeedsHelper
module BoardsHelper
end

View File

@@ -1,77 +1,88 @@
# redMine - project management software
# Copyright (C) 2006 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.
module CustomFieldsHelper
# Return custom field html tag corresponding to its format
def custom_field_tag(custom_value)
custom_field = custom_value.custom_field
field_name = "custom_fields[#{custom_field.id}]"
field_id = "custom_fields_#{custom_field.id}"
case custom_field.field_format
when "string", "int"
text_field 'custom_value', 'value', :name => field_name, :id => field_id
when "date"
text_field('custom_value', 'value', :name => field_name, :id => field_id, :size => 10) +
calendar_for(field_id)
when "text"
text_area 'custom_value', 'value', :name => field_name, :id => field_id, :cols => 60, :rows => 3
when "bool"
check_box 'custom_value', 'value', :name => field_name, :id => field_id
when "list"
select 'custom_value', 'value', custom_field.possible_values, { :include_blank => true }, :name => field_name, :id => field_id
end
end
# Return custom field label tag
def custom_field_label_tag(custom_value)
content_tag "label", custom_value.custom_field.name +
(custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>" : ""),
:for => "custom_fields_#{custom_value.custom_field.id}",
:class => (custom_value.errors.empty? ? nil : "error" )
end
# Return custom field tag with its label tag
def custom_field_tag_with_label(custom_value)
custom_field_label_tag(custom_value) + custom_field_tag(custom_value)
end
# Return a string used to display a custom value
def show_value(custom_value)
return "" unless custom_value
format_value(custom_value.value, custom_value.custom_field.field_format)
end
# Return a string used to display a custom value
def format_value(value, field_format)
return "" unless value && !value.empty?
case field_format
when "date"
begin; l_date(value.to_date); rescue; value end
when "bool"
l_YesNo(value == "1")
else
value
end
end
# Return an array of custom field formats which can be used in select_tag
def custom_field_formats_for_select
CustomField::FIELD_FORMATS.sort {|a,b| a[1][:order]<=>b[1][:order]}.collect { |k| [ l(k[1][:name]), k[0] ] }
# redMine - project management software
# Copyright (C) 2006 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.
module CustomFieldsHelper
def custom_fields_tabs
tabs = [{:name => 'IssueCustomField', :label => :label_issue_plural},
{:name => 'TimeEntryCustomField', :label => :label_spent_time},
{:name => 'ProjectCustomField', :label => :label_project_plural},
{:name => 'UserCustomField', :label => :label_user_plural}
]
end
# Return custom field html tag corresponding to its format
def custom_field_tag(name, custom_value)
custom_field = custom_value.custom_field
field_name = "#{name}[custom_field_values][#{custom_field.id}]"
field_id = "#{name}_custom_field_values_#{custom_field.id}"
case custom_field.field_format
when "date"
text_field_tag(field_name, custom_value.value, :id => field_id, :size => 10) +
calendar_for(field_id)
when "text"
text_area_tag(field_name, custom_value.value, :id => field_id, :rows => 3, :style => 'width:90%')
when "bool"
check_box_tag(field_name, '1', custom_value.true?, :id => field_id) + hidden_field_tag(field_name, '0')
when "list"
blank_option = custom_field.is_required? ?
(custom_field.default_value.blank? ? "<option value=\"\">--- #{l(:actionview_instancetag_blank_option)} ---</option>" : '') :
'<option></option>'
select_tag(field_name, blank_option + options_for_select(custom_field.possible_values, custom_value.value), :id => field_id)
else
text_field_tag(field_name, custom_value.value, :id => field_id)
end
end
# Return custom field label tag
def custom_field_label_tag(name, custom_value)
content_tag "label", custom_value.custom_field.name +
(custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>" : ""),
:for => "#{name}_custom_field_values_#{custom_value.custom_field.id}",
:class => (custom_value.errors.empty? ? nil : "error" )
end
# Return custom field tag with its label tag
def custom_field_tag_with_label(name, custom_value)
custom_field_label_tag(name, custom_value) + custom_field_tag(name, custom_value)
end
# Return a string used to display a custom value
def show_value(custom_value)
return "" unless custom_value
format_value(custom_value.value, custom_value.custom_field.field_format)
end
# Return a string used to display a custom value
def format_value(value, field_format)
return "" unless value && !value.empty?
case field_format
when "date"
begin; format_date(value.to_date); rescue; value end
when "bool"
l_YesNo(value == "1")
else
value
end
end
# Return an array of custom field formats which can be used in select_tag
def custom_field_formats_for_select
CustomField::FIELD_FORMATS.sort {|a,b| a[1][:order]<=>b[1][:order]}.collect { |k| [ l(k[1][:name]), k[0] ] }
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module DocumentsHelper
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module EnumerationsHelper
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module IssueCategoriesHelper
end

View File

@@ -1,24 +1,23 @@
# redMine - project management software
# Copyright (C) 2006 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.
class IssueHistory < ActiveRecord::Base
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
belongs_to :issue
validates_presence_of :status
# redMine - project management software
# Copyright (C) 2006-2007 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.
module IssueRelationsHelper
def collection_for_relation_type_select
values = IssueRelation::TYPES
values.keys.sort{|x,y| values[x][:order] <=> values[y][:order]}.collect{|k| [l(values[k][:name]), k]}
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module IssueStatusesHelper
end

View File

@@ -1,74 +1,196 @@
# redMine - project management software
# Copyright (C) 2006 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.
module IssuesHelper
def show_detail(detail, no_html=false)
case detail.property
when 'attr'
label = l(("field_" + detail.prop_key.to_s.gsub(/\_id$/, "")).to_sym)
case detail.prop_key
when 'due_date', 'start_date'
value = format_date(detail.value.to_date) if detail.value
old_value = format_date(detail.old_value.to_date) if detail.old_value
when 'status_id'
s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
when 'assigned_to_id'
u = User.find_by_id(detail.value) and value = u.name if detail.value
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
when 'priority_id'
e = Enumeration.find_by_id(detail.value) and value = e.name if detail.value
e = Enumeration.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
when 'category_id'
c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
when 'fixed_version_id'
v = Version.find_by_id(detail.value) and value = v.name if detail.value
v = Version.find_by_id(detail.old_value) and old_value = v.name if detail.old_value
end
when 'cf'
custom_field = CustomField.find_by_id(detail.prop_key)
if custom_field
label = custom_field.name
value = format_value(detail.value, custom_field.field_format) if detail.value
old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
end
end
label ||= detail.prop_key
value ||= detail.value
old_value ||= detail.old_value
unless no_html
label = content_tag('strong', label)
old_value = content_tag("i", h(old_value)) if detail.old_value
old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
value = content_tag("i", h(value)) if value
end
if detail.value and !detail.value.to_s.empty?
if old_value
label + " " + l(:text_journal_changed, old_value, value)
else
label + " " + l(:text_journal_set_to, value)
end
else
label + " " + l(:text_journal_deleted) + " (#{old_value})"
end
# redMine - project management software
# Copyright (C) 2006 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 'csv'
module IssuesHelper
include ApplicationHelper
def render_issue_tooltip(issue)
@cached_label_start_date ||= l(:field_start_date)
@cached_label_due_date ||= l(:field_due_date)
@cached_label_assigned_to ||= l(:field_assigned_to)
@cached_label_priority ||= l(:field_priority)
link_to_issue(issue) + ": #{h(issue.subject)}<br /><br />" +
"<strong>#{@cached_label_start_date}</strong>: #{format_date(issue.start_date)}<br />" +
"<strong>#{@cached_label_due_date}</strong>: #{format_date(issue.due_date)}<br />" +
"<strong>#{@cached_label_assigned_to}</strong>: #{issue.assigned_to}<br />" +
"<strong>#{@cached_label_priority}</strong>: #{issue.priority.name}"
end
# Returns a string of css classes that apply to the given issue
def css_issue_classes(issue)
s = "issue status-#{issue.status.position} priority-#{issue.priority.position}"
s << ' closed' if issue.closed?
s << ' overdue' if issue.overdue?
s
end
def sidebar_queries
unless @sidebar_queries
# User can see public queries and his own queries
visible = ARCondition.new(["is_public = ? OR user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
# Project specific queries and global queries
visible << (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id])
@sidebar_queries = Query.find(:all,
:order => "name ASC",
:conditions => visible.conditions)
end
@sidebar_queries
end
def show_detail(detail, no_html=false)
case detail.property
when 'attr'
label = l(("field_" + detail.prop_key.to_s.gsub(/\_id$/, "")).to_sym)
case detail.prop_key
when 'due_date', 'start_date'
value = format_date(detail.value.to_date) if detail.value
old_value = format_date(detail.old_value.to_date) if detail.old_value
when 'project_id'
p = Project.find_by_id(detail.value) and value = p.name if detail.value
p = Project.find_by_id(detail.old_value) and old_value = p.name if detail.old_value
when 'status_id'
s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
when 'tracker_id'
t = Tracker.find_by_id(detail.value) and value = t.name if detail.value
t = Tracker.find_by_id(detail.old_value) and old_value = t.name if detail.old_value
when 'assigned_to_id'
u = User.find_by_id(detail.value) and value = u.name if detail.value
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
when 'priority_id'
e = Enumeration.find_by_id(detail.value) and value = e.name if detail.value
e = Enumeration.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
when 'category_id'
c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
when 'fixed_version_id'
v = Version.find_by_id(detail.value) and value = v.name if detail.value
v = Version.find_by_id(detail.old_value) and old_value = v.name if detail.old_value
when 'estimated_hours'
value = "%0.02f" % detail.value.to_f unless detail.value.blank?
old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank?
end
when 'cf'
custom_field = CustomField.find_by_id(detail.prop_key)
if custom_field
label = custom_field.name
value = format_value(detail.value, custom_field.field_format) if detail.value
old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
end
when 'attachment'
label = l(:label_attachment)
end
call_hook(:helper_issues_show_detail_after_setting, {:detail => detail, :label => label, :value => value, :old_value => old_value })
label ||= detail.prop_key
value ||= detail.value
old_value ||= detail.old_value
unless no_html
label = content_tag('strong', label)
old_value = content_tag("i", h(old_value)) if detail.old_value
old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key)
# Link to the attachment if it has not been removed
value = link_to_attachment(a)
else
value = content_tag("i", h(value)) if value
end
end
if !detail.value.blank?
case detail.property
when 'attr', 'cf'
if !detail.old_value.blank?
label + " " + l(:text_journal_changed, old_value, value)
else
label + " " + l(:text_journal_set_to, value)
end
when 'attachment'
"#{label} #{value} #{l(:label_added)}"
end
else
case detail.property
when 'attr', 'cf'
label + " " + l(:text_journal_deleted) + " (#{old_value})"
when 'attachment'
"#{label} #{old_value} #{l(:label_deleted)}"
end
end
end
def issues_to_csv(issues, project = nil)
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
decimal_separator = l(:general_csv_decimal_separator)
export = StringIO.new
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
# csv header fields
headers = [ "#",
l(:field_status),
l(:field_project),
l(:field_tracker),
l(:field_priority),
l(:field_subject),
l(:field_assigned_to),
l(:field_category),
l(:field_fixed_version),
l(:field_author),
l(:field_start_date),
l(:field_due_date),
l(:field_done_ratio),
l(:field_estimated_hours),
l(:field_created_on),
l(:field_updated_on)
]
# Export project custom fields if project is given
# otherwise export custom fields marked as "For all projects"
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_issue_custom_fields
custom_fields.each {|f| headers << f.name}
# Description in the last column
headers << l(:field_description)
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
# csv lines
issues.each do |issue|
fields = [issue.id,
issue.status.name,
issue.project.name,
issue.tracker.name,
issue.priority.name,
issue.subject,
issue.assigned_to,
issue.category,
issue.fixed_version,
issue.author.name,
format_date(issue.start_date),
format_date(issue.due_date),
issue.done_ratio,
issue.estimated_hours.to_s.gsub('.', decimal_separator),
format_time(issue.created_on),
format_time(issue.updated_on)
]
custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) }
fields << issue.description
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
end
end
export.rewind
export
end
end

View File

@@ -0,0 +1,40 @@
# redMine - project management software
# Copyright (C) 2006-2008 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.
module JournalsHelper
def render_notes(journal, options={})
content = ''
editable = journal.editable_by?(User.current)
links = []
if !journal.notes.blank?
links << link_to_remote(image_tag('comment.png'),
{ :url => {:controller => 'issues', :action => 'reply', :id => journal.journalized, :journal_id => journal} },
:title => l(:button_quote)) if options[:reply_links]
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
{ :controller => 'journals', :action => 'edit', :id => journal },
:title => l(:button_edit)) if editable
end
content << content_tag('div', links.join(' '), :class => 'contextual') unless links.empty?
content << textilizable(journal, :notes)
content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => (editable ? 'wiki editable' : 'wiki'))
end
def link_to_in_place_notes_editor(text, field_id, url, options={})
onclick = "new Ajax.Request('#{url_for(url)}', {asynchronous:true, evalScripts:true, method:'get'}); return false;"
link_to text, '#', options.merge(:onclick => onclick)
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
module HelpHelper
# redMine - project management software
# Copyright (C) 2006-2008 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.
module MailHandlerHelper
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module MembersHelper
end

View File

@@ -0,0 +1,28 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
module MessagesHelper
def link_to_message(message)
return '' unless message
link_to h(truncate(message.subject, 60)), :controller => 'messages',
:action => 'show',
:board_id => message.board_id,
:id => message.root,
:anchor => (message.parent_id ? "message-#{message.id}" : nil)
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module NewsHelper
end

View File

@@ -1,19 +1,36 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module ProjectsHelper
def link_to_version(version, options = {})
return '' unless version && version.is_a?(Version)
link_to h(version.name), { :controller => 'versions', :action => 'show', :id => version }, options
end
def project_settings_tabs
tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
{:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
{:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
{:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
{:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
{:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
{:name => 'repository', :action => :manage_repository, :partial => 'projects/settings/repository', :label => :label_repository},
{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}
]
tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
end
end

View File

@@ -1,6 +1,55 @@
module QueriesHelper
# redMine - project management software
# Copyright (C) 2006-2007 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.
module QueriesHelper
def operators_for_select(filter_type)
Query.operators_by_filter_type[filter_type].collect {|o| [l(Query.operators[o]), o]}
end
def column_header(column)
column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
:default_order => column.default_order) :
content_tag('th', column.caption)
end
def column_content(column, issue)
if column.is_a?(QueryCustomFieldColumn)
cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
show_value(cv)
else
value = issue.send(column.name)
if value.is_a?(Date)
format_date(value)
elsif value.is_a?(Time)
format_time(value)
else
case column.name
when :subject
h((@project.nil? || @project != issue.project) ? "#{issue.project.name} - " : '') +
link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
when :done_ratio
progress_bar(value, :width => '80px')
when :fixed_version
link_to(h(value), { :controller => 'versions', :action => 'show', :id => issue.fixed_version_id })
else
h(value)
end
end
end
end
end

View File

@@ -1,32 +1,36 @@
# redMine - project management software
# Copyright (C) 2006 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.
module ReportsHelper
def aggregate(data, criteria)
a = 0
data.each { |row|
match = 1
criteria.each { |k, v|
match = 0 unless row[k].to_s == v.to_s
} unless criteria.nil?
a = a + row["total"].to_i if match == 1
} unless data.nil?
a
end
# redMine - project management software
# Copyright (C) 2006 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.
module ReportsHelper
def aggregate(data, criteria)
a = 0
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"))
} unless criteria.nil?
a = a + row["total"].to_i if match == 1
} unless data.nil?
a
end
def aggregate_link(data, criteria, *args)
a = aggregate data, criteria
a > 0 ? link_to(a, *args) : '-'
end
end

View File

@@ -15,5 +15,168 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'iconv'
module RepositoriesHelper
def format_revision(txt)
txt.to_s[0,8]
end
def truncate_at_line_break(text, length = 255)
if text
text.gsub(%r{^(.{#{length}}[^\n]*)\n.+$}m, '\\1...')
end
end
def render_properties(properties)
unless properties.nil? || properties.empty?
content = ''
properties.keys.sort.each do |property|
content << content_tag('li', "<b>#{h property}</b>: <span>#{h properties[property]}</span>")
end
content_tag('ul', content, :class => 'properties')
end
end
def render_changeset_changes
changes = @changeset.changes.find(:all, :limit => 1000, :order => 'path').collect do |change|
case change.action
when 'A'
# Detects moved/copied files
if !change.from_path.blank?
change.action = @changeset.changes.detect {|c| c.action == 'D' && c.path == change.from_path} ? 'R' : 'C'
end
change
when 'D'
@changeset.changes.detect {|c| c.from_path == change.path} ? nil : change
else
change
end
end.compact
tree = { }
changes.each do |change|
p = tree
dirs = change.path.to_s.split('/').select {|d| !d.blank?}
dirs.each do |dir|
p[:s] ||= {}
p = p[:s]
p[dir] ||= {}
p = p[dir]
end
p[:c] = change
end
render_changes_tree(tree[:s])
end
def render_changes_tree(tree)
return '' if tree.nil?
output = ''
output << '<ul>'
tree.keys.sort.each do |file|
s = !tree[file][:s].nil?
c = tree[file][:c]
style = 'change'
style << ' folder' if s
style << " change-#{c.action}" if c
text = h(file)
unless c.nil?
path_param = to_path_param(@repository.relative_path(c.path))
text = link_to(text, :controller => 'repositories',
:action => 'entry',
:id => @project,
:path => path_param,
:rev => @changeset.revision) unless s || c.action == 'D'
text << " - #{c.revision}" unless c.revision.blank?
text << ' (' + link_to('diff', :controller => 'repositories',
:action => 'diff',
:id => @project,
:path => path_param,
:rev => @changeset.revision) + ') ' if c.action == 'M'
text << ' ' + content_tag('span', c.from_path, :class => 'copied-from') unless c.from_path.blank?
end
output << "<li class='#{style}'>#{text}</li>"
output << render_changes_tree(tree[file][:s]) if s
end
output << '</ul>'
output
end
def to_utf8(str)
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
@encodings ||= Setting.repositories_encodings.split(',').collect(&:strip)
@encodings.each do |encoding|
begin
return Iconv.conv('UTF-8', encoding, str)
rescue Iconv::Failure
# do nothing here and try the next encoding
end
end
str
end
def repository_field_tags(form, repository)
method = repository.class.name.demodulize.underscore + "_field_tags"
send(method, form, repository) if repository.is_a?(Repository) && respond_to?(method)
end
def scm_select_tag(repository)
scm_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']]
REDMINE_SUPPORTED_SCM.each do |scm|
scm_options << ["Repository::#{scm}".constantize.scm_name, scm] if Setting.enabled_scm.include?(scm) || (repository && repository.class.name.demodulize == scm)
end
select_tag('repository_scm',
options_for_select(scm_options, repository.class.name.demodulize),
:disabled => (repository && !repository.new_record?),
:onchange => remote_function(:url => { :controller => 'repositories', :action => 'edit', :id => @project }, :method => :get, :with => "Form.serialize(this.form)")
)
end
def with_leading_slash(path)
path.to_s.starts_with?('/') ? path : "/#{path}"
end
def without_leading_slash(path)
path.gsub(%r{^/+}, '')
end
def subversion_field_tags(form, repository)
content_tag('p', form.text_field(:url, :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)) +
'<br />(http://, https://, svn://, file:///)') +
content_tag('p', form.text_field(:login, :size => 30)) +
content_tag('p', form.password_field(:password, :size => 30, :name => 'ignore',
:value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
:onfocus => "this.value=''; this.name='repository[password]';",
:onchange => "this.name='repository[password]';"))
end
def darcs_field_tags(form, repository)
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
end
def mercurial_field_tags(form, repository)
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
end
def git_field_tags(form, repository)
content_tag('p', form.text_field(:url, :label => 'Path to .git directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
end
def cvs_field_tags(form, repository)
content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
end
def bazaar_field_tags(form, repository)
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
end
def filesystem_field_tags(form, repository)
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module RolesHelper
end

View File

@@ -0,0 +1,63 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
module SearchHelper
def highlight_tokens(text, tokens)
return text unless text && tokens && !tokens.empty?
re_tokens = tokens.collect {|t| Regexp.escape(t)}
regexp = Regexp.new "(#{re_tokens.join('|')})", Regexp::IGNORECASE
result = ''
text.split(regexp).each_with_index do |words, i|
if result.length > 1200
# maximum length of the preview reached
result << '...'
break
end
if i.even?
result << h(words.length > 100 ? "#{words[0..44]} ... #{words[-45..-1]}" : words)
else
t = (tokens.index(words.downcase) || 0) % 4
result << content_tag('span', h(words), :class => "highlight token-#{t}")
end
end
result
end
def type_label(t)
l("label_#{t.singularize}_plural")
end
def project_select_tag
options = [[l(:label_project_all), 'all']]
options << [l(:label_my_projects), 'my_projects'] unless User.current.memberships.empty?
options << [l(:label_and_its_subprojects, @project.name), 'subprojects'] unless @project.nil? || @project.active_children.empty?
options << [@project.name, ''] unless @project.nil?
select_tag('scope', options_for_select(options, params[:scope].to_s)) if options.size > 1
end
def render_results_by_type(results_by_type)
links = []
# Sorts types by results count
results_by_type.keys.sort {|a, b| results_by_type[b] <=> results_by_type[a]}.each do |t|
c = results_by_type[t]
next if c == 0
text = "#{type_label(t)} (#{c})"
links << link_to(text, :q => params[:q], :titles_only => params[:title_only], :all_words => params[:all_words], :scope => params[:scope], t => 1)
end
('<ul>' + links.map {|link| content_tag('li', link)}.join(' ') + '</ul>') unless links.empty?
end
end

View File

@@ -16,4 +16,14 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module SettingsHelper
def administration_settings_tabs
tabs = [{:name => 'general', :partial => 'settings/general', :label => :label_general},
{:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
{:name => 'projects', :partial => 'settings/projects', :label => :label_project_plural},
{:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
{:name => 'notifications', :partial => 'settings/notifications', :label => l(:field_mail_notification)},
{:name => 'mail_handler', :partial => 'settings/mail_handler', :label => l(:label_incoming_emails)},
{:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
]
end
end

View File

@@ -67,23 +67,31 @@ module SortHelper
# Updates the sort state. Call this in the controller prior to calling
# sort_clause.
#
def sort_update()
if params[:sort_key]
sort = {:key => params[:sort_key], :order => params[:sort_order]}
# sort_keys can be either an array or a hash of allowed keys
def sort_update(sort_keys)
sort_key = params[:sort_key]
sort_key = nil unless (sort_keys.is_a?(Array) ? sort_keys.include?(sort_key) : sort_keys[sort_key])
sort_order = (params[:sort_order] == 'desc' ? 'DESC' : 'ASC')
if sort_key
sort = {:key => sort_key, :order => sort_order}
elsif session[@sort_name]
sort = session[@sort_name] # Previous sort.
else
sort = @sort_default
end
session[@sort_name] = sort
sort_column = (sort_keys.is_a?(Hash) ? sort_keys[sort[:key]] : sort[:key])
@sort_clause = (sort_column.blank? ? nil : "#{sort_column} #{sort[:order]}")
end
# Returns an SQL sort clause corresponding to the current sort state.
# Use this to sort the controller's table items collection.
#
def sort_clause()
session[@sort_name][:key] + ' ' + session[@sort_name][:order]
@sort_clause
end
# Returns a link which sorts by the named column.
@@ -92,7 +100,7 @@ module SortHelper
# - The optional caption explicitly specifies the displayed link text.
# - A sort icon image is positioned to the right of the sort link.
#
def sort_link(column, caption=nil)
def sort_link(column, caption, default_order)
key, order = session[@sort_name][:key], session[@sort_name][:order]
if key == column
if order.downcase == 'asc'
@@ -104,13 +112,17 @@ module SortHelper
end
else
icon = nil
order = 'desc' # changed for desc order by default
order = default_order
end
caption = titleize(Inflector::humanize(column)) unless caption
params = {:params => {:sort_key => column, :sort_order => order}}
sort_options = { :sort_key => column, :sort_order => order }
# don't reuse params if filters are present
url_options = params.has_key?(:set_filter) ? sort_options : params.merge(sort_options)
link_to_remote(caption,
{:update => "content", :url => { :sort_key => column, :sort_order => order}},
{:href => url_for(:params => { :sort_key => column, :sort_order => order})}) +
{:update => "content", :url => url_options},
{:href => url_for(url_options)}) +
(icon ? nbsp(2) + image_tag(icon) : '')
end
@@ -135,14 +147,10 @@ module SortHelper
# </th>
#
def sort_header_tag(column, options = {})
if options[:caption]
caption = options[:caption]
options.delete(:caption)
else
caption = titleize(Inflector::humanize(column))
end
options[:title]= "Sort by #{caption}" unless options[:title]
content_tag('th', sort_link(column, caption), options)
caption = options.delete(:caption) || titleize(Inflector::humanize(column))
default_order = options.delete(:default_order) || 'asc'
options[:title]= l(:label_sort_by, "\"#{caption}\"") unless options[:title]
content_tag('th', sort_link(column, caption, default_order), options)
end
private

View File

@@ -0,0 +1,160 @@
# redMine - project management software
# Copyright (C) 2006 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.
module TimelogHelper
include ApplicationHelper
def render_timelog_breadcrumb
links = []
links << link_to(l(:label_project_all), {:project_id => nil, :issue_id => nil})
links << link_to(h(@project), {:project_id => @project, :issue_id => nil}) if @project
links << link_to_issue(@issue) if @issue
breadcrumb links
end
def activity_collection_for_select_options
activities = Enumeration::get_values('ACTI')
collection = []
collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
activities.each { |a| collection << [a.name, a.id] }
collection
end
def select_hours(data, criteria, value)
data.select {|row| row[criteria] == value}
end
def sum_hours(data)
sum = 0
data.each do |row|
sum += row['hours'].to_f
end
sum
end
def options_for_period_select(value)
options_for_select([[l(:label_all_time), 'all'],
[l(:label_today), 'today'],
[l(:label_yesterday), 'yesterday'],
[l(:label_this_week), 'current_week'],
[l(:label_last_week), 'last_week'],
[l(:label_last_n_days, 7), '7_days'],
[l(:label_this_month), 'current_month'],
[l(:label_last_month), 'last_month'],
[l(:label_last_n_days, 30), '30_days'],
[l(:label_this_year), 'current_year']],
value)
end
def entries_to_csv(entries)
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
decimal_separator = l(:general_csv_decimal_separator)
custom_fields = TimeEntryCustomField.find(:all)
export = StringIO.new
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
# csv header fields
headers = [l(:field_spent_on),
l(:field_user),
l(:field_activity),
l(:field_project),
l(:field_issue),
l(:field_tracker),
l(:field_subject),
l(:field_hours),
l(:field_comments)
]
# Export custom fields
headers += custom_fields.collect(&:name)
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
# csv lines
entries.each do |entry|
fields = [format_date(entry.spent_on),
entry.user,
entry.activity,
entry.project,
(entry.issue ? entry.issue.id : nil),
(entry.issue ? entry.issue.tracker : nil),
(entry.issue ? entry.issue.subject : nil),
entry.hours.to_s.gsub('.', decimal_separator),
entry.comments
]
fields += custom_fields.collect {|f| show_value(entry.custom_value_for(f)) }
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
end
end
export.rewind
export
end
def format_criteria_value(criteria, value)
value.blank? ? l(:label_none) : ((k = @available_criterias[criteria][:klass]) ? k.find_by_id(value.to_i) : format_value(value, @available_criterias[criteria][:format]))
end
def report_to_csv(criterias, periods, hours)
export = StringIO.new
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
# Column headers
headers = criterias.collect {|criteria| l(@available_criterias[criteria][:label]) }
headers += periods
headers << l(:label_total)
csv << headers.collect {|c| to_utf8(c) }
# Content
report_criteria_to_csv(csv, criterias, periods, hours)
# Total row
row = [ l(:label_total) ] + [''] * (criterias.size - 1)
total = 0
periods.each do |period|
sum = sum_hours(select_hours(hours, @columns, period.to_s))
total += sum
row << (sum > 0 ? "%.2f" % sum : '')
end
row << "%.2f" %total
csv << row
end
export.rewind
export
end
def report_criteria_to_csv(csv, criterias, periods, hours, level=0)
hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value|
hours_for_value = select_hours(hours, criterias[level], value)
next if hours_for_value.empty?
row = [''] * level
row << to_utf8(format_criteria_value(criterias[level], value))
row += [''] * (criterias.length - level - 1)
total = 0
periods.each do |period|
sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s))
total += sum
row << (sum > 0 ? "%.2f" % sum : '')
end
row << "%.2f" %total
csv << row
if criterias.length > level + 1
report_criteria_to_csv(csv, criterias, periods, hours_for_value, level + 1)
end
end
end
def to_utf8(s)
@ic ||= Iconv.new(l(:general_csv_encoding), 'UTF-8')
begin; @ic.iconv(s.to_s); rescue; s.to_s; end
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module TrackersHelper
end

View File

@@ -1,19 +1,58 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module UsersHelper
def users_status_options_for_select(selected)
user_count_by_status = User.count(:group => 'status').to_hash
options_for_select([[l(:label_all), ''],
["#{l(:status_active)} (#{user_count_by_status[1].to_i})", 1],
["#{l(:status_registered)} (#{user_count_by_status[2].to_i})", 2],
["#{l(:status_locked)} (#{user_count_by_status[3].to_i})", 3]], selected)
end
# Options for the new membership projects combo-box
def projects_options_for_select(projects)
options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
projects_by_root = projects.group_by(&:root)
projects_by_root.keys.sort.each do |root|
options << content_tag('option', h(root.name), :value => root.id, :disabled => (!projects.include?(root)))
projects_by_root[root].sort.each do |project|
next if project == root
options << content_tag('option', '&#187; ' + h(project.name), :value => project.id)
end
end
options
end
def change_status_link(user)
url = {:action => 'edit', :id => user, :page => params[:page], :status => params[:status]}
if user.locked?
link_to l(:button_unlock), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :post, :class => 'icon icon-unlock'
elsif user.registered?
link_to l(:button_activate), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :post, :class => 'icon icon-unlock'
elsif user != User.current
link_to l(:button_lock), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :post, :class => 'icon icon-lock'
end
end
def user_settings_tabs
tabs = [{:name => 'general', :partial => 'users/general', :label => :label_general},
{:name => 'memberships', :partial => 'users/memberships', :label => :label_project_plural}
]
end
end

View File

@@ -1,19 +1,47 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module VersionsHelper
STATUS_BY_CRITERIAS = %w(category tracker priority author assigned_to)
def render_issue_status_by(version, criteria)
criteria ||= 'category'
raise 'Unknown criteria' unless STATUS_BY_CRITERIAS.include?(criteria)
h = Hash.new {|k,v| k[v] = [0, 0]}
begin
# Total issue count
Issue.count(:group => criteria,
:conditions => ["#{Issue.table_name}.fixed_version_id = ?", version.id]).each {|c,s| h[c][0] = s}
# Open issues count
Issue.count(:group => criteria,
:include => :status,
:conditions => ["#{Issue.table_name}.fixed_version_id = ? AND #{IssueStatus.table_name}.is_closed = ?", version.id, false]).each {|c,s| h[c][1] = s}
rescue ActiveRecord::RecordNotFound
# When grouping by an association, Rails throws this exception if there's no result (bug)
end
counts = h.keys.compact.sort.collect {|k| {:group => k, :total => h[k][0], :open => h[k][1], :closed => (h[k][0] - h[k][1])}}
max = counts.collect {|c| c[:total]}.max
render :partial => 'issue_counts', :locals => {:version => version, :criteria => criteria, :counts => counts, :max => max}
end
def status_by_options_for_select(value)
options_for_select(STATUS_BY_CRITERIAS.collect {|criteria| [l("field_#{criteria}".to_sym), criteria]}, value)
end
end

View File

@@ -0,0 +1,41 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
module WatchersHelper
def watcher_tag(object, user)
content_tag("span", watcher_link(object, user), :id => 'watcher')
end
def watcher_link(object, user)
return '' unless user && user.logged? && object.respond_to?('watched_by?')
watched = object.watched_by?(user)
url = {:controller => 'watchers',
:action => (watched ? 'unwatch' : 'watch'),
:object_type => object.class.to_s.underscore,
:object_id => object.id}
link_to_remote((watched ? l(:button_unwatch) : l(:button_watch)),
{:url => url},
:href => url_for(url),
:class => (watched ? 'icon icon-fav' : 'icon icon-fav-off'))
end
# Returns a comma separated list of users watching the given object
def watchers_list(object)
object.watcher_users.collect {|u| content_tag('span', link_to_user(u), :class => 'user') }.join(",\n")
end
end

View File

@@ -1,19 +1,19 @@
# redMine - project management software
# Copyright (C) 2006 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.
# redMine - project management software
# Copyright (C) 2006 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.
module WelcomeHelper
end

View File

@@ -0,0 +1,56 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
module WikiHelper
def html_diff(wdiff)
words = wdiff.words.collect{|word| h(word)}
words_add = 0
words_del = 0
dels = 0
del_off = 0
wdiff.diff.diffs.each do |diff|
add_at = nil
add_to = nil
del_at = nil
deleted = ""
diff.each do |change|
pos = change[1]
if change[0] == "+"
add_at = pos + dels unless add_at
add_to = pos + dels
words_add += 1
else
del_at = pos unless del_at
deleted << ' ' + change[2]
words_del += 1
end
end
if add_at
words[add_at] = '<span class="diff_in">' + words[add_at]
words[add_to] = words[add_to] + '</span>'
end
if del_at
words.insert del_at - del_off + dels + words_add, '<span class="diff_out">' + deleted + '</span>'
dels += 1
del_off += words_del
words_del = 0
end
end
simple_format_without_paragraph(words.join(' '))
end
end

View File

@@ -0,0 +1,19 @@
# Redmine - project management software
# Copyright (C) 2006-2008 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.
module WorkflowsHelper
end

View File

@@ -1,92 +1,151 @@
# redMine - project management software
# Copyright (C) 2006-2007 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 "digest/md5"
class Attachment < ActiveRecord::Base
belongs_to :container, :polymorphic => true
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
validates_presence_of :container, :filename
cattr_accessor :storage_path
@@storage_path = "#{RAILS_ROOT}/files"
def validate
errors.add_to_base :too_long if self.filesize > Setting.attachment_max_size.to_i.kilobytes
end
def file=(incomming_file)
unless incomming_file.nil?
@temp_file = incomming_file
if @temp_file.size > 0
self.filename = sanitize_filename(@temp_file.original_filename)
self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
self.content_type = @temp_file.content_type
self.filesize = @temp_file.size
end
end
end
def file
nil
end
# Copy temp file to its final location
def before_save
if @temp_file && (@temp_file.size > 0)
logger.debug("saving '#{self.diskfile}'")
File.open(diskfile, "wb") do |f|
f.write(@temp_file.read)
end
self.digest = Digest::MD5.hexdigest(File.read(diskfile))
end
end
# Deletes file on the disk
def after_destroy
if self.filename?
File.delete(diskfile) if File.exist?(diskfile)
end
end
# Returns file's location on disk
def diskfile
"#{@@storage_path}/#{self.disk_filename}"
end
def increment_download
increment!(:downloads)
end
# returns last created projects
def self.most_downloaded
find(:all, :limit => 5, :order => "downloads DESC")
end
private
def sanitize_filename(value)
# get only the filename, not the whole path
just_filename = value.gsub(/^.*(\\|\/)/, '')
# NOTE: File.basename doesn't work right with Windows paths on Unix
# INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
# Finally, replace all non alphanumeric, underscore or periods with underscore
@filename = just_filename.gsub(/[^\w\.\-]/,'_')
end
# redMine - project management software
# Copyright (C) 2006-2007 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 "digest/md5"
class Attachment < ActiveRecord::Base
belongs_to :container, :polymorphic => true
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
validates_presence_of :container, :filename, :author
validates_length_of :filename, :maximum => 255
validates_length_of :disk_filename, :maximum => 255
acts_as_event :title => :filename,
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}}
acts_as_activity_provider :type => 'files',
:permission => :view_files,
:author_key => :author_id,
:find_options => {:select => "#{Attachment.table_name}.*",
:joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
"LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id"}
acts_as_activity_provider :type => 'documents',
:permission => :view_documents,
:author_key => :author_id,
:find_options => {:select => "#{Attachment.table_name}.*",
:joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
"LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"}
cattr_accessor :storage_path
@@storage_path = "#{RAILS_ROOT}/files"
def validate
errors.add_to_base :too_long if self.filesize > Setting.attachment_max_size.to_i.kilobytes
end
def file=(incoming_file)
unless incoming_file.nil?
@temp_file = incoming_file
if @temp_file.size > 0
self.filename = sanitize_filename(@temp_file.original_filename)
self.disk_filename = Attachment.disk_filename(filename)
self.content_type = @temp_file.content_type.to_s.chomp
self.filesize = @temp_file.size
end
end
end
def file
nil
end
# Copy temp file to its final location
def before_save
if @temp_file && (@temp_file.size > 0)
logger.debug("saving '#{self.diskfile}'")
File.open(diskfile, "wb") do |f|
f.write(@temp_file.read)
end
self.digest = self.class.digest(diskfile)
end
# Don't save the content type if it's longer than the authorized length
if self.content_type && self.content_type.length > 255
self.content_type = nil
end
end
# Deletes file on the disk
def after_destroy
File.delete(diskfile) if !filename.blank? && File.exist?(diskfile)
end
# Returns file's location on disk
def diskfile
"#{@@storage_path}/#{self.disk_filename}"
end
def increment_download
increment!(:downloads)
end
def project
container.project
end
def visible?(user=User.current)
container.attachments_visible?(user)
end
def deletable?(user=User.current)
container.attachments_deletable?(user)
end
def image?
self.filename =~ /\.(jpe?g|gif|png)$/i
end
def is_text?
Redmine::MimeType.is_type?('text', filename)
end
def is_diff?
self.filename =~ /\.(patch|diff)$/i
end
private
def sanitize_filename(value)
# get only the filename, not the whole path
just_filename = value.gsub(/^.*(\\|\/)/, '')
# NOTE: File.basename doesn't work right with Windows paths on Unix
# INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
# Finally, replace all non alphanumeric, hyphens or periods with underscore
@filename = just_filename.gsub(/[^\w\.\-]/,'_')
end
# Returns an ASCII or hashed filename
def self.disk_filename(filename)
df = DateTime.now.strftime("%y%m%d%H%M%S") + "_"
if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
df << filename
else
df << Digest::MD5.hexdigest(filename)
# keep the extension if any
df << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
end
df
end
# Returns the MD5 digest of the file at given path
def self.digest(filename)
File.open(filename, 'rb') do |f|
Digest::MD5.hexdigest(f.read)
end
end
end

View File

@@ -20,6 +20,7 @@ class AuthSource < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 60
def authenticate(login, password)
end
@@ -37,7 +38,8 @@ class AuthSource < ActiveRecord::Base
begin
logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
attrs = source.authenticate(login, password)
rescue
rescue => e
logger.error "Error during authentication: #{e.message}"
attrs = nil
end
return attrs if attrs

View File

@@ -1,79 +1,98 @@
# redMine - project management software
# Copyright (C) 2006 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 'net/ldap'
require 'iconv'
class AuthSourceLdap < AuthSource
validates_presence_of :host, :port, :attr_login
def after_initialize
self.port = 389 if self.port == 0
end
def authenticate(login, password)
attrs = []
# get user's DN
ldap_con = initialize_ldap_con(self.account, self.account_password)
login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
dn = String.new
ldap_con.search( :base => self.base_dn,
:filter => object_filter & login_filter,
:attributes=> ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]) do |entry|
dn = entry.dn
attrs = [:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
:lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
:mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
:auth_source_id => self.id ]
end
return nil if dn.empty?
logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
# authenticate user
ldap_con = initialize_ldap_con(dn, password)
return nil unless ldap_con.bind
# return user's attributes
logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
attrs
rescue Net::LDAP::LdapError => text
raise "LdapError: " + text
end
# test the connection to the LDAP
def test_connection
ldap_con = initialize_ldap_con(self.account, self.account_password)
ldap_con.open { }
rescue Net::LDAP::LdapError => text
raise "LdapError: " + text
end
def auth_method_name
"LDAP"
end
private
def initialize_ldap_con(ldap_user, ldap_password)
Net::LDAP.new( {:host => self.host,
:port => self.port,
:auth => { :method => :simple, :username => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_user), :password => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_password) }}
)
end
def self.get_attr(entry, attr_name)
entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
# redMine - project management software
# Copyright (C) 2006 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 'net/ldap'
require 'iconv'
class AuthSourceLdap < AuthSource
validates_presence_of :host, :port, :attr_login
validates_length_of :name, :host, :account_password, :maximum => 60, :allow_nil => true
validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
validates_numericality_of :port, :only_integer => true
before_validation :strip_ldap_attributes
def after_initialize
self.port = 389 if self.port == 0
end
def authenticate(login, password)
return nil if login.blank? || password.blank?
attrs = []
# get user's DN
ldap_con = initialize_ldap_con(self.account, self.account_password)
login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
dn = String.new
ldap_con.search( :base => self.base_dn,
:filter => object_filter & login_filter,
# only ask for the DN if on-the-fly registration is disabled
:attributes=> (onthefly_register? ? ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail] : ['dn'])) do |entry|
dn = entry.dn
attrs = [:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
:lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
:mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
:auth_source_id => self.id ] if onthefly_register?
end
return nil if dn.empty?
logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
# authenticate user
ldap_con = initialize_ldap_con(dn, password)
return nil unless ldap_con.bind
# return user's attributes
logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
attrs
rescue Net::LDAP::LdapError => text
raise "LdapError: " + text
end
# test the connection to the LDAP
def test_connection
ldap_con = initialize_ldap_con(self.account, self.account_password)
ldap_con.open { }
rescue Net::LDAP::LdapError => text
raise "LdapError: " + text
end
def auth_method_name
"LDAP"
end
private
def strip_ldap_attributes
[:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
end
end
def initialize_ldap_con(ldap_user, ldap_password)
options = { :host => self.host,
:port => self.port,
:encryption => (self.tls ? :simple_tls : nil)
}
options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
Net::LDAP.new options
end
def self.get_attr(entry, attr_name)
if !attr_name.blank?
entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
end
end
end

29
app/models/board.rb Normal file
View File

@@ -0,0 +1,29 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class Board < ActiveRecord::Base
belongs_to :project
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
has_many :messages, :dependent => :delete_all, :order => "#{Message.table_name}.created_on DESC"
belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id
acts_as_list :scope => :project_id
acts_as_watchable
validates_presence_of :name, :description
validates_length_of :name, :maximum => 30
validates_length_of :description, :maximum => 255
end

View File

@@ -1,5 +1,5 @@
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
# Copyright (C) 2006-2007 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
@@ -15,11 +15,12 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class FeedsController < ApplicationController
session :off
class Change < ActiveRecord::Base
belongs_to :changeset
def news
@news = News.find :all, :order => 'news.created_on DESC', :limit => 10, :include => [ :author, :project ]
headers["Content-Type"] = "application/rss+xml"
validates_presence_of :changeset_id, :action, :path
def relative_path
changeset.repository.relative_path(path)
end
end

155
app/models/changeset.rb Normal file
View File

@@ -0,0 +1,155 @@
# Redmine - project management software
# Copyright (C) 2006-2008 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 'iconv'
class Changeset < ActiveRecord::Base
belongs_to :repository
belongs_to :user
has_many :changes, :dependent => :delete_all
has_and_belongs_to_many :issues
acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.revision}" + (o.comments.blank? ? '' : (': ' + o.comments))},
:description => :comments,
:datetime => :committed_on,
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project_id, :rev => o.revision}}
acts_as_searchable :columns => 'comments',
:include => {:repository => :project},
:project_key => "#{Repository.table_name}.project_id",
:date_column => 'committed_on'
acts_as_activity_provider :timestamp => "#{table_name}.committed_on",
:author_key => :user_id,
:find_options => {:include => {:repository => :project}}
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
validates_uniqueness_of :revision, :scope => :repository_id
validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
def revision=(r)
write_attribute :revision, (r.nil? ? nil : r.to_s)
end
def comments=(comment)
write_attribute(:comments, Changeset.normalize_comments(comment))
end
def committed_on=(date)
self.commit_date = date
super
end
def project
repository.project
end
def author
user || committer.to_s.split('<').first
end
def before_create
self.user = repository.find_committer_user(committer)
end
def after_create
scan_comment_for_issue_ids
end
require 'pp'
def scan_comment_for_issue_ids
return if comments.blank?
# keywords used to reference issues
ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip)
# keywords used to fix issues
fix_keywords = Setting.commit_fix_keywords.downcase.split(",").collect(&:strip)
# status and optional done ratio applied
fix_status = IssueStatus.find_by_id(Setting.commit_fix_status_id)
done_ratio = Setting.commit_fix_done_ratio.blank? ? nil : Setting.commit_fix_done_ratio.to_i
kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|")
return if kw_regexp.blank?
referenced_issues = []
if ref_keywords.delete('*')
# find any issue ID in the comments
target_issue_ids = []
comments.scan(%r{([\s\(,-]|^)#(\d+)(?=[[:punct:]]|\s|<|$)}).each { |m| target_issue_ids << m[1] }
referenced_issues += repository.project.issues.find_all_by_id(target_issue_ids)
end
comments.scan(Regexp.new("(#{kw_regexp})[\s:]+(([\s,;&]*#?\\d+)+)", Regexp::IGNORECASE)).each do |match|
action = match[0]
target_issue_ids = match[1].scan(/\d+/)
target_issues = repository.project.issues.find_all_by_id(target_issue_ids)
if fix_status && fix_keywords.include?(action.downcase)
# update status of issues
logger.debug "Issues fixed by changeset #{self.revision}: #{issue_ids.join(', ')}." if logger && logger.debug?
target_issues.each do |issue|
# the issue may have been updated by the closure of another one (eg. duplicate)
issue.reload
# don't change the status is the issue is closed
next if issue.status.is_closed?
csettext = "r#{self.revision}"
if self.scmid && (! (csettext =~ /^r[0-9]+$/))
csettext = "commit:\"#{self.scmid}\""
end
journal = issue.init_journal(user || User.anonymous, l(:text_status_changed_by_changeset, csettext))
issue.status = fix_status
issue.done_ratio = done_ratio if done_ratio
issue.save
Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
end
end
referenced_issues += target_issues
end
self.issues = referenced_issues.uniq
end
# Returns the previous changeset
def previous
@previous ||= Changeset.find(:first, :conditions => ['id < ? AND repository_id = ?', self.id, self.repository_id], :order => 'id DESC')
end
# Returns the next changeset
def next
@next ||= Changeset.find(:first, :conditions => ['id > ? AND repository_id = ?', self.id, self.repository_id], :order => 'id ASC')
end
# Strips and reencodes a commit log before insertion into the database
def self.normalize_comments(str)
to_utf8(str.to_s.strip)
end
private
def self.to_utf8(str)
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
encoding = Setting.commit_logs_encoding.to_s.strip
unless encoding.blank? || encoding == 'UTF-8'
begin
return Iconv.conv('UTF-8', encoding, str)
rescue Iconv::Failure
# do nothing here
end
end
str
end
end

View File

@@ -19,5 +19,5 @@ class Comment < ActiveRecord::Base
belongs_to :commented, :polymorphic => true, :counter_cache => true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :commented, :author, :comment
validates_presence_of :commented, :author, :comments
end

View File

@@ -1,60 +1,75 @@
# redMine - project management software
# Copyright (C) 2006 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.
class CustomField < ActiveRecord::Base
has_many :custom_values, :dependent => :delete_all
serialize :possible_values
FIELD_FORMATS = { "string" => { :name => :label_string, :order => 1 },
"text" => { :name => :label_text, :order => 2 },
"int" => { :name => :label_integer, :order => 3 },
"list" => { :name => :label_list, :order => 4 },
"date" => { :name => :label_date, :order => 5 },
"bool" => { :name => :label_boolean, :order => 6 }
}.freeze
validates_presence_of :name, :field_format
validates_uniqueness_of :name
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
def initialize(attributes = nil)
super
self.possible_values ||= []
end
def before_validation
# remove empty values
self.possible_values = self.possible_values.collect{|v| v unless v.empty?}.compact
end
def validate
if self.field_format == "list"
errors.add(:possible_values, :activerecord_error_blank) if self.possible_values.nil? || self.possible_values.empty?
errors.add(:possible_values, :activerecord_error_invalid) unless self.possible_values.is_a? Array
end
end
# to move in project_custom_field
def self.for_all
find(:all, :conditions => ["is_for_all=?", true])
end
def type_name
nil
# redMine - project management software
# Copyright (C) 2006 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.
class CustomField < ActiveRecord::Base
has_many :custom_values, :dependent => :delete_all
acts_as_list :scope => 'type = \'#{self.class}\''
serialize :possible_values
FIELD_FORMATS = { "string" => { :name => :label_string, :order => 1 },
"text" => { :name => :label_text, :order => 2 },
"int" => { :name => :label_integer, :order => 3 },
"float" => { :name => :label_float, :order => 4 },
"list" => { :name => :label_list, :order => 5 },
"date" => { :name => :label_date, :order => 6 },
"bool" => { :name => :label_boolean, :order => 7 }
}.freeze
validates_presence_of :name, :field_format
validates_uniqueness_of :name, :scope => :type
validates_length_of :name, :maximum => 30
validates_format_of :name, :with => /^[\w\s\.\'\-]*$/i
validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
def initialize(attributes = nil)
super
self.possible_values ||= []
end
end
def before_validation
# remove empty values
self.possible_values = self.possible_values.collect{|v| v unless v.empty?}.compact
# make sure these fields are not searchable
self.searchable = false if %w(int float date bool).include?(field_format)
true
end
def validate
if self.field_format == "list"
errors.add(:possible_values, :activerecord_error_blank) if self.possible_values.nil? || self.possible_values.empty?
errors.add(:possible_values, :activerecord_error_invalid) unless self.possible_values.is_a? Array
end
# validate default value
v = CustomValue.new(:custom_field => self.clone, :value => default_value, :customized => nil)
v.custom_field.is_required = false
errors.add(:default_value, :activerecord_error_invalid) unless v.valid?
end
def <=>(field)
position <=> field.position
end
# to move in project_custom_field
def self.for_all
find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
end
def type_name
nil
end
end

View File

@@ -1,38 +1,55 @@
# redMine - project management software
# Copyright (C) 2006 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.
class CustomValue < ActiveRecord::Base
belongs_to :custom_field
belongs_to :customized, :polymorphic => true
protected
def validate
errors.add(:value, :activerecord_error_blank) and return if custom_field.is_required? and value.empty?
errors.add(:value, :activerecord_error_invalid) unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
errors.add(:value, :activerecord_error_too_short) if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
errors.add(:value, :activerecord_error_too_long) if custom_field.max_length > 0 and value.length > custom_field.max_length
case custom_field.field_format
when "int"
errors.add(:value, :activerecord_error_not_a_number) unless value =~ /^[0-9]*$/
when "date"
errors.add(:value, :activerecord_error_not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/ or value.empty?
when "list"
errors.add(:value, :activerecord_error_inclusion) unless custom_field.possible_values.include? value or value.empty?
end
end
end
# redMine - project management software
# Copyright (C) 2006 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.
class CustomValue < ActiveRecord::Base
belongs_to :custom_field
belongs_to :customized, :polymorphic => true
def after_initialize
if custom_field && new_record? && (customized_type.blank? || (customized && customized.new_record?))
self.value ||= custom_field.default_value
end
end
# Returns true if the boolean custom value is true
def true?
self.value == '1'
end
protected
def validate
if value.blank?
errors.add(:value, :activerecord_error_blank) if custom_field.is_required? and value.blank?
else
errors.add(:value, :activerecord_error_invalid) unless custom_field.regexp.blank? or value =~ Regexp.new(custom_field.regexp)
errors.add(:value, :activerecord_error_too_short) if custom_field.min_length > 0 and value.length < custom_field.min_length
errors.add(:value, :activerecord_error_too_long) if custom_field.max_length > 0 and value.length > custom_field.max_length
# Format specific validations
case custom_field.field_format
when 'int'
errors.add(:value, :activerecord_error_not_a_number) unless value =~ /^[+-]?\d+$/
when 'float'
begin; Kernel.Float(value); rescue; errors.add(:value, :activerecord_error_invalid) end
when 'date'
errors.add(:value, :activerecord_error_not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/
when 'list'
errors.add(:value, :activerecord_error_inclusion) unless custom_field.possible_values.include?(value)
end
end
end
end

View File

@@ -1,24 +1,37 @@
# redMine - project management software
# Copyright (C) 2006 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.
class Document < ActiveRecord::Base
belongs_to :project
belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
has_many :attachments, :as => :container, :dependent => :destroy
# redMine - project management software
# Copyright (C) 2006 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.
class Document < ActiveRecord::Base
belongs_to :project
belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
acts_as_attachable :delete_permission => :manage_documents
acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"},
:author => Proc.new {|o| (a = o.attachments.find(:first, :order => "#{Attachment.table_name}.created_on ASC")) ? a.author : nil },
:url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}}
acts_as_activity_provider :find_options => {:include => :project}
validates_presence_of :project, :title, :category
validates_length_of :title, :maximum => 60
def after_initialize
if new_record?
self.category ||= Enumeration.default('DCAT')
end
end
end

View File

@@ -0,0 +1,23 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class EnabledModule < ActiveRecord::Base
belongs_to :project
validates_presence_of :name
validates_uniqueness_of :name, :scope => :project_id
end

View File

@@ -1,47 +1,81 @@
# redMine - project management software
# Copyright (C) 2006 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.
class Enumeration < ActiveRecord::Base
before_destroy :check_integrity
validates_presence_of :opt, :name
validates_uniqueness_of :name, :scope => [:opt]
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
OPTIONS = {
"IPRI" => :enumeration_issue_priorities,
"DCAT" => :enumeration_doc_categories
}.freeze
def self.get_values(option)
find(:all, :conditions => ['opt=?', option])
end
def option_name
OPTIONS[self.opt]
end
private
def check_integrity
case self.opt
when "IPRI"
raise "Can't delete enumeration" if Issue.find(:first, :conditions => ["priority_id=?", self.id])
when "DCAT"
raise "Can't delete enumeration" if Document.find(:first, :conditions => ["category_id=?", self.id])
end
# redMine - project management software
# Copyright (C) 2006 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.
class Enumeration < ActiveRecord::Base
acts_as_list :scope => 'opt = \'#{opt}\''
before_destroy :check_integrity
validates_presence_of :opt, :name
validates_uniqueness_of :name, :scope => [:opt]
validates_length_of :name, :maximum => 30
# Single table inheritance would be an option
OPTIONS = {
"IPRI" => {:label => :enumeration_issue_priorities, :model => Issue, :foreign_key => :priority_id},
"DCAT" => {:label => :enumeration_doc_categories, :model => Document, :foreign_key => :category_id},
"ACTI" => {:label => :enumeration_activities, :model => TimeEntry, :foreign_key => :activity_id}
}.freeze
def self.get_values(option)
find(:all, :conditions => {:opt => option}, :order => 'position')
end
def self.default(option)
find(:first, :conditions => {:opt => option, :is_default => true}, :order => 'position')
end
def option_name
OPTIONS[self.opt][:label]
end
def before_save
if is_default? && is_default_changed?
Enumeration.update_all("is_default = #{connection.quoted_false}", {:opt => opt})
end
end
def objects_count
OPTIONS[self.opt][:model].count(:conditions => "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
end
def in_use?
self.objects_count != 0
end
alias :destroy_without_reassign :destroy
# Destroy the enumeration
# If a enumeration is specified, objects are reassigned
def destroy(reassign_to = nil)
if reassign_to && reassign_to.is_a?(Enumeration)
OPTIONS[self.opt][:model].update_all("#{OPTIONS[self.opt][:foreign_key]} = #{reassign_to.id}", "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
end
destroy_without_reassign
end
def <=>(enumeration)
position <=> enumeration.position
end
def to_s; name end
private
def check_integrity
raise "Can't delete enumeration" if self.in_use?
end
end

View File

@@ -1,102 +1,280 @@
# redMine - project management software
# Copyright (C) 2006 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.
class Issue < ActiveRecord::Base
belongs_to :project
belongs_to :tracker
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
has_many :journals, :as => :journalized, :dependent => :destroy
has_many :attachments, :as => :container, :dependent => :destroy
has_many :custom_values, :dependent => :delete_all, :as => :customized
has_many :custom_fields, :through => :custom_values
validates_presence_of :subject, :description, :priority, :tracker, :author, :status
validates_inclusion_of :done_ratio, :in => 0..100
validates_associated :custom_values, :on => :update
# set default status for new issues
def before_validation
self.status = IssueStatus.default if new_record?
end
def validate
if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
errors.add :due_date, :activerecord_error_not_a_date
end
if self.due_date and self.start_date and self.due_date < self.start_date
errors.add :due_date, :activerecord_error_greater_than_start_date
end
end
#def before_create
# build_history
#end
def before_save
if @current_journal
# attributes changes
(Issue.column_names - %w(id description)).each {|c|
@current_journal.details << JournalDetail.new(:property => 'attr',
:prop_key => c,
:old_value => @issue_before_change.send(c),
:value => send(c)) unless send(c)==@issue_before_change.send(c)
}
# custom fields changes
custom_values.each {|c|
@current_journal.details << JournalDetail.new(:property => 'cf',
:prop_key => c.custom_field_id,
:old_value => @custom_values_before_change[c.custom_field_id],
:value => c.value) unless @custom_values_before_change[c.custom_field_id]==c.value
}
@current_journal.save unless @current_journal.details.empty? and @current_journal.notes.empty?
end
end
def long_id
"%05d" % self.id
end
def custom_value_for(custom_field)
self.custom_values.each {|v| return v if v.custom_field_id == custom_field.id }
return nil
end
def init_journal(user, notes = "")
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
@issue_before_change = self.clone
@custom_values_before_change = {}
self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
@current_journal
end
private
# Creates an history for the issue
#def build_history
# @history = self.histories.build
# @history.status = self.status
# @history.author = self.author
#end
# redMine - project management software
# Copyright (C) 2006-2007 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.
class Issue < ActiveRecord::Base
belongs_to :project
belongs_to :tracker
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
has_many :journals, :as => :journalized, :dependent => :destroy
has_many :time_entries, :dependent => :delete_all
has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC"
has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all
has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all
acts_as_attachable :after_remove => :attachment_removed
acts_as_customizable
acts_as_watchable
acts_as_searchable :columns => ['subject', "#{table_name}.description", "#{Journal.table_name}.notes"],
:include => [:project, :journals],
# sort by id so that limited eager loading doesn't break with postgresql
:order_column => "#{table_name}.id"
acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id}: #{o.subject}"},
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}}
acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]},
:author_key => :author_id
validates_presence_of :subject, :priority, :project, :tracker, :author, :status
validates_length_of :subject, :maximum => 255
validates_inclusion_of :done_ratio, :in => 0..100
validates_numericality_of :estimated_hours, :allow_nil => true
def after_initialize
if new_record?
# set default values for new records only
self.status ||= IssueStatus.default
self.priority ||= Enumeration.default('IPRI')
end
end
# Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
def available_custom_fields
(project && tracker) ? project.all_issue_custom_fields.select {|c| tracker.custom_fields.include? c } : []
end
def copy_from(arg)
issue = arg.is_a?(Issue) ? arg : Issue.find(arg)
self.attributes = issue.attributes.dup
self.custom_values = issue.custom_values.collect {|v| v.clone}
self
end
# Move an issue to a new project and tracker
def move_to(new_project, new_tracker = nil)
transaction do
if new_project && project_id != new_project.id
# delete issue relations
unless Setting.cross_project_issue_relations?
self.relations_from.clear
self.relations_to.clear
end
# issue is moved to another project
# reassign to the category with same name if any
new_category = category.nil? ? nil : new_project.issue_categories.find_by_name(category.name)
self.category = new_category
self.fixed_version = nil
self.project = new_project
end
if new_tracker
self.tracker = new_tracker
end
if save
# Manually update project_id on related time entries
TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id})
else
rollback_db_transaction
return false
end
end
return true
end
def priority_id=(pid)
self.priority = nil
write_attribute(:priority_id, pid)
end
def estimated_hours=(h)
write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
end
def validate
if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
errors.add :due_date, :activerecord_error_not_a_date
end
if self.due_date and self.start_date and self.due_date < self.start_date
errors.add :due_date, :activerecord_error_greater_than_start_date
end
if start_date && soonest_start && start_date < soonest_start
errors.add :start_date, :activerecord_error_invalid
end
end
def validate_on_create
errors.add :tracker_id, :activerecord_error_invalid unless project.trackers.include?(tracker)
end
def before_create
# default assignment based on category
if assigned_to.nil? && category && category.assigned_to
self.assigned_to = category.assigned_to
end
end
def before_save
if @current_journal
# attributes changes
(Issue.column_names - %w(id description)).each {|c|
@current_journal.details << JournalDetail.new(:property => 'attr',
:prop_key => c,
:old_value => @issue_before_change.send(c),
:value => send(c)) unless send(c)==@issue_before_change.send(c)
}
# custom fields changes
custom_values.each {|c|
next if (@custom_values_before_change[c.custom_field_id]==c.value ||
(@custom_values_before_change[c.custom_field_id].blank? && c.value.blank?))
@current_journal.details << JournalDetail.new(:property => 'cf',
:prop_key => c.custom_field_id,
:old_value => @custom_values_before_change[c.custom_field_id],
:value => c.value)
}
@current_journal.save
end
# Save the issue even if the journal is not saved (because empty)
true
end
def after_save
# Reload is needed in order to get the right status
reload
# Update start/due dates of following issues
relations_from.each(&:set_issue_to_dates)
# Close duplicates if the issue was closed
if @issue_before_change && !@issue_before_change.closed? && self.closed?
duplicates.each do |duplicate|
# Reload is need in case the duplicate was updated by a previous duplicate
duplicate.reload
# Don't re-close it if it's already closed
next if duplicate.closed?
# Same user and notes
duplicate.init_journal(@current_journal.user, @current_journal.notes)
duplicate.update_attribute :status, self.status
end
end
end
def init_journal(user, notes = "")
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
@issue_before_change = self.clone
@issue_before_change.status = self.status
@custom_values_before_change = {}
self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
# Make sure updated_on is updated when adding a note.
updated_on_will_change!
@current_journal
end
# Return true if the issue is closed, otherwise false
def closed?
self.status.is_closed?
end
# Returns true if the issue is overdue
def overdue?
!due_date.nil? && (due_date < Date.today)
end
# Users the issue can be assigned to
def assignable_users
project.assignable_users
end
# Returns an array of status that user is able to apply
def new_statuses_allowed_to(user)
statuses = status.find_new_statuses_allowed_to(user.role_for_project(project), tracker)
statuses << status unless statuses.empty?
statuses.uniq.sort
end
# Returns the mail adresses of users that should be notified for the issue
def recipients
recipients = project.recipients
# Author and assignee are always notified unless they have been locked
recipients << author.mail if author && author.active?
recipients << assigned_to.mail if assigned_to && assigned_to.active?
recipients.compact.uniq
end
def spent_hours
@spent_hours ||= time_entries.sum(:hours) || 0
end
def relations
(relations_from + relations_to).sort
end
def all_dependent_issues
dependencies = []
relations_from.each do |relation|
dependencies << relation.issue_to
dependencies += relation.issue_to.all_dependent_issues
end
dependencies
end
# Returns an array of issues that duplicate this one
def duplicates
relations_to.select {|r| r.relation_type == IssueRelation::TYPE_DUPLICATES}.collect {|r| r.issue_from}
end
# Returns the due date or the target due date if any
# Used on gantt chart
def due_before
due_date || (fixed_version ? fixed_version.effective_date : nil)
end
def duration
(start_date && due_date) ? due_date - start_date : 0
end
def soonest_start
@soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
end
def self.visible_by(usr)
with_scope(:find => { :conditions => Project.visible_by(usr) }) do
yield
end
end
def to_s
"#{tracker} ##{id}: #{subject}"
end
private
# Callback on attachment deletion
def attachment_removed(obj)
journal = init_journal(User.current)
journal.details << JournalDetail.new(:property => 'attachment',
:prop_key => obj.id,
:old_value => obj.filename)
journal.save
end
end

View File

@@ -1,29 +1,43 @@
# redMine - project management software
# Copyright (C) 2006 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.
class IssueCategory < ActiveRecord::Base
before_destroy :check_integrity
belongs_to :project
validates_presence_of :name
validates_uniqueness_of :name, :scope => [:project_id]
private
def check_integrity
raise "Can't delete category" if Issue.find(:first, :conditions => ["category_id=?", self.id])
# redMine - project management software
# Copyright (C) 2006 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.
class IssueCategory < ActiveRecord::Base
belongs_to :project
belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
has_many :issues, :foreign_key => 'category_id', :dependent => :nullify
validates_presence_of :name
validates_uniqueness_of :name, :scope => [:project_id]
validates_length_of :name, :maximum => 30
alias :destroy_without_reassign :destroy
# Destroy the category
# If a category is specified, issues are reassigned to this category
def destroy(reassign_to = nil)
if reassign_to && reassign_to.is_a?(IssueCategory) && reassign_to.project == self.project
Issue.update_all("category_id = #{reassign_to.id}", "category_id = #{id}")
end
destroy_without_reassign
end
def <=>(category)
name <=> category.name
end
def to_s; name end
end

View File

@@ -1,27 +1,27 @@
# redMine - project management software
# Copyright (C) 2006 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.
class IssueCustomField < CustomField
has_and_belongs_to_many :projects, :join_table => "custom_fields_projects", :foreign_key => "custom_field_id"
has_and_belongs_to_many :trackers, :join_table => "custom_fields_trackers", :foreign_key => "custom_field_id"
has_many :issues, :through => :issue_custom_values
def type_name
:label_issue_plural
end
end
# redMine - project management software
# Copyright (C) 2006 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.
class IssueCustomField < CustomField
has_and_belongs_to_many :projects, :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :foreign_key => "custom_field_id"
has_and_belongs_to_many :trackers, :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :foreign_key => "custom_field_id"
has_many :issues, :through => :issue_custom_values
def type_name
:label_issue_plural
end
end

View File

@@ -0,0 +1,79 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class IssueRelation < ActiveRecord::Base
belongs_to :issue_from, :class_name => 'Issue', :foreign_key => 'issue_from_id'
belongs_to :issue_to, :class_name => 'Issue', :foreign_key => 'issue_to_id'
TYPE_RELATES = "relates"
TYPE_DUPLICATES = "duplicates"
TYPE_BLOCKS = "blocks"
TYPE_PRECEDES = "precedes"
TYPES = { TYPE_RELATES => { :name => :label_relates_to, :sym_name => :label_relates_to, :order => 1 },
TYPE_DUPLICATES => { :name => :label_duplicates, :sym_name => :label_duplicated_by, :order => 2 },
TYPE_BLOCKS => { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 3 },
TYPE_PRECEDES => { :name => :label_precedes, :sym_name => :label_follows, :order => 4 },
}.freeze
validates_presence_of :issue_from, :issue_to, :relation_type
validates_inclusion_of :relation_type, :in => TYPES.keys
validates_numericality_of :delay, :allow_nil => true
validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
def validate
if issue_from && issue_to
errors.add :issue_to_id, :activerecord_error_invalid if issue_from_id == issue_to_id
errors.add :issue_to_id, :activerecord_error_not_same_project unless issue_from.project_id == issue_to.project_id || Setting.cross_project_issue_relations?
errors.add_to_base :activerecord_error_circular_dependency if issue_to.all_dependent_issues.include? issue_from
end
end
def other_issue(issue)
(self.issue_from_id == issue.id) ? issue_to : issue_from
end
def label_for(issue)
TYPES[relation_type] ? TYPES[relation_type][(self.issue_from_id == issue.id) ? :name : :sym_name] : :unknow
end
def before_save
if TYPE_PRECEDES == relation_type
self.delay ||= 0
else
self.delay = nil
end
set_issue_to_dates
end
def set_issue_to_dates
soonest_start = self.successor_soonest_start
if soonest_start && (!issue_to.start_date || issue_to.start_date < soonest_start)
issue_to.start_date, issue_to.due_date = successor_soonest_start, successor_soonest_start + issue_to.duration
issue_to.save
end
end
def successor_soonest_start
return nil unless (TYPE_PRECEDES == self.relation_type) && (issue_from.start_date || issue_from.due_date)
(issue_from.due_date || issue_from.start_date) + 1 + delay
end
def <=>(relation)
TYPES[self.relation_type][:order] <=> TYPES[relation.relation_type][:order]
end
end

View File

@@ -1,51 +1,69 @@
# redMine - project management software
# Copyright (C) 2006 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.
class IssueStatus < ActiveRecord::Base
before_destroy :check_integrity
has_many :workflows, :foreign_key => "old_status_id"
acts_as_list
validates_presence_of :name
validates_uniqueness_of :name
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
validates_length_of :html_color, :is => 6
validates_format_of :html_color, :with => /^[a-f0-9]*$/i
def before_save
IssueStatus.update_all "is_default=#{connection.quoted_false}" if self.is_default?
end
# Returns the default status for new issues
def self.default
find(:first, :conditions =>["is_default=?", true])
end
# Returns an array of all statuses the given role can switch to
def new_statuses_allowed_to(role, tracker)
statuses = []
for workflow in self.workflows
statuses << workflow.new_status if workflow.role_id == role.id and workflow.tracker_id == tracker.id
end unless role.nil? or tracker.nil?
statuses
end
private
def check_integrity
raise "Can't delete status" if Issue.find(:first, :conditions => ["status_id=?", self.id])
# redMine - project management software
# Copyright (C) 2006 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.
class IssueStatus < ActiveRecord::Base
before_destroy :check_integrity
has_many :workflows, :foreign_key => "old_status_id", :dependent => :delete_all
acts_as_list
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 30
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
def after_save
IssueStatus.update_all("is_default=#{connection.quoted_false}", ['id <> ?', id]) if self.is_default?
end
# Returns the default status for new issues
def self.default
find(:first, :conditions =>["is_default=?", true])
end
# Returns an array of all statuses the given role can switch to
# Uses association cache when called more than one time
def new_statuses_allowed_to(role, tracker)
new_statuses = workflows.select {|w| w.role_id == role.id && w.tracker_id == tracker.id}.collect{|w| w.new_status} if role && tracker
new_statuses ? new_statuses.compact.sort{|x, y| x.position <=> y.position } : []
end
# Same thing as above but uses a database query
# More efficient than the previous method if called just once
def find_new_statuses_allowed_to(role, tracker)
new_statuses = workflows.find(:all,
:include => :new_status,
:conditions => ["role_id=? and tracker_id=?", role.id, tracker.id]).collect{ |w| w.new_status }.compact if role && tracker
new_statuses ? new_statuses.sort{|x, y| x.position <=> y.position } : []
end
def new_status_allowed_to?(status, role, tracker)
status && role && tracker ?
!workflows.find(:first, :conditions => {:new_status_id => status.id, :role_id => role.id, :tracker_id => tracker.id}).nil? :
false
end
def <=>(status)
position <=> status.position
end
def to_s; name end
private
def check_integrity
raise "Can't delete status" if Issue.find(:first, :conditions => ["status_id=?", self.id])
end
end

View File

@@ -17,6 +17,52 @@
class Journal < ActiveRecord::Base
belongs_to :journalized, :polymorphic => true
# added as a quick fix to allow eager loading of the polymorphic association
# since always associated to an issue, for now
belongs_to :issue, :foreign_key => :journalized_id
belongs_to :user
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
attr_accessor :indice
acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
:description => :notes,
:author => :user,
:type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
acts_as_activity_provider :type => 'issues',
:permission => :view_issues,
:author_key => :user_id,
:find_options => {:include => [{:issue => :project}, :details, :user],
:conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
" (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
def save
# Do not save an empty journal
(details.empty? && notes.blank?) ? false : super
end
# Returns the new status if the journal contains a status change, otherwise nil
def new_status
c = details.detect {|detail| detail.prop_key == 'status_id'}
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
end
def new_value_for(prop)
c = details.detect {|detail| detail.prop_key == prop}
c ? c.value : nil
end
def editable_by?(usr)
usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
end
def project
journalized.respond_to?(:project) ? journalized.project : nil
end
def attachments
journalized.respond_to?(:attachments) ? journalized.attachments : nil
end
end

View File

@@ -17,4 +17,9 @@
class JournalDetail < ActiveRecord::Base
belongs_to :journal
def before_save
self.value = value[0..254] if value && value.is_a?(String)
self.old_value = old_value[0..254] if old_value && old_value.is_a?(String)
end
end

200
app/models/mail_handler.rb Normal file
View File

@@ -0,0 +1,200 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class MailHandler < ActionMailer::Base
include ActionView::Helpers::SanitizeHelper
class UnauthorizedAction < StandardError; end
class MissingInformation < StandardError; end
attr_reader :email, :user
def self.receive(email, options={})
@@handler_options = options.dup
@@handler_options[:issue] ||= {}
@@handler_options[:allow_override] = @@handler_options[:allow_override].split(',').collect(&:strip) if @@handler_options[:allow_override].is_a?(String)
@@handler_options[:allow_override] ||= []
# Project needs to be overridable if not specified
@@handler_options[:allow_override] << 'project' unless @@handler_options[:issue].has_key?(:project)
# Status overridable by default
@@handler_options[:allow_override] << 'status' unless @@handler_options[:issue].has_key?(:status)
super email
end
# Processes incoming emails
def receive(email)
@email = email
@user = User.active.find(:first, :conditions => ["LOWER(mail) = ?", email.from.to_a.first.to_s.strip.downcase])
unless @user
# Unknown user => the email is ignored
# TODO: ability to create the user's account
logger.info "MailHandler: email submitted by unknown user [#{email.from.first}]" if logger && logger.info
return false
end
User.current = @user
dispatch
end
private
ISSUE_REPLY_SUBJECT_RE = %r{\[[^\]]+#(\d+)\]}
def dispatch
if m = email.subject.match(ISSUE_REPLY_SUBJECT_RE)
receive_issue_update(m[1].to_i)
else
receive_issue
end
rescue ActiveRecord::RecordInvalid => e
# TODO: send a email to the user
logger.error e.message if logger
false
rescue MissingInformation => e
logger.error "MailHandler: missing information from #{user}: #{e.message}" if logger
false
rescue UnauthorizedAction => e
logger.error "MailHandler: unauthorized attempt from #{user}" if logger
false
end
# Creates a new issue
def receive_issue
project = target_project
tracker = (get_keyword(:tracker) && project.trackers.find_by_name(get_keyword(:tracker))) || project.trackers.find(:first)
category = (get_keyword(:category) && project.issue_categories.find_by_name(get_keyword(:category)))
priority = (get_keyword(:priority) && Enumeration.find_by_opt_and_name('IPRI', get_keyword(:priority)))
status = (get_keyword(:status) && IssueStatus.find_by_name(get_keyword(:status)))
# check permission
raise UnauthorizedAction unless user.allowed_to?(:add_issues, project)
issue = Issue.new(:author => user, :project => project, :tracker => tracker, :category => category, :priority => priority)
# check workflow
if status && issue.new_statuses_allowed_to(user).include?(status)
issue.status = status
end
issue.subject = email.subject.chomp.toutf8
issue.description = plain_text_body
# custom fields
issue.custom_field_values = issue.available_custom_fields.inject({}) do |h, c|
if value = get_keyword(c.name, :override => true)
h[c.id] = value
end
h
end
issue.save!
add_attachments(issue)
logger.info "MailHandler: issue ##{issue.id} created by #{user}" if logger && logger.info
# add To and Cc as watchers
add_watchers(issue)
# send notification after adding watchers so that they can reply to Redmine
Mailer.deliver_issue_add(issue) if Setting.notified_events.include?('issue_added')
issue
end
def target_project
# TODO: other ways to specify project:
# * parse the email To field
# * specific project (eg. Setting.mail_handler_target_project)
target = Project.find_by_identifier(get_keyword(:project))
raise MissingInformation.new('Unable to determine target project') if target.nil?
target
end
# Adds a note to an existing issue
def receive_issue_update(issue_id)
status = (get_keyword(:status) && IssueStatus.find_by_name(get_keyword(:status)))
issue = Issue.find_by_id(issue_id)
return unless issue
# check permission
raise UnauthorizedAction unless user.allowed_to?(:add_issue_notes, issue.project) || user.allowed_to?(:edit_issues, issue.project)
raise UnauthorizedAction unless status.nil? || user.allowed_to?(:edit_issues, issue.project)
# add the note
journal = issue.init_journal(user, plain_text_body)
add_attachments(issue)
# check workflow
if status && issue.new_statuses_allowed_to(user).include?(status)
issue.status = status
end
issue.save!
logger.info "MailHandler: issue ##{issue.id} updated by #{user}" if logger && logger.info
Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
journal
end
def add_attachments(obj)
if email.has_attachments?
email.attachments.each do |attachment|
Attachment.create(:container => obj,
:file => attachment,
:author => user,
:content_type => attachment.content_type)
end
end
end
# Adds To and Cc as watchers of the given object if the sender has the
# appropriate permission
def add_watchers(obj)
if user.allowed_to?("add_#{obj.class.name.underscore}_watchers".to_sym, obj.project)
addresses = [email.to, email.cc].flatten.compact.uniq.collect {|a| a.strip.downcase}
unless addresses.empty?
watchers = User.active.find(:all, :conditions => ['LOWER(mail) IN (?)', addresses])
watchers.each {|w| obj.add_watcher(w)}
end
end
end
def get_keyword(attr, options={})
@keywords ||= {}
if @keywords.has_key?(attr)
@keywords[attr]
else
@keywords[attr] = begin
if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) && plain_text_body.gsub!(/^#{attr}:[ \t]*(.+)\s*$/i, '')
$1.strip
elsif !@@handler_options[:issue][attr].blank?
@@handler_options[:issue][attr]
end
end
end
end
# Returns the text/plain part of the email
# If not found (eg. HTML-only email), returns the body with tags removed
def plain_text_body
return @plain_text_body unless @plain_text_body.nil?
parts = @email.parts.collect {|c| (c.respond_to?(:parts) && !c.parts.empty?) ? c.parts : c}.flatten
if parts.empty?
parts << @email
end
plain_text_part = parts.detect {|p| p.content_type == 'text/plain'}
if plain_text_part.nil?
# no text/plain part found, assuming html-only email
# strip html tags and remove doctype directive
@plain_text_body = strip_tags(@email.body.to_s)
@plain_text_body.gsub! %r{^<!DOCTYPE .*$}, ''
else
@plain_text_body = plain_text_part.body.to_s
end
@plain_text_body.strip!
@plain_text_body
end
end

View File

@@ -1,88 +1,262 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class Mailer < ActionMailer::Base
helper IssuesHelper
# redMine - project management software
# Copyright (C) 2006-2007 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.
def issue_add(issue)
set_language_if_valid(Setting.default_language)
# Sends to all project members
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
@from = Setting.mail_from
@subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
@body['issue'] = issue
end
def issue_edit(journal)
set_language_if_valid(Setting.default_language)
# Sends to all project members
issue = journal.journalized
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
@from = Setting.mail_from
@subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
@body['issue'] = issue
@body['journal']= journal
end
def document_add(document)
set_language_if_valid(Setting.default_language)
@recipients = document.project.users.collect { |u| u.mail if u.mail_notification }.compact
@from = Setting.mail_from
@subject = "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
@body['document'] = document
end
def attachments_add(attachments)
set_language_if_valid(Setting.default_language)
container = attachments.first.container
url = "http://#{Setting.host_name}/"
added_to = ""
case container.class.to_s
when 'Version'
url << "projects/list_files/#{container.project_id}"
added_to = "#{l(:label_version)}: #{container.name}"
when 'Document'
url << "documents/show/#{container.id}"
added_to = "#{l(:label_document)}: #{container.title}"
when 'Issue'
url << "issues/show/#{container.id}"
added_to = "#{container.tracker.name} ##{container.id}: #{container.subject}"
end
@recipients = container.project.users.collect { |u| u.mail if u.mail_notification }.compact
@from = Setting.mail_from
@subject = "[#{container.project.name}] #{l(:label_attachment_new)}"
@body['attachments'] = attachments
@body['url'] = url
@body['added_to'] = added_to
end
def lost_password(token)
set_language_if_valid(token.user.language)
@recipients = token.user.mail
@from = Setting.mail_from
@subject = l(:mail_subject_lost_password)
@body['token'] = token
end
def register(token)
set_language_if_valid(token.user.language)
@recipients = token.user.mail
@from = Setting.mail_from
@subject = l(:mail_subject_register)
@body['token'] = token
end
class Mailer < ActionMailer::Base
helper :application
helper :issues
helper :custom_fields
include ActionController::UrlWriter
def self.default_url_options
h = Setting.host_name
h = h.to_s.gsub(%r{\/.*$}, '') unless Redmine::Utils.relative_url_root.blank?
{ :host => h, :protocol => Setting.protocol }
end
def issue_add(issue)
redmine_headers 'Project' => issue.project.identifier,
'Issue-Id' => issue.id,
'Issue-Author' => issue.author.login
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
recipients issue.recipients
cc(issue.watcher_recipients - @recipients)
subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
body :issue => issue,
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
end
def issue_edit(journal)
issue = journal.journalized
redmine_headers 'Project' => issue.project.identifier,
'Issue-Id' => issue.id,
'Issue-Author' => issue.author.login
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
@author = journal.user
recipients issue.recipients
# Watchers in cc
cc(issue.watcher_recipients - @recipients)
s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
s << issue.subject
subject s
body :issue => issue,
:journal => journal,
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
end
def reminder(user, issues, days)
set_language_if_valid user.language
recipients user.mail
subject l(:mail_subject_reminder, issues.size)
body :issues => issues,
:days => days,
:issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'due_date', :sort_order => 'asc')
end
def document_added(document)
redmine_headers 'Project' => document.project.identifier
recipients document.project.recipients
subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
body :document => document,
:document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
end
def attachments_added(attachments)
container = attachments.first.container
added_to = ''
added_to_url = ''
case container.class.name
when 'Project'
added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container)
added_to = "#{l(:label_project)}: #{container}"
when 'Version'
added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container.project_id)
added_to = "#{l(:label_version)}: #{container.name}"
when 'Document'
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
added_to = "#{l(:label_document)}: #{container.title}"
end
redmine_headers 'Project' => container.project.identifier
recipients container.project.recipients
subject "[#{container.project.name}] #{l(:label_attachment_new)}"
body :attachments => attachments,
:added_to => added_to,
:added_to_url => added_to_url
end
def news_added(news)
redmine_headers 'Project' => news.project.identifier
recipients news.project.recipients
subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
body :news => news,
:news_url => url_for(:controller => 'news', :action => 'show', :id => news)
end
def message_posted(message, recipients)
redmine_headers 'Project' => message.project.identifier,
'Topic-Id' => (message.parent_id || message.id)
recipients(recipients)
subject "[#{message.board.project.name} - #{message.board.name}] #{message.subject}"
body :message => message,
:message_url => url_for(:controller => 'messages', :action => 'show', :board_id => message.board_id, :id => message.root)
end
def account_information(user, password)
set_language_if_valid user.language
recipients user.mail
subject l(:mail_subject_register, Setting.app_title)
body :user => user,
:password => password,
:login_url => url_for(:controller => 'account', :action => 'login')
end
def account_activation_request(user)
# Send the email to all active administrators
recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
subject l(:mail_subject_account_activation_request, Setting.app_title)
body :user => user,
:url => url_for(:controller => 'users', :action => 'index', :status => User::STATUS_REGISTERED, :sort_key => 'created_on', :sort_order => 'desc')
end
# A registered user's account was activated by an administrator
def account_activated(user)
set_language_if_valid user.language
recipients user.mail
subject l(:mail_subject_register, Setting.app_title)
body :user => user,
:login_url => url_for(:controller => 'account', :action => 'login')
end
def lost_password(token)
set_language_if_valid(token.user.language)
recipients token.user.mail
subject l(:mail_subject_lost_password, Setting.app_title)
body :token => token,
:url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
end
def register(token)
set_language_if_valid(token.user.language)
recipients token.user.mail
subject l(:mail_subject_register, Setting.app_title)
body :token => token,
:url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
end
def test(user)
set_language_if_valid(user.language)
recipients user.mail
subject 'Redmine test'
body :url => url_for(:controller => 'welcome')
end
# Overrides default deliver! method to prevent from sending an email
# with no recipient, cc or bcc
def deliver!(mail = @mail)
return false if (recipients.nil? || recipients.empty?) &&
(cc.nil? || cc.empty?) &&
(bcc.nil? || bcc.empty?)
super
end
# Sends reminders to issue assignees
# Available options:
# * :days => how many days in the future to remind about (defaults to 7)
# * :tracker => id of tracker for filtering issues (defaults to all trackers)
# * :project => id or identifier of project to process (defaults to all projects)
def self.reminders(options={})
days = options[:days] || 7
project = options[:project] ? Project.find(options[:project]) : nil
tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
s = ARCondition.new ["#{IssueStatus.table_name}.is_closed = ? AND #{Issue.table_name}.due_date <= ?", false, days.day.from_now.to_date]
s << "#{Issue.table_name}.assigned_to_id IS NOT NULL"
s << "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}"
s << "#{Issue.table_name}.project_id = #{project.id}" if project
s << "#{Issue.table_name}.tracker_id = #{tracker.id}" if tracker
issues_by_assignee = Issue.find(:all, :include => [:status, :assigned_to, :project, :tracker],
:conditions => s.conditions
).group_by(&:assigned_to)
issues_by_assignee.each do |assignee, issues|
deliver_reminder(assignee, issues, days) unless assignee.nil?
end
end
private
def initialize_defaults(method_name)
super
set_language_if_valid Setting.default_language
from Setting.mail_from
# Common headers
headers 'X-Mailer' => 'Redmine',
'X-Redmine-Host' => Setting.host_name,
'X-Redmine-Site' => Setting.app_title
end
# Appends a Redmine header field (name is prepended with 'X-Redmine-')
def redmine_headers(h)
h.each { |k,v| headers["X-Redmine-#{k}"] = v }
end
# Overrides the create_mail method
def create_mail
# Removes the current user from the recipients and cc
# if he doesn't want to receive notifications about what he does
@author ||= User.current
if @author.pref[:no_self_notified]
recipients.delete(@author.mail) if recipients
cc.delete(@author.mail) if cc
end
# Blind carbon copy recipients
if Setting.bcc_recipients?
bcc([recipients, cc].flatten.compact.uniq)
recipients []
cc []
end
super
end
# Renders a message with the corresponding layout
def render_message(method_name, body)
layout = method_name.match(%r{text\.html\.(rhtml|rxml)}) ? 'layout.text.html.rhtml' : 'layout.text.plain.rhtml'
body[:content_for_layout] = render(:file => method_name, :body => body)
ActionView::Base.new(template_root, body, self).render(:file => "mailer/#{layout}", :use_full_path => true)
end
# for the case of plain text only
def body(*params)
value = super(*params)
if Setting.plain_text_mail?
templates = Dir.glob("#{template_path}/#{@template}.text.plain.{rhtml,erb}")
unless String === @body or templates.empty?
template = File.basename(templates.first)
@body[:content_for_layout] = render(:file => template, :body => @body)
@body = ActionView::Base.new(template_root, @body, self).render(:file => "mailer/layout.text.plain.rhtml", :use_full_path => true)
return @body
end
end
return value
end
# Makes partial rendering work with Rails 1.2 (retro-compatibility)
def self.controller_path
''
end unless respond_to?('controller_path')
end

View File

@@ -1,29 +1,42 @@
# redMine - project management software
# Copyright (C) 2006 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.
class Member < ActiveRecord::Base
belongs_to :user
belongs_to :role
belongs_to :project
validates_presence_of :role, :user, :project
validates_uniqueness_of :user_id, :scope => :project_id
def name
self.user.display_name
# redMine - project management software
# Copyright (C) 2006 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.
class Member < ActiveRecord::Base
belongs_to :user
belongs_to :role
belongs_to :project
validates_presence_of :role, :user, :project
validates_uniqueness_of :user_id, :scope => :project_id
def validate
errors.add :role_id, :activerecord_error_invalid if role && !role.member?
end
def name
self.user.name
end
def <=>(member)
role == member.role ? (user <=> member.user) : (role <=> member.role)
end
def before_destroy
# remove category based auto assignments for this member
IssueCategory.update_all "assigned_to_id = NULL", ["project_id = ? AND assigned_to_id = ?", project.id, user.id]
end
end

89
app/models/message.rb Normal file
View File

@@ -0,0 +1,89 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class Message < ActiveRecord::Base
belongs_to :board
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
acts_as_attachable
belongs_to :last_reply, :class_name => 'Message', :foreign_key => 'last_reply_id'
acts_as_searchable :columns => ['subject', 'content'],
:include => {:board => :project},
:project_key => 'project_id',
:date_column => "#{table_name}.created_on"
acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
:description => :content,
:type => Proc.new {|o| o.parent_id.nil? ? 'message' : 'reply'},
:url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id}.merge(o.parent_id.nil? ? {:id => o.id} :
{:id => o.parent_id, :anchor => "message-#{o.id}"})}
acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]},
:author_key => :author_id
acts_as_watchable
attr_protected :locked, :sticky
validates_presence_of :subject, :content
validates_length_of :subject, :maximum => 255
after_create :add_author_as_watcher
def validate_on_create
# Can not reply to a locked topic
errors.add_to_base 'Topic is locked' if root.locked? && self != root
end
def after_create
board.update_attribute(:last_message_id, self.id)
board.increment! :messages_count
if parent
parent.reload.update_attribute(:last_reply_id, self.id)
else
board.increment! :topics_count
end
end
def after_destroy
# The following line is required so that the previous counter
# updates (due to children removal) are not overwritten
board.reload
board.decrement! :messages_count
board.decrement! :topics_count unless parent
end
def sticky?
sticky == 1
end
def project
board.project
end
def editable_by?(usr)
usr && usr.logged? && (usr.allowed_to?(:edit_messages, project) || (self.author == usr && usr.allowed_to?(:edit_own_messages, project)))
end
def destroyable_by?(usr)
usr && usr.logged? && (usr.allowed_to?(:delete_messages, project) || (self.author == usr && usr.allowed_to?(:delete_own_messages, project)))
end
private
def add_author_as_watcher
Watcher.create(:watchable => self.root, :user => author)
end
end

View File

@@ -0,0 +1,30 @@
# redMine - project management software
# Copyright (C) 2006-2007 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.
class MessageObserver < ActiveRecord::Observer
def after_create(message)
recipients = []
# send notification to the topic watchers
recipients += message.root.watcher_recipients
# send notification to the board watchers
recipients += message.board.watcher_recipients
# send notification to project members who want to be notified
recipients += message.board.project.recipients
recipients = recipients.compact.uniq
Mailer.deliver_message_posted(message, recipients) if !recipients.empty? && Setting.notified_events.include?('message_posted')
end
end

View File

@@ -1,29 +1,36 @@
# redMine - project management software
# Copyright (C) 2006 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.
class News < ActiveRecord::Base
belongs_to :project
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
validates_presence_of :title, :description
# returns latest news for projects visible by user
def self.latest(user=nil, count=5)
find(:all, :limit => count, :conditions => Project.visible_by(user), :include => [ :author, :project ], :order => "news.created_on DESC")
# Redmine - project management software
# Copyright (C) 2006-2008 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.
class News < ActiveRecord::Base
belongs_to :project
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
validates_presence_of :title, :description
validates_length_of :title, :maximum => 60
validates_length_of :summary, :maximum => 255
acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
acts_as_activity_provider :find_options => {:include => [:project, :author]},
:author_key => :author_id
# returns latest news for projects visible by user
def self.latest(user = User.current, count = 5)
find(:all, :limit => count, :conditions => Project.allowed_to_condition(user, :view_news), :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
end
end

View File

@@ -1,65 +0,0 @@
# redMine - project management software
# Copyright (C) 2006 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.
class Permission < ActiveRecord::Base
has_and_belongs_to_many :roles
validates_presence_of :controller, :action, :description
GROUPS = {
100 => :label_project,
200 => :label_member_plural,
300 => :label_version_plural,
400 => :label_issue_category_plural,
600 => :label_query_plural,
1000 => :label_issue_plural,
1100 => :label_news_plural,
1200 => :label_document_plural,
1300 => :label_attachment_plural,
1400 => :label_repository
}.freeze
@@cached_perms_for_public = nil
@@cached_perms_for_roles = nil
def name
self.controller + "/" + self.action
end
def group_id
(self.sort / 100)*100
end
def self.allowed_to_public(action)
@@cached_perms_for_public ||= find(:all, :conditions => ["is_public=?", true]).collect {|p| "#{p.controller}/#{p.action}"}
@@cached_perms_for_public.include? action
end
def self.allowed_to_role(action, role)
@@cached_perms_for_roles ||=
begin
perms = {}
find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } }
perms
end
allowed_to_public(action) or (@@cached_perms_for_roles[action] and @@cached_perms_for_roles[action].include? role)
end
def self.allowed_to_role_expired
@@cached_perms_for_roles = nil
end
end

View File

@@ -1,70 +1,276 @@
# redMine - project management software
# Copyright (C) 2006 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.
class Project < ActiveRecord::Base
has_many :versions, :dependent => :destroy, :order => "versions.effective_date DESC, versions.name DESC"
has_many :members, :dependent => :delete_all, :include => :user, :conditions => "users.status=#{User::STATUS_ACTIVE}"
has_many :users, :through => :members
has_many :custom_values, :dependent => :delete_all, :as => :customized
has_many :issues, :dependent => :destroy, :order => "issues.created_on DESC", :include => [:status, :tracker]
has_many :queries, :dependent => :delete_all
has_many :documents, :dependent => :destroy
has_many :news, :dependent => :delete_all, :include => :author
has_many :issue_categories, :dependent => :delete_all, :order => "issue_categories.name"
has_one :repository, :dependent => :destroy
has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
acts_as_tree :order => "name", :counter_cache => true
validates_presence_of :name, :description
validates_uniqueness_of :name
validates_associated :custom_values, :on => :update
validates_associated :repository
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
# returns latest created projects
# non public projects will be returned only if user is a member of those
def self.latest(user=nil, count=5)
find(:all, :limit => count, :conditions => visible_by(user), :order => "projects.created_on DESC")
end
def self.visible_by(user=nil)
if user && !user.memberships.empty?
return ["projects.is_public = ? or projects.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')})", true]
else
return ["projects.is_public = ?", true]
end
end
# Returns an array of all custom fields enabled for project issues
# (explictly associated custom fields and custom fields enabled for all projects)
def custom_fields_for_issues(tracker)
tracker.custom_fields.find(:all, :include => :projects,
:conditions => ["is_for_all=? or project_id=?", true, self.id])
#(CustomField.for_all + custom_fields).uniq
end
def all_custom_fields
@all_custom_fields ||= IssueCustomField.find(:all, :include => :projects,
:conditions => ["is_for_all=? or project_id=?", true, self.id])
end
protected
def validate
errors.add(parent_id, " must be a root project") if parent and parent.parent
errors.add_to_base("A project with subprojects can't be a subproject") if parent and children.size > 0
# redMine - project management software
# Copyright (C) 2006 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.
class Project < ActiveRecord::Base
# Project statuses
STATUS_ACTIVE = 1
STATUS_ARCHIVED = 9
has_many :members, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
has_many :users, :through => :members
has_many :enabled_modules, :dependent => :delete_all
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
has_many :issues, :dependent => :destroy, :order => "#{Issue.table_name}.created_on DESC", :include => [:status, :tracker]
has_many :issue_changes, :through => :issues, :source => :journals
has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
has_many :time_entries, :dependent => :delete_all
has_many :queries, :dependent => :delete_all
has_many :documents, :dependent => :destroy
has_many :news, :dependent => :delete_all, :include => :author
has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name"
has_many :boards, :dependent => :destroy, :order => "position ASC"
has_one :repository, :dependent => :destroy
has_many :changesets, :through => :repository
has_one :wiki, :dependent => :destroy
# Custom field for the project issues
has_and_belongs_to_many :issue_custom_fields,
:class_name => 'IssueCustomField',
:order => "#{CustomField.table_name}.position",
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
:association_foreign_key => 'custom_field_id'
acts_as_tree :order => "name", :counter_cache => true
acts_as_attachable :view_permission => :view_files,
:delete_permission => :manage_files
acts_as_customizable
acts_as_searchable :columns => ['name', 'description'], :project_key => 'id', :permission => nil
acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"},
:url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o.id}},
:author => nil
attr_protected :status, :enabled_module_names
validates_presence_of :name, :identifier
validates_uniqueness_of :name, :identifier
validates_associated :repository, :wiki
validates_length_of :name, :maximum => 30
validates_length_of :homepage, :maximum => 255
validates_length_of :identifier, :in => 2..20
validates_format_of :identifier, :with => /^[a-z0-9\-]*$/
before_destroy :delete_all_members
named_scope :has_module, lambda { |mod| { :conditions => ["#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s] } }
def identifier=(identifier)
super unless identifier_frozen?
end
def identifier_frozen?
errors[:identifier].nil? && !(new_record? || identifier.blank?)
end
def issues_with_subprojects(include_subprojects=false)
conditions = nil
if include_subprojects
ids = [id] + child_ids
conditions = ["#{Project.table_name}.id IN (#{ids.join(',')}) AND #{Project.visible_by}"]
end
conditions ||= ["#{Project.table_name}.id = ?", id]
# Quick and dirty fix for Rails 2 compatibility
Issue.send(:with_scope, :find => { :conditions => conditions }) do
Version.send(:with_scope, :find => { :conditions => conditions }) do
yield
end
end
end
# returns latest created projects
# non public projects will be returned only if user is a member of those
def self.latest(user=nil, count=5)
find(:all, :limit => count, :conditions => visible_by(user), :order => "created_on DESC")
end
def self.visible_by(user=nil)
user ||= User.current
if user && user.admin?
return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
elsif user && user.memberships.any?
return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND (#{Project.table_name}.is_public = #{connection.quoted_true} or #{Project.table_name}.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')}))"
else
return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND #{Project.table_name}.is_public = #{connection.quoted_true}"
end
end
def self.allowed_to_condition(user, permission, options={})
statements = []
base_statement = "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
if perm = Redmine::AccessControl.permission(permission)
unless perm.project_module.nil?
# If the permission belongs to a project module, make sure the module is enabled
base_statement << " AND EXISTS (SELECT em.id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.project_module}' AND em.project_id=#{Project.table_name}.id)"
end
end
if options[:project]
project_statement = "#{Project.table_name}.id = #{options[:project].id}"
project_statement << " OR #{Project.table_name}.parent_id = #{options[:project].id}" if options[:with_subprojects]
base_statement = "(#{project_statement}) AND (#{base_statement})"
end
if user.admin?
# no restriction
else
statements << "1=0"
if user.logged?
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" if Role.non_member.allowed_to?(permission)
allowed_project_ids = user.memberships.select {|m| m.role.allowed_to?(permission)}.collect {|m| m.project_id}
statements << "#{Project.table_name}.id IN (#{allowed_project_ids.join(',')})" if allowed_project_ids.any?
elsif Role.anonymous.allowed_to?(permission)
# anonymous user allowed on public project
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}"
else
# anonymous user is not authorized
end
end
statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))"
end
def project_condition(with_subprojects)
cond = "#{Project.table_name}.id = #{id}"
cond = "(#{cond} OR #{Project.table_name}.parent_id = #{id})" if with_subprojects
cond
end
def self.find(*args)
if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
project = find_by_identifier(*args)
raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil?
project
else
super
end
end
def to_param
# id is used for projects with a numeric identifier (compatibility)
@to_param ||= (identifier.to_s =~ %r{^\d*$} ? id : identifier)
end
def active?
self.status == STATUS_ACTIVE
end
def archive
# Archive subprojects if any
children.each do |subproject|
subproject.archive
end
update_attribute :status, STATUS_ARCHIVED
end
def unarchive
return false if parent && !parent.active?
update_attribute :status, STATUS_ACTIVE
end
def active_children
children.select {|child| child.active?}
end
# Returns an array of the trackers used by the project and its sub projects
def rolled_up_trackers
@rolled_up_trackers ||=
Tracker.find(:all, :include => :projects,
:select => "DISTINCT #{Tracker.table_name}.*",
:conditions => ["#{Project.table_name}.id = ? OR #{Project.table_name}.parent_id = ?", id, id],
:order => "#{Tracker.table_name}.position")
end
# Deletes all project's members
def delete_all_members
Member.delete_all(['project_id = ?', id])
end
# Users issues can be assigned to
def assignable_users
members.select {|m| m.role.assignable?}.collect {|m| m.user}.sort
end
# Returns the mail adresses of users that should be always notified on project events
def recipients
members.select {|m| m.mail_notification? || m.user.mail_notification?}.collect {|m| m.user.mail}
end
# Returns an array of all custom fields enabled for project issues
# (explictly associated custom fields and custom fields enabled for all projects)
def all_issue_custom_fields
@all_issue_custom_fields ||= (IssueCustomField.for_all + issue_custom_fields).uniq.sort
end
def project
self
end
def <=>(project)
name.downcase <=> project.name.downcase
end
def to_s
name
end
# Returns a short description of the projects (first lines)
def short_description(length = 255)
description.gsub(/^(.{#{length}}[^\n]*).*$/m, '\1').strip if description
end
def allows_to?(action)
if action.is_a? Hash
allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
else
allowed_permissions.include? action
end
end
def module_enabled?(module_name)
module_name = module_name.to_s
enabled_modules.detect {|m| m.name == module_name}
end
def enabled_module_names=(module_names)
enabled_modules.clear
module_names = [] unless module_names && module_names.is_a?(Array)
module_names.each do |name|
enabled_modules << EnabledModule.new(:name => name.to_s)
end
end
# Returns an auto-generated project identifier based on the last identifier used
def self.next_identifier
p = Project.find(:first, :order => 'created_on DESC')
p.nil? ? nil : p.identifier.to_s.succ
end
protected
def validate
errors.add(parent_id, " must be a root project") if parent and parent.parent
errors.add_to_base("A project with subprojects can't be a subproject") if parent and children.size > 0
errors.add(:identifier, :activerecord_error_invalid) if !identifier.blank? && identifier.match(/^\d*$/)
end
private
def allowed_permissions
@allowed_permissions ||= begin
module_names = enabled_modules.collect {|m| m.name}
Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name}
end
end
def allowed_actions
@actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
end
end

View File

@@ -1,22 +1,22 @@
# redMine - project management software
# Copyright (C) 2006 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.
class ProjectCustomField < CustomField
def type_name
:label_project_plural
end
end
# redMine - project management software
# Copyright (C) 2006 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.
class ProjectCustomField < CustomField
def type_name
:label_project_plural
end
end

View File

@@ -1,5 +1,5 @@
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
# Redmine - project management software
# Copyright (C) 2006-2008 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
@@ -15,14 +15,49 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class QueryColumn
attr_accessor :name, :sortable, :default_order
include GLoc
def initialize(name, options={})
self.name = name
self.sortable = options[:sortable]
self.default_order = options[:default_order]
end
def caption
set_language_if_valid(User.current.language)
l("field_#{name}")
end
end
class QueryCustomFieldColumn < QueryColumn
def initialize(custom_field)
self.name = "cf_#{custom_field.id}".to_sym
self.sortable = false
@cf = custom_field
end
def caption
@cf.name
end
def custom_field
@cf
end
end
class Query < ActiveRecord::Base
belongs_to :project
belongs_to :user
serialize :filters
serialize :column_names
attr_protected :project, :user
attr_protected :project_id, :user_id
validates_presence_of :name, :on => :save
validates_length_of :name, :maximum => 255
@@operators = { "=" => :label_equals,
"!" => :label_not_equals,
@@ -30,10 +65,13 @@ class Query < ActiveRecord::Base
"c" => :label_closed_issues,
"!*" => :label_none,
"*" => :label_all,
">=" => '>=',
"<=" => '<=',
"<t+" => :label_in_less_than,
">t+" => :label_in_more_than,
"t+" => :label_in,
"t" => :label_today,
"w" => :label_this_week,
">t-" => :label_less_than_ago,
"<t-" => :label_more_than_ago,
"t-" => :label_ago,
@@ -45,46 +83,104 @@ class Query < ActiveRecord::Base
@@operators_by_filter_type = { :list => [ "=", "!" ],
:list_status => [ "o", "=", "!", "c", "*" ],
:list_optional => [ "=", "!", "!*", "*" ],
:date => [ "<t+", ">t+", "t+", "t", ">t-", "<t-", "t-" ],
:date_past => [ ">t-", "<t-", "t-", "t" ],
:text => [ "~", "!~" ] }
:list_subprojects => [ "*", "!*", "=" ],
:date => [ "<t+", ">t+", "t+", "t", "w", ">t-", "<t-", "t-" ],
:date_past => [ ">t-", "<t-", "t-", "t", "w" ],
:string => [ "=", "~", "!", "!~" ],
:text => [ "~", "!~" ],
:integer => [ "=", ">=", "<=", "!*", "*" ] }
cattr_reader :operators_by_filter_type
@@available_columns = [
QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position"),
QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position"),
QueryColumn.new(:priority, :sortable => "#{Enumeration.table_name}.position", :default_order => 'desc'),
QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
QueryColumn.new(:author),
QueryColumn.new(:assigned_to, :sortable => "#{User.table_name}.lastname"),
QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'),
QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name"),
QueryColumn.new(:fixed_version, :sortable => "#{Version.table_name}.effective_date", :default_order => 'desc'),
QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"),
QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"),
QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"),
QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio"),
QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'),
]
cattr_reader :available_columns
def initialize(attributes = nil)
super attributes
self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
self.is_public = true
set_language_if_valid(User.current.language)
end
def after_initialize
# Store the fact that project is nil (used in #editable_by?)
@is_for_all = project.nil?
end
def validate
filters.each_key do |field|
errors.add field.gsub(/\_id$/, ""), :activerecord_error_blank unless
errors.add label_for(field), :activerecord_error_blank unless
# filter requires one or more values
(values_for(field) and !values_for(field).first.empty?) or
(values_for(field) and !values_for(field).first.blank?) or
# filter doesn't require any value
["o", "c", "!*", "*", "t"].include? operator_for(field)
["o", "c", "!*", "*", "t", "w"].include? operator_for(field)
end if filters
end
def editable_by?(user)
return false unless user
# Admin can edit them all and regular users can edit their private queries
return true if user.admin? || (!is_public && self.user_id == user.id)
# Members can not edit public queries that are for all project (only admin is allowed to)
is_public && !@is_for_all && user.allowed_to?(:manage_public_queries, project)
end
def available_filters
return @available_filters if @available_filters
trackers = project.nil? ? Tracker.find(:all, :order => 'position') : project.rolled_up_trackers
@available_filters = { "status_id" => { :type => :list_status, :order => 1, :values => IssueStatus.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] } },
"tracker_id" => { :type => :list, :order => 2, :values => Tracker.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] } },
"priority_id" => { :type => :list, :order => 3, :values => Enumeration.find(:all, :conditions => ['opt=?','IPRI']).collect{|s| [s.name, s.id.to_s] } },
"tracker_id" => { :type => :list, :order => 2, :values => trackers.collect{|s| [s.name, s.id.to_s] } },
"priority_id" => { :type => :list, :order => 3, :values => Enumeration.find(:all, :conditions => ['opt=?','IPRI'], :order => 'position').collect{|s| [s.name, s.id.to_s] } },
"subject" => { :type => :text, :order => 8 },
"created_on" => { :type => :date_past, :order => 9 },
"updated_on" => { :type => :date_past, :order => 10 },
"start_date" => { :type => :date, :order => 11 },
"due_date" => { :type => :date, :order => 12 } }
unless project.nil?
"due_date" => { :type => :date, :order => 12 },
"estimated_hours" => { :type => :integer, :order => 13 },
"done_ratio" => { :type => :integer, :order => 14 }}
user_values = []
user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
if project
user_values += project.users.sort.collect{|s| [s.name, s.id.to_s] }
else
# members of the user's projects
user_values += User.current.projects.collect(&:users).flatten.uniq.sort.collect{|s| [s.name, s.id.to_s] }
end
@available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty?
@available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
if project
# project specific filters
@available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => @project.users.collect{|s| [s.name, s.id.to_s] } }
@available_filters["author_id"] = { :type => :list, :order => 5, :values => @project.users.collect{|s| [s.name, s.id.to_s] } }
@available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.collect{|s| [s.name, s.id.to_s] } }
# remove category filter if no category defined
@available_filters.delete "category_id" if @available_filters["category_id"][:values].empty?
unless @project.issue_categories.empty?
@available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
end
unless @project.versions.empty?
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } }
end
unless @project.active_children.empty?
@available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } }
end
add_custom_fields_filters(@project.all_issue_custom_fields)
else
# global filters for cross project issue list
add_custom_fields_filters(IssueCustomField.find(:all, :conditions => {:is_filter => true, :is_for_all => true}))
end
@available_filters
end
@@ -122,46 +218,189 @@ class Query < ActiveRecord::Base
has_filter?(field) ? filters[field][:values] : nil
end
def statement
sql = "1=1"
sql << " AND issues.project_id=%d" % project.id if project
filters.each_key do |field|
v = values_for field
next unless v and !v.empty?
sql = sql + " AND " unless sql.empty?
case operator_for field
when "="
sql = sql + "issues.#{field} IN (" + v.each(&:to_i).join(",") + ")"
when "!"
sql = sql + "issues.#{field} NOT IN (" + v.each(&:to_i).join(",") + ")"
when "!*"
sql = sql + "issues.#{field} IS NULL"
when "*"
sql = sql + "issues.#{field} IS NOT NULL"
when "o"
sql = sql + "issue_statuses.is_closed=#{connection.quoted_false}" if field == "status_id"
when "c"
sql = sql + "issue_statuses.is_closed=#{connection.quoted_true}" if field == "status_id"
when ">t-"
sql = sql + "issues.#{field} >= '%s'" % connection.quoted_date(Date.today - v.first.to_i)
when "<t-"
sql = sql + "issues.#{field} <= '" + (Date.today - v.first.to_i).strftime("%Y-%m-%d") + "'"
when "t-"
sql = sql + "issues.#{field} = '" + (Date.today - v.first.to_i).strftime("%Y-%m-%d") + "'"
when ">t+"
sql = sql + "issues.#{field} >= '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
when "<t+"
sql = sql + "issues.#{field} <= '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
when "t+"
sql = sql + "issues.#{field} = '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
when "t"
sql = sql + "issues.#{field} = '%s'" % connection.quoted_date(Date.today)
when "~"
sql = sql + "issues.#{field} LIKE '%#{connection.quote_string(v.first)}%'"
when "!~"
sql = sql + "issues.#{field} NOT LIKE '%#{connection.quote_string(v.first)}%'"
def label_for(field)
label = available_filters[field][:name] if available_filters.has_key?(field)
label ||= field.gsub(/\_id$/, "")
end
def available_columns
return @available_columns if @available_columns
@available_columns = Query.available_columns
@available_columns += (project ?
project.all_issue_custom_fields :
IssueCustomField.find(:all, :conditions => {:is_for_all => true})
).collect {|cf| QueryCustomFieldColumn.new(cf) }
end
def columns
if has_default_columns?
available_columns.select {|c| Setting.issue_list_default_columns.include?(c.name.to_s) }
else
# preserve the column_names order
column_names.collect {|name| available_columns.find {|col| col.name == name}}.compact
end
end
def column_names=(names)
names = names.select {|n| n.is_a?(Symbol) || !n.blank? } if names
names = names.collect {|n| n.is_a?(Symbol) ? n : n.to_sym } if names
write_attribute(:column_names, names)
end
def has_column?(column)
column_names && column_names.include?(column.name)
end
def has_default_columns?
column_names.nil? || column_names.empty?
end
def project_statement
project_clauses = []
if project && !@project.active_children.empty?
ids = [project.id]
if has_filter?("subproject_id")
case operator_for("subproject_id")
when '='
# include the selected subprojects
ids += values_for("subproject_id").each(&:to_i)
when '!*'
# main project only
else
# all subprojects
ids += project.child_ids
end
elsif Setting.display_subprojects_issues?
ids += project.child_ids
end
project_clauses << "#{Project.table_name}.id IN (%s)" % ids.join(',')
elsif project
project_clauses << "#{Project.table_name}.id = %d" % project.id
end
project_clauses << Project.allowed_to_condition(User.current, :view_issues)
project_clauses.join(' AND ')
end
def statement
# filters clauses
filters_clauses = []
filters.each_key do |field|
next if field == "subproject_id"
v = values_for(field).clone
next unless v and !v.empty?
sql = ''
is_custom_filter = false
if field =~ /^cf_(\d+)$/
# custom field
db_table = CustomValue.table_name
db_field = 'value'
is_custom_filter = true
sql << "#{Issue.table_name}.id IN (SELECT #{Issue.table_name}.id FROM #{Issue.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{$1} WHERE "
else
# regular field
db_table = Issue.table_name
db_field = field
sql << '('
end
# "me" value subsitution
if %w(assigned_to_id author_id).include?(field)
v.push(User.current.logged? ? User.current.id.to_s : "0") if v.delete("me")
end
sql = sql + sql_for_field(field, v, db_table, db_field, is_custom_filter)
sql << ')'
filters_clauses << sql
end if filters and valid?
sql
(filters_clauses << project_statement).join(' AND ')
end
private
# Helper method to generate the WHERE sql for a +field+ with a +value+
def sql_for_field(field, value, db_table, db_field, is_custom_filter)
sql = ''
case operator_for field
when "="
sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
when "!"
sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
when "!*"
sql = "#{db_table}.#{db_field} IS NULL"
sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter
when "*"
sql = "#{db_table}.#{db_field} IS NOT NULL"
sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter
when ">="
sql = "#{db_table}.#{db_field} >= #{value.first.to_i}"
when "<="
sql = "#{db_table}.#{db_field} <= #{value.first.to_i}"
when "o"
sql = "#{IssueStatus.table_name}.is_closed=#{connection.quoted_false}" if field == "status_id"
when "c"
sql = "#{IssueStatus.table_name}.is_closed=#{connection.quoted_true}" if field == "status_id"
when ">t-"
sql = date_range_clause(db_table, db_field, - value.first.to_i, 0)
when "<t-"
sql = date_range_clause(db_table, db_field, nil, - value.first.to_i)
when "t-"
sql = date_range_clause(db_table, db_field, - value.first.to_i, - value.first.to_i)
when ">t+"
sql = date_range_clause(db_table, db_field, value.first.to_i, nil)
when "<t+"
sql = date_range_clause(db_table, db_field, 0, value.first.to_i)
when "t+"
sql = date_range_clause(db_table, db_field, value.first.to_i, value.first.to_i)
when "t"
sql = date_range_clause(db_table, db_field, 0, 0)
when "w"
from = l(:general_first_day_of_week) == '7' ?
# week starts on sunday
((Date.today.cwday == 7) ? Time.now.at_beginning_of_day : Time.now.at_beginning_of_week - 1.day) :
# week starts on monday (Rails default)
Time.now.at_beginning_of_week
sql = "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date(from), connection.quoted_date(from + 7.days)]
when "~"
sql = "#{db_table}.#{db_field} LIKE '%#{connection.quote_string(value.first)}%'"
when "!~"
sql = "#{db_table}.#{db_field} NOT LIKE '%#{connection.quote_string(value.first)}%'"
end
return sql
end
def add_custom_fields_filters(custom_fields)
@available_filters ||= {}
custom_fields.select(&:is_filter?).each do |field|
case field.field_format
when "text"
options = { :type => :text, :order => 20 }
when "list"
options = { :type => :list_optional, :values => field.possible_values, :order => 20}
when "date"
options = { :type => :date, :order => 20 }
when "bool"
options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
else
options = { :type => :string, :order => 20 }
end
@available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
end
end
# Returns a SQL clause for a date or datetime field.
def date_range_clause(table, field, from, to)
s = []
if from
s << ("#{table}.#{field} > '%s'" % [connection.quoted_date((Date.yesterday + from).to_time.end_of_day)])
end
if to
s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date((Date.today + to).to_time.end_of_day)])
end
s.join(' AND ')
end
end

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