summaryrefslogtreecommitdiffstats
path: root/redmine/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2006-07-29 09:32:58 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2006-07-29 09:32:58 +0000
commit310a0f924aa0092228a173cc71864af4ce574f1f (patch)
tree9885aa2d18d4cf99f6d00100e260bbe56cf255f5 /redmine/app
parent7e57db1edbad635fcbe1e3ae3294d24e1a43046f (diff)
downloadredmine-310a0f924aa0092228a173cc71864af4ce574f1f.tar.gz
redmine-310a0f924aa0092228a173cc71864af4ce574f1f.zip
0.3 unstable
git-svn-id: http://redmine.rubyforge.org/svn/trunk@12 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'redmine/app')
-rw-r--r--redmine/app/controllers/account_controller.rb141
-rw-r--r--redmine/app/controllers/application.rb63
-rw-r--r--redmine/app/controllers/auth_sources_controller.rb82
-rw-r--r--redmine/app/controllers/custom_fields_controller.rb57
-rw-r--r--redmine/app/controllers/documents_controller.rb2
-rw-r--r--redmine/app/controllers/issues_controller.rb44
-rw-r--r--redmine/app/controllers/projects_controller.rb230
-rw-r--r--redmine/app/controllers/users_controller.rb15
-rw-r--r--redmine/app/controllers/welcome_controller.rb9
-rw-r--r--redmine/app/helpers/application_helper.rb78
-rw-r--r--redmine/app/helpers/auth_sources_helper.rb19
-rw-r--r--redmine/app/helpers/custom_fields_helper.rb62
-rw-r--r--redmine/app/models/attachment.rb2
-rw-r--r--redmine/app/models/auth_source.rb47
-rw-r--r--redmine/app/models/auth_source_ldap.rb79
-rw-r--r--redmine/app/models/custom_field.rb38
-rw-r--r--redmine/app/models/custom_value.rb42
-rw-r--r--redmine/app/models/document.rb2
-rw-r--r--redmine/app/models/issue.rb12
-rw-r--r--redmine/app/models/issue_custom_field.rb27
-rw-r--r--redmine/app/models/mailer.rb46
-rw-r--r--redmine/app/models/news.rb2
-rw-r--r--redmine/app/models/permission.rb2
-rw-r--r--redmine/app/models/project.rb52
-rw-r--r--redmine/app/models/project_custom_field.rb22
-rw-r--r--redmine/app/models/token.rb44
-rw-r--r--redmine/app/models/tracker.rb3
-rw-r--r--redmine/app/models/user.rb49
-rw-r--r--redmine/app/models/user_custom_field.rb23
-rw-r--r--redmine/app/views/account/login.rhtml34
-rw-r--r--redmine/app/views/account/lost_password.rhtml14
-rw-r--r--redmine/app/views/account/my_account.rhtml36
-rw-r--r--redmine/app/views/account/my_page.rhtml17
-rw-r--r--redmine/app/views/account/password_recovery.rhtml21
-rw-r--r--redmine/app/views/account/register.rhtml46
-rw-r--r--redmine/app/views/account/show.rhtml8
-rw-r--r--redmine/app/views/admin/index.rhtml31
-rw-r--r--redmine/app/views/admin/info.rhtml4
-rw-r--r--redmine/app/views/admin/mail_options.rhtml12
-rw-r--r--redmine/app/views/admin/projects.rhtml18
-rw-r--r--redmine/app/views/auth_sources/_form.rhtml49
-rw-r--r--redmine/app/views/auth_sources/edit.rhtml7
-rw-r--r--redmine/app/views/auth_sources/list.rhtml32
-rw-r--r--redmine/app/views/auth_sources/new.rhtml6
-rw-r--r--redmine/app/views/custom_fields/_form.rhtml55
-rw-r--r--redmine/app/views/custom_fields/edit.rhtml6
-rw-r--r--redmine/app/views/custom_fields/list.rhtml29
-rw-r--r--redmine/app/views/custom_fields/new.rhtml7
-rw-r--r--redmine/app/views/documents/_form.rhtml10
-rw-r--r--redmine/app/views/documents/show.rhtml2
-rw-r--r--redmine/app/views/issues/change_status.rhtml5
-rw-r--r--redmine/app/views/issues/edit.rhtml27
-rw-r--r--redmine/app/views/issues/show.rhtml11
-rw-r--r--redmine/app/views/layouts/base.rhtml97
-rw-r--r--redmine/app/views/mailer/_issue.rhtml4
-rw-r--r--redmine/app/views/mailer/issue_add_en.rhtml (renamed from redmine/app/views/mailer/issue_add.rhtml)0
-rw-r--r--redmine/app/views/mailer/issue_add_fr.rhtml3
-rw-r--r--redmine/app/views/mailer/issue_change_status_en.rhtml (renamed from redmine/app/views/mailer/issue_change_status.rhtml)0
-rw-r--r--redmine/app/views/mailer/issue_change_status_fr.rhtml3
-rw-r--r--redmine/app/views/mailer/lost_password_en.rhtml3
-rw-r--r--redmine/app/views/mailer/lost_password_fr.rhtml3
-rw-r--r--redmine/app/views/mailer/register_en.rhtml3
-rw-r--r--redmine/app/views/mailer/register_fr.rhtml3
-rw-r--r--redmine/app/views/news/_form.rhtml8
-rw-r--r--redmine/app/views/news/show.rhtml4
-rw-r--r--redmine/app/views/projects/_form.rhtml17
-rw-r--r--redmine/app/views/projects/add.rhtml1
-rw-r--r--redmine/app/views/projects/add_document.rhtml4
-rw-r--r--redmine/app/views/projects/add_issue.rhtml33
-rw-r--r--redmine/app/views/projects/changelog.rhtml2
-rw-r--r--redmine/app/views/projects/list.rhtml2
-rw-r--r--redmine/app/views/projects/list_documents.rhtml2
-rw-r--r--redmine/app/views/projects/list_issues.rhtml8
-rw-r--r--redmine/app/views/projects/list_news.rhtml2
-rw-r--r--redmine/app/views/projects/settings.rhtml6
-rw-r--r--redmine/app/views/projects/show.rhtml21
-rw-r--r--redmine/app/views/roles/_form.rhtml5
-rw-r--r--redmine/app/views/trackers/_form.rhtml2
-rw-r--r--redmine/app/views/users/_form.rhtml24
-rw-r--r--redmine/app/views/users/list.rhtml6
-rw-r--r--redmine/app/views/versions/_form.rhtml4
-rw-r--r--redmine/app/views/welcome/index.rhtml9
82 files changed, 1471 insertions, 589 deletions
diff --git a/redmine/app/controllers/account_controller.rb b/redmine/app/controllers/account_controller.rb
index 54e0ef704..b156bfd5b 100644
--- a/redmine/app/controllers/account_controller.rb
+++ b/redmine/app/controllers/account_controller.rb
@@ -17,11 +17,14 @@
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
- before_filter :require_login, :except => [:show, :login]
+ skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register]
+ before_filter :require_login, :except => [:show, :login, :lost_password, :register]
+ # Show user's account
def show
@user = User.find(params[:id])
end
@@ -29,49 +32,123 @@ class AccountController < ApplicationController
# Login request and validation
def login
if request.get?
- session[:user] = nil
+ # Logout user
+ self.logged_in_user = nil
else
- logged_in_user = User.try_to_login(params[:login], params[:password])
- if logged_in_user
- session[:user] = logged_in_user
+ # Authenticate user
+ user = User.try_to_login(params[:login], params[:password])
+ if user
+ self.logged_in_user = user
redirect_back_or_default :controller => 'account', :action => 'my_page'
else
- flash[:notice] = _('Invalid user/password')
+ flash[:notice] = l(:notice_account_invalid_creditentials)
end
end
end
-
- # Log out current user and redirect to welcome page
- def logout
- session[:user] = nil
- redirect_to(:controller => '')
- end
- def my_page
- @user = session[:user]
- @reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
- @assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
- end
-
- # Edit current user's account
- def my_account
- @user = User.find(session[:user].id)
- if request.post? and @user.update_attributes(@params[:user])
- flash[:notice] = 'Account was successfully updated.'
- session[:user] = @user
+ # Log out current user and redirect to welcome page
+ def logout
+ self.logged_in_user = nil
+ redirect_to :controller => ''
+ end
+
+ # Show logged in user's page
+ def my_page
+ @user = self.logged_in_user
+ @reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
+ @assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
+ end
+
+ # Edit logged in user's account
+ def my_account
+ @user = self.logged_in_user
+ if request.post? and @user.update_attributes(@params[:user])
set_localization
- end
- end
+ flash[:notice] = l(:notice_account_updated)
+ self.logged_in_user.reload
+ end
+ end
- # Change current user's password
+ # Change logged in user's password
def change_password
- @user = User.find(session[:user].id)
+ @user = self.logged_in_user
if @user.check_password?(@params[:password])
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
- flash[:notice] = 'Password was successfully updated.' if @user.save
+ flash[:notice] = l(:notice_account_password_updated) if @user.save
else
- flash[:notice] = 'Wrong password'
+ flash[:notice] = l(:notice_account_wrong_password)
end
render :action => 'my_account'
- end
+ end
+
+ # Enable user to choose a new password
+ def lost_password
+ if params[:token]
+ @token = Token.find_by_action_and_value("recovery", params[:token])
+ redirect_to :controller => '' 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])
+ flash[:notice] = l(:notice_account_unknown_email) and return unless user
+ token = Token.new(:user => user, :action => "recovery")
+ if token.save
+ Mailer.set_language_if_valid(Localization.lang)
+ 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 => '' and return if $RDM_SELF_REGISTRATION == false
+ if params[:token]
+ token = Token.find_by_action_and_value("register", params[:token])
+ redirect_to :controller => '' and return unless token and !token.expired?
+ user = token.user
+ redirect_to :controller => '' 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 => $RDM_DEFAULT_LANG)
+ @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.set_language_if_valid(Localization.lang)
+ Mailer.deliver_register(token)
+ flash[:notice] = l(:notice_account_register_done)
+ redirect_to :controller => ''
+ end
+ end
+ end
+ end
end
diff --git a/redmine/app/controllers/application.rb b/redmine/app/controllers/application.rb
index 9cc37cfa9..adae23550 100644
--- a/redmine/app/controllers/application.rb
+++ b/redmine/app/controllers/application.rb
@@ -18,43 +18,59 @@
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], :include => :memberships)
+ else
+ nil
+ end
+ end
+
# check if login is globally required to access the application
def check_if_login_required
- require_login if RDM_LOGIN_REQUIRED
+ require_login if $RDM_LOGIN_REQUIRED
end
def set_localization
Localization.lang = begin
- if session[:user]
- session[:user].language
+ if self.logged_in_user and Localization.langs.keys.include? self.logged_in_user.language
+ self.logged_in_user.language
elsif request.env['HTTP_ACCEPT_LANGUAGE']
accept_lang = HTTPUtils.parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first
- if Localization.langs.collect{ |l| l[1] }.include? accept_lang
+ if Localization.langs.keys.include? accept_lang
accept_lang
end
end
rescue
nil
- end || RDM_DEFAULT_LANG
+ end || $RDM_DEFAULT_LANG
+
+ set_language_if_valid(Localization.lang)
+
end
def require_login
- unless session[:user]
+ unless self.logged_in_user
store_location
redirect_to(:controller => "account", :action => "login")
+ return false
end
+ true
end
def require_admin
- if session[:user].nil?
- store_location
- redirect_to(:controller => "account", :action => "login")
- else
- unless session[:user].admin?
- flash[:notice] = "Acces not allowed"
- redirect_to(:controller => "projects", :action => "list")
- end
+ return unless require_login
+ unless self.logged_in_user.admin?
+ flash[:notice] = "Acces denied"
+ redirect_to:controller => ''
+ return false
end
+ true
end
# authorizes the user for the requested action.
@@ -62,19 +78,18 @@ class ApplicationController < ActionController::Base
# check if action is allowed on public projects
if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ @params[:controller], @params[:action] ]
return true
- end
- # if user not logged in, redirect to login form
- unless session[:user]
- store_location
- redirect_to(:controller => "account", :action => "login")
- return false
- end
- # if logged in, check if authorized
- if session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], session[:user].role_for_project(@project.id) )
+ 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" % [ @params[:controller], @params[:action] ], @user_membership.role_id )
return true
end
flash[:notice] = "Acces denied"
- redirect_to(:controller => "")
+ redirect_to :controller => ''
false
end
diff --git a/redmine/app/controllers/auth_sources_controller.rb b/redmine/app/controllers/auth_sources_controller.rb
new file mode 100644
index 000000000..fe8536f99
--- /dev/null
+++ b/redmine/app/controllers/auth_sources_controller.rb
@@ -0,0 +1,82 @@
+# 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 AuthSourcesController < ApplicationController
+ layout 'base'
+ before_filter :require_admin
+
+ def index
+ list
+ render :action => 'list'
+ end
+
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
+ verify :method => :post, :only => [ :destroy, :create, :update ],
+ :redirect_to => { :action => :list }
+
+ def list
+ @auth_source_pages, @auth_sources = paginate :auth_sources, :per_page => 10
+ end
+
+ def new
+ @auth_source = AuthSourceLdap.new
+ end
+
+ def create
+ @auth_source = AuthSourceLdap.new(params[:auth_source])
+ if @auth_source.save
+ flash[:notice] = l(:notice_successful_create)
+ redirect_to :action => 'list'
+ else
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ @auth_source = AuthSource.find(params[:id])
+ end
+
+ def update
+ @auth_source = AuthSource.find(params[:id])
+ if @auth_source.update_attributes(params[:auth_source])
+ flash[:notice] = l(:notice_successful_update)
+ redirect_to :action => 'list'
+ else
+ render :action => 'edit'
+ end
+ end
+
+ def test_connection
+ @auth_method = AuthSource.find(params[:id])
+ begin
+ @auth_method.test_connection
+ rescue => text
+ flash[:notice] = text
+ end
+ flash[:notice] ||= l(:notice_successful_connection)
+ redirect_to :action => 'list'
+ end
+
+ def destroy
+ @auth_source = AuthSource.find(params[:id])
+ unless @auth_source.users.find(:first)
+ @auth_source.destroy
+ flash[:notice] = l(:notice_successful_delete)
+ end
+ redirect_to :action => 'list'
+ end
+end
diff --git a/redmine/app/controllers/custom_fields_controller.rb b/redmine/app/controllers/custom_fields_controller.rb
index 93f6353fa..57430743d 100644
--- a/redmine/app/controllers/custom_fields_controller.rb
+++ b/redmine/app/controllers/custom_fields_controller.rb
@@ -16,37 +16,48 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class CustomFieldsController < ApplicationController
- layout 'base'
- before_filter :require_admin
-
+ layout 'base'
+ before_filter :require_admin
+
def index
list
render :action => 'list'
end
def list
- @custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 10
+ @custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 15
end
-
+
def new
- if request.get?
- @custom_field = CustomField.new
- else
- @custom_field = CustomField.new(params[:custom_field])
- if @custom_field.save
- flash[:notice] = 'CustomField was successfully created.'
- redirect_to :action => 'list'
+ 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
+ redirect_to :action => 'list'
+ end
+ @trackers = Tracker.find(:all)
+ 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
- end
- end
-
- def edit
- @custom_field = CustomField.find(params[:id])
- if request.post? and @custom_field.update_attributes(params[:custom_field])
- flash[:notice] = 'CustomField was successfully updated.'
- redirect_to :action => 'list'
- end
- end
+ flash[:notice] = 'Custom field was successfully updated.'
+ redirect_to :action => 'list'
+ end
+ @trackers = Tracker.find(:all)
+ end
def destroy
CustomField.find(params[:id]).destroy
@@ -54,5 +65,5 @@ class CustomFieldsController < ApplicationController
rescue
flash[:notice] = "Unable to delete custom field"
redirect_to :action => 'list'
- end
+ end
end
diff --git a/redmine/app/controllers/documents_controller.rb b/redmine/app/controllers/documents_controller.rb
index 3c76465c9..cc30f8e1e 100644
--- a/redmine/app/controllers/documents_controller.rb
+++ b/redmine/app/controllers/documents_controller.rb
@@ -45,7 +45,7 @@ class DocumentsController < ApplicationController
# Save the attachment
if params[:attachment][:file].size > 0
@attachment = @document.attachments.build(params[:attachment])
- @attachment.author_id = session[:user].id unless session[:user].nil?
+ @attachment.author_id = self.logged_in_user.id if self.logged_in_user
@attachment.save
end
render :action => 'show'
diff --git a/redmine/app/controllers/issues_controller.rb b/redmine/app/controllers/issues_controller.rb
index 5d5872f39..fa97e7c1c 100644
--- a/redmine/app/controllers/issues_controller.rb
+++ b/redmine/app/controllers/issues_controller.rb
@@ -23,21 +23,21 @@ class IssuesController < ApplicationController
include CustomFieldsHelper
def show
- @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user]
+ @status_options = @issue.status.workflows.find(:all, :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)
end
- def edit
- @trackers = Tracker.find(:all)
+ def edit
@priorities = Enumeration::get_values('IPRI')
if request.get?
- @custom_values = @project.custom_fields_for_issues.collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
+ @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
# Retrieve custom fields and values
- @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
-
+ @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
- if @issue.update_attributes(params[:issue])
+ @issue.attributes = params[:issue]
+ if @issue.save
flash[:notice] = 'Issue was successfully updated.'
redirect_to :action => 'show', :id => @issue
end
@@ -46,12 +46,11 @@ class IssuesController < ApplicationController
def change_status
@history = @issue.histories.build(params[:history])
- @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user]
+ @status_options = @issue.status.workflows.find(:all, :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
if params[:confirm]
- unless session[:user].nil?
- @history.author = session[:user]
- end
+ @history.author_id = self.logged_in_user.id if self.logged_in_user
+
if @history.save
@issue.status = @history.status
@issue.fixed_version_id = (params[:issue][:fixed_version_id])
@@ -76,7 +75,7 @@ class IssuesController < ApplicationController
# Save the attachment
if params[:attachment][:file].size > 0
@attachment = @issue.attachments.build(params[:attachment])
- @attachment.author_id = session[:user].id unless session[:user].nil?
+ @attachment.author_id = self.logged_in_user.id if self.logged_in_user
@attachment.save
end
redirect_to :action => 'show', :id => @issue
@@ -86,17 +85,16 @@ class IssuesController < ApplicationController
@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
- end
-
+
+ # Send the file in stream mode
+ def download
+ @attachment = @issue.attachments.find(params[:attachment_id])
+ send_file @attachment.diskfile, :filename => @attachment.filename
+ end
+
private
- def find_project
+ def find_project
@issue = Issue.find(params[:id])
- @project = @issue.project
- end
-
+ @project = @issue.project
+ end
end
diff --git a/redmine/app/controllers/projects_controller.rb b/redmine/app/controllers/projects_controller.rb
index 2bef221b1..3c4d806b5 100644
--- a/redmine/app/controllers/projects_controller.rb
+++ b/redmine/app/controllers/projects_controller.rb
@@ -48,11 +48,15 @@ class ProjectsController < ApplicationController
# Add a new project
def add
- @custom_fields = CustomField::find_all
- @root_projects = Project::find(:all, :conditions => "parent_id is null")
+ @custom_fields = IssueCustomField.find(:all)
+ @root_projects = Project.find(:all, :conditions => "parent_id is null")
@project = Project.new(params[:project])
- if request.post?
- @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
+ 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 @project.save
flash[:notice] = 'Project was successfully created.'
redirect_to :controller => 'admin', :action => 'projects'
@@ -60,26 +64,33 @@ class ProjectsController < ApplicationController
end
end
- # Show @project
+ # 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_count > 0
- @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
+ @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
+ @trackers = Tracker.find(:all)
end
def settings
@root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
- @custom_fields = CustomField::find_all
+ @custom_fields = IssueCustomField::find_all
@issue_category ||= IssueCategory.new
@member ||= @project.members.new
@roles = Role.find_all
@users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
+ @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 = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
+ @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 @project.update_attributes(params[:project])
flash[:notice] = 'Project was successfully updated.'
redirect_to :action => 'settings', :id => @project
@@ -89,102 +100,101 @@ class ProjectsController < ApplicationController
end
end
end
-
- # Delete @project
- def destroy
+
+ # Delete @project
+ def destroy
if request.post? and params[:confirm]
@project.destroy
redirect_to :controller => 'admin', :action => 'projects'
end
- 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
- redirect_to :action => 'settings', :id => @project
- else
+ # 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
+ redirect_to :action => 'settings', :id => @project
+ else
settings
render :action => 'settings'
- end
- end
- 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
+ # Add a new version to @project
+ def add_version
+ @version = @project.versions.build(params[:version])
+ if request.post? and @version.save
redirect_to :action => 'settings', :id => @project
- end
- end
+ end
+ end
- # Add a new member to @project
- def add_member
+ # Add a new member to @project
+ def add_member
@member = @project.members.build(params[:member])
- if request.post?
- if @member.save
+ if request.post?
+ if @member.save
flash[:notice] = 'Member was successfully added.'
- redirect_to :action => 'settings', :id => @project
- else
+ redirect_to :action => 'settings', :id => @project
+ else
settings
render :action => 'settings'
end
- end
- end
+ end
+ end
- # Show members list of @project
- def list_members
- @members = @project.members
- end
+ # Show members list of @project
+ def list_members
+ @members = @project.members
+ end
- # Add a new document to @project
- def add_document
- @categories = Enumeration::get_values('DCAT')
- @document = @project.documents.build(params[:document])
- if request.post?
+ # Add a new document to @project
+ def add_document
+ @categories = Enumeration::get_values('DCAT')
+ @document = @project.documents.build(params[:document])
+ if request.post?
# Save the attachment
- if params[:attachment][:file].size > 0
- @attachment = @document.attachments.build(params[:attachment])
- @attachment.author_id = session[:user].id unless session[:user].nil?
- end
- if @document.save
- redirect_to :action => 'list_documents', :id => @project
- end
- end
- end
-
- # Show documents list of @project
- def list_documents
- @documents = @project.documents
- end
+ if params[:attachment][:file].size > 0
+ @attachment = @document.attachments.build(params[:attachment])
+ @attachment.author_id = self.logged_in_user.id if self.logged_in_user
+ end
+ if @document.save
+ redirect_to :action => 'list_documents', :id => @project
+ end
+ end
+ end
+
+ # Show documents list of @project
+ def list_documents
+ @documents = @project.documents
+ end
- # Add a new issue to @project
- def add_issue
- @trackers = Tracker.find(:all)
- @priorities = Enumeration::get_values('IPRI')
- if request.get?
- @issue = @project.issues.build
- @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x) }
- else
- # Create the issue and set the author
- @issue = @project.issues.build(params[:issue])
- @issue.author = session[:user] unless session[:user].nil?
- # Create the document if a file was sent
- if params[:attachment][:file].size > 0
- @attachment = @issue.attachments.build(params[:attachment])
- @attachment.author_id = session[:user].id unless session[:user].nil?
- end
- @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
- @issue.custom_values = @custom_values
- if @issue.save
+ # 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?
+ @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
+ # Create the document if a file was sent
+ if params[:attachment][:file].size > 0
+ @attachment = @issue.attachments.build(params[:attachment])
+ @attachment.author_id = self.logged_in_user.id if self.logged_in_user
+ end
+ @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
flash[:notice] = "Issue was successfully added."
- 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
-
+ 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'
@@ -195,11 +205,11 @@ class ProjectsController < ApplicationController
@issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
@issue_pages = Paginator.new self, @issue_count, 15, @params['page']
- @issues = Issue.find :all, :order => sort_clause,
+ @issues = Issue.find :all, :order => sort_clause,
:include => [ :author, :status, :tracker, :project ],
:conditions => search_filter_clause,
:limit => @issue_pages.items_per_page,
- :offset => @issue_pages.current.offset
+ :offset => @issue_pages.current.offset
end
# Export filtered/sorted issues list to CSV
@@ -225,29 +235,30 @@ class ProjectsController < ApplicationController
:type => 'text/csv; charset=utf-8; header=present',
:filename => 'export.csv')
end
-
- # Add a news to @project
- def add_news
- @news = @project.news.build(params[:news])
- if request.post?
- @news.author = session[:user] unless session[:user].nil?
- if @news.save
- redirect_to :action => 'list_news', :id => @project
- end
- end
- end
- # Show news list of @project
+ # 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
+ 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"
end
-
+
def add_file
if request.post?
# Save the attachment
if params[:attachment][:file].size > 0
@attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
- @attachment.author_id = session[:user].id unless session[:user].nil?
+ @attachment.author_id = self.logged_in_user.id if self.logged_in_user
if @attachment.save
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
end
@@ -269,14 +280,13 @@ class ProjectsController < ApplicationController
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
- flash[:notice] = 'Project not found.'
- redirect_to :action => 'list'
- end
-
+ # 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
+ flash[:notice] = 'Project not found.'
+ redirect_to :action => 'list'
+ end
end
diff --git a/redmine/app/controllers/users_controller.rb b/redmine/app/controllers/users_controller.rb
index 3a6042718..758afc2d8 100644
--- a/redmine/app/controllers/users_controller.rb
+++ b/redmine/app/controllers/users_controller.rb
@@ -21,6 +21,8 @@ class UsersController < ApplicationController
helper :sort
include SortHelper
+ helper :custom_fields
+ include CustomFieldsHelper
def index
list
@@ -41,12 +43,15 @@ class UsersController < ApplicationController
def add
if request.get?
- @user = User.new
+ @user = User.new(:language => $RDM_DEFAULT_LANG)
+ @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
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]
+ @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
if @user.save
flash[:notice] = 'User was successfully created.'
redirect_to :action => 'list'
@@ -56,10 +61,16 @@ class UsersController < ApplicationController
def edit
@user = User.find(params[:id])
- if request.post?
+ 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?
+ 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])
flash[:notice] = 'User was successfully updated.'
redirect_to :action => 'list'
diff --git a/redmine/app/controllers/welcome_controller.rb b/redmine/app/controllers/welcome_controller.rb
index b266975aa..c47198d51 100644
--- a/redmine/app/controllers/welcome_controller.rb
+++ b/redmine/app/controllers/welcome_controller.rb
@@ -16,11 +16,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class WelcomeController < ApplicationController
- layout 'base'
-
- def index
+ layout 'base'
+
+ def index
@news = News.latest
@projects = Project.latest
- end
-
+ end
end
diff --git a/redmine/app/helpers/application_helper.rb b/redmine/app/helpers/application_helper.rb
index de53f2ad6..ddb846073 100644
--- a/redmine/app/helpers/application_helper.rb
+++ b/redmine/app/helpers/application_helper.rb
@@ -17,35 +17,38 @@
module ApplicationHelper
- def loggedin?
- session[:user]
- end
+ # return current logged in user or nil
+ def loggedin?
+ @logged_in_user
+ end
+
+ # return true if user is loggend in and is admin, otherwise false
+ def admin_loggedin?
+ @logged_in_user and @logged_in_user.admin?
+ end
- def admin_loggedin?
- session[:user] && session[:user].admin
- end
-
- def authorize_for(controller, action)
+ 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
+ end
# check if user is authorized
- if session[:user] and (session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], session[:user].role_for_project(@project.id) ) )
- return true
- end
- return false
- end
-
- 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
-
+ 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 format_date(date)
_('(date)', date) if date
end
@@ -61,5 +64,30 @@ module ApplicationHelper
html << ' ' + link_to((_('Next') + ' &#187;'), { :page => paginator.current.next }) if paginator.current.next
html
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)
+ end
+ end
+ content_tag("div",
+ content_tag(
+ options[:header_tag] || "h2", lwr(:gui_validation_error, object.errors.count) + " :"
+ ) +
+ content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
+ "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
+ )
+ else
+ ""
+ end
+ end
end
diff --git a/redmine/app/helpers/auth_sources_helper.rb b/redmine/app/helpers/auth_sources_helper.rb
new file mode 100644
index 000000000..d47e9856a
--- /dev/null
+++ b/redmine/app/helpers/auth_sources_helper.rb
@@ -0,0 +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 AuthSourcesHelper
+end
diff --git a/redmine/app/helpers/custom_fields_helper.rb b/redmine/app/helpers/custom_fields_helper.rb
index 4e3aea50f..10cb1bb94 100644
--- a/redmine/app/helpers/custom_fields_helper.rb
+++ b/redmine/app/helpers/custom_fields_helper.rb
@@ -16,21 +16,49 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module CustomFieldsHelper
- def custom_field_tag(custom_value)
-
- custom_field = custom_value.custom_field
-
- field_name = "custom_fields[#{custom_field.id}]"
-
- case custom_field.typ
- when 0 .. 2
- text_field_tag field_name, custom_value.value
- when 3
- check_box field_name
- when 4
- select_tag field_name,
- options_for_select(custom_field.possible_values.split('|'),
- custom_value.value)
- end
- end
+
+ def custom_field_tag(custom_value)
+ custom_field = custom_value.custom_field
+ field_name = "custom_fields[#{custom_field.id}]"
+ case custom_field.field_format
+ when "string", "int", "date"
+ text_field_tag field_name, custom_value.value
+ when "text"
+ text_area_tag field_name, custom_value.value, :cols => 60, :rows => 3
+ when "bool"
+ check_box_tag(field_name, "1", custom_value.value == "1") +
+ hidden_field_tag(field_name, "0")
+ when "list"
+ select_tag field_name,
+ "<option></option>" + options_for_select(custom_field.possible_values.split('|'),
+ custom_value.value)
+ end
+ end
+
+ 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>" : "")
+ end
+
+ def custom_field_tag_with_label(custom_value)
+ case custom_value.custom_field.field_format
+ when "bool"
+ custom_field_tag(custom_value) + " " + custom_field_label_tag(custom_value)
+ else
+ custom_field_label_tag(custom_value) + "<br />" + custom_field_tag(custom_value)
+ end
+ end
+
+ def show_value(custom_value)
+ case custom_value.custom_field.field_format
+ when "bool"
+ l_YesNo(custom_value.value == "1")
+ else
+ custom_value.value
+ end
+ end
+
+ def custom_field_formats_for_select
+ CustomField::FIELD_FORMATS.keys.collect { |k| [ l(CustomField::FIELD_FORMATS[k]), k ] }
+ end
end
diff --git a/redmine/app/models/attachment.rb b/redmine/app/models/attachment.rb
index 1e5bd22b4..2e1e9b156 100644
--- a/redmine/app/models/attachment.rb
+++ b/redmine/app/models/attachment.rb
@@ -55,7 +55,7 @@ class Attachment < ActiveRecord::Base
# Returns file's location on disk
def diskfile
- "#{RDM_STORAGE_PATH}/#{self.disk_filename}"
+ "#{$RDM_STORAGE_PATH}/#{self.disk_filename}"
end
def increment_download
diff --git a/redmine/app/models/auth_source.rb b/redmine/app/models/auth_source.rb
new file mode 100644
index 000000000..47eec106d
--- /dev/null
+++ b/redmine/app/models/auth_source.rb
@@ -0,0 +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.
+
+class AuthSource < ActiveRecord::Base
+ has_many :users
+
+ validates_presence_of :name
+ validates_uniqueness_of :name
+
+ def authenticate(login, password)
+ end
+
+ def test_connection
+ end
+
+ def auth_method_name
+ "Abstract"
+ end
+
+ # Try to authenticate a user not yet registered against available sources
+ def self.authenticate(login, password)
+ AuthSource.find(:all, :conditions => ["onthefly_register=?", true]).each do |source|
+ begin
+ logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
+ attrs = source.authenticate(login, password)
+ rescue
+ attrs = nil
+ end
+ return attrs if attrs
+ end
+ return nil
+ end
+end
diff --git a/redmine/app/models/auth_source_ldap.rb b/redmine/app/models/auth_source_ldap.rb
new file mode 100644
index 000000000..9579a1094
--- /dev/null
+++ b/redmine/app/models/auth_source_ldap.rb
@@ -0,0 +1,79 @@
+# 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", "organizationalPerson" )
+ 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]
+ end
+end
diff --git a/redmine/app/models/custom_field.rb b/redmine/app/models/custom_field.rb
index 9e817d1ef..924a874a3 100644
--- a/redmine/app/models/custom_field.rb
+++ b/redmine/app/models/custom_field.rb
@@ -16,23 +16,27 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class CustomField < ActiveRecord::Base
+ has_many :custom_values, :dependent => true
- has_and_belongs_to_many :projects
- has_many :custom_values, :dependent => true
- has_many :issues, :through => :issue_custom_values
+ FIELD_FORMATS = { "list" => :label_list,
+ "date" => :label_date,
+ "bool" => :label_boolean,
+ "int" => :label_integer,
+ "string" => :label_string,
+ "text" => :label_text
+ }.freeze
- validates_presence_of :name, :typ
- validates_uniqueness_of :name
+ validates_presence_of :name, :field_format
+ validates_uniqueness_of :name
+ validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
+ validates_presence_of :possible_values, :if => Proc.new { |field| field.field_format == "list" }
- TYPES = [
- [ "Integer", 0 ],
- [ "String", 1 ],
- [ "Date", 2 ],
- [ "Boolean", 3 ],
- [ "List", 4 ]
- ].freeze
-
- def self.for_all
- find(:all, :conditions => ["is_for_all=?", true])
- end
-end
+ # to move in project_custom_field
+ def self.for_all
+ find(:all, :conditions => ["is_for_all=?", true])
+ end
+
+ def type_name
+ nil
+ end
+end
diff --git a/redmine/app/models/custom_value.rb b/redmine/app/models/custom_value.rb
index faaa8ff82..ac72e5aba 100644
--- a/redmine/app/models/custom_value.rb
+++ b/redmine/app/models/custom_value.rb
@@ -16,26 +16,28 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class CustomValue < ActiveRecord::Base
- belongs_to :issue
- belongs_to :custom_field
-
+ belongs_to :custom_field
+ belongs_to :customized, :polymorphic => true
+
protected
def validate
- errors.add(custom_field.name, "can't be blank") if custom_field.is_required? and value.empty?
- errors.add(custom_field.name, "is not valid") unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
-
- case custom_field.typ
- when 0
- errors.add(custom_field.name, "must be an integer") unless value =~ /^[0-9]*$/
- when 1
- errors.add(custom_field.name, "is too short") if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
- errors.add(custom_field.name, "is too long") if custom_field.max_length > 0 and value.length > custom_field.max_length
- when 2
- errors.add(custom_field.name, "must be a valid date") unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty?
- when 3
-
- when 4
- errors.add(custom_field.name, "is not a valid value") unless custom_field.possible_values.split('|').include? value or value.empty?
- end
+ # errors are added to customized object unless it's nil
+ object = customized || self
+
+ object.errors.add(custom_field.name, :activerecord_error_blank) if custom_field.is_required? and value.empty?
+ object.errors.add(custom_field.name, :activerecord_error_invalid) unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
+
+ object.errors.add(custom_field.name, :activerecord_error_too_short) if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
+ object.errors.add(custom_field.name, :activerecord_error_too_long) if custom_field.max_length > 0 and value.length > custom_field.max_length
+
+ case custom_field.field_format
+ when "int"
+ object.errors.add(custom_field.name, :activerecord_error_not_a_number) unless value =~ /^[0-9]*$/
+ when "date"
+ object.errors.add(custom_field.name, :activerecord_error_invalid) unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty?
+ when "list"
+ object.errors.add(custom_field.name, :activerecord_error_inclusion) unless custom_field.possible_values.split('|').include? value or value.empty?
+ end
end
-end
+end
+
diff --git a/redmine/app/models/document.rb b/redmine/app/models/document.rb
index 40c3a1656..08e0ef607 100644
--- a/redmine/app/models/document.rb
+++ b/redmine/app/models/document.rb
@@ -20,5 +20,5 @@ class Document < ActiveRecord::Base
belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
has_many :attachments, :as => :container, :dependent => true
- validates_presence_of :title
+ validates_presence_of :project, :title, :category
end
diff --git a/redmine/app/models/issue.rb b/redmine/app/models/issue.rb
index 4a21ac03b..dc5b3fd84 100644
--- a/redmine/app/models/issue.rb
+++ b/redmine/app/models/issue.rb
@@ -29,15 +29,19 @@ class Issue < ActiveRecord::Base
has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
has_many :attachments, :as => :container, :dependent => true
- has_many :custom_values, :dependent => true
+ has_many :custom_values, :dependent => true, :as => :customized
has_many :custom_fields, :through => :custom_values
- validates_presence_of :subject, :descr, :priority, :tracker, :author
+ validates_presence_of :subject, :description, :priority, :tracker, :author
+ validates_associated :custom_values, :on => :update
# set default status for new issues
+ def before_validation
+ self.status = IssueStatus.default if new_record?
+ end
+
def before_create
- self.status = IssueStatus.default
- build_history
+ build_history
end
def long_id
diff --git a/redmine/app/models/issue_custom_field.rb b/redmine/app/models/issue_custom_field.rb
new file mode 100644
index 000000000..209ae206b
--- /dev/null
+++ b/redmine/app/models/issue_custom_field.rb
@@ -0,0 +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
+
diff --git a/redmine/app/models/mailer.rb b/redmine/app/models/mailer.rb
index b04ec7ebc..bf4c85dbb 100644
--- a/redmine/app/models/mailer.rb
+++ b/redmine/app/models/mailer.rb
@@ -17,20 +17,34 @@
class Mailer < ActionMailer::Base
- def issue_change_status(issue)
- # Sends to all project members
- @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
- @from = 'redmine@somenet.foo'
- @subject = "Issue ##{issue.id} has been updated"
- @body['issue'] = issue
- end
-
- def issue_add(issue)
- # Sends to all project members
- @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
- @from = 'redmine@somenet.foo'
- @subject = "Issue ##{issue.id} has been reported"
- @body['issue'] = issue
- end
-
+ def issue_change_status(issue)
+ # Sends to all project members
+ @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
+ @from = 'redmine@somenet.foo'
+ @subject = "Issue ##{issue.id} has been updated"
+ @body['issue'] = issue
+ end
+
+ def issue_add(issue)
+ # Sends to all project members
+ @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
+ @from = 'redmine@somenet.foo'
+ @subject = "Issue ##{issue.id} has been reported"
+ @body['issue'] = issue
+ end
+
+ def lost_password(token)
+ @recipients = token.user.mail
+ @from = 'redmine@somenet.foo'
+ @subject = "redMine password"
+ @body['token'] = token
+ end
+
+ def register(token)
+ @recipients = token.user.mail
+ @from = 'redmine@somenet.foo'
+ @subject = "redMine account activation"
+ @body['token'] = token
+ end
+
end
diff --git a/redmine/app/models/news.rb b/redmine/app/models/news.rb
index 0642a4bf5..c4884ace5 100644
--- a/redmine/app/models/news.rb
+++ b/redmine/app/models/news.rb
@@ -19,7 +19,7 @@ class News < ActiveRecord::Base
belongs_to :project
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
- validates_presence_of :title, :shortdescr, :descr
+ validates_presence_of :title, :description
# returns last created news
def self.latest
diff --git a/redmine/app/models/permission.rb b/redmine/app/models/permission.rb
index e05ca0fba..164ca21b9 100644
--- a/redmine/app/models/permission.rb
+++ b/redmine/app/models/permission.rb
@@ -18,7 +18,7 @@
class Permission < ActiveRecord::Base
has_and_belongs_to_many :roles
- validates_presence_of :controller, :action, :descr
+ validates_presence_of :controller, :action, :description
GROUPS = {
100 => "Project",
diff --git a/redmine/app/models/project.rb b/redmine/app/models/project.rb
index e5b5779cb..ee848cb30 100644
--- a/redmine/app/models/project.rb
+++ b/redmine/app/models/project.rb
@@ -16,30 +16,34 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Project < ActiveRecord::Base
- has_many :versions, :dependent => true, :order => "versions.effective_date DESC"
- has_many :members, :dependent => true
- has_many :users, :through => :members
- has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
- has_many :documents, :dependent => true
- has_many :news, :dependent => true, :include => :author
- has_many :issue_categories, :dependent => true
- has_and_belongs_to_many :custom_fields
- acts_as_tree :order => "name", :counter_cache => true
-
- validates_presence_of :name, :descr
- validates_uniqueness_of :name
-
- # returns 5 last created projects
- def self.latest
- find(:all, :limit => 5, :order => "created_on DESC")
- 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
- (CustomField.for_all + custom_fields).uniq
- end
-
+ has_many :versions, :dependent => true, :order => "versions.effective_date DESC, versions.name DESC"
+ has_many :members, :dependent => true
+ has_many :users, :through => :members
+ has_many :custom_values, :dependent => true, :as => :customized
+ has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
+ has_many :documents, :dependent => true
+ has_many :news, :dependent => true, :include => :author
+ has_many :issue_categories, :dependent => true, :order => "issue_categories.name"
+ 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
+
+ # returns 5 last created projects
+ def self.latest
+ find(:all, :limit => 5, :order => "created_on DESC")
+ 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
+
protected
def validate
errors.add(parent_id, " must be a root project") if parent and parent.parent
diff --git a/redmine/app/models/project_custom_field.rb b/redmine/app/models/project_custom_field.rb
new file mode 100644
index 000000000..baa533812
--- /dev/null
+++ b/redmine/app/models/project_custom_field.rb
@@ -0,0 +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
diff --git a/redmine/app/models/token.rb b/redmine/app/models/token.rb
new file mode 100644
index 000000000..98745d29e
--- /dev/null
+++ b/redmine/app/models/token.rb
@@ -0,0 +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.
+
+class Token < ActiveRecord::Base
+ belongs_to :user
+
+ @@validity_time = 1.day
+
+ def before_create
+ self.value = Token.generate_token_value
+ end
+
+ # Return true if token has expired
+ def expired?
+ return Time.now > self.created_on + @@validity_time
+ end
+
+ # Delete all expired tokens
+ def self.destroy_expired
+ Token.delete_all ["created_on < ?", Time.now - @@validity_time]
+ end
+
+private
+ def self.generate_token_value
+ chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
+ token_value = ''
+ 40.times { |i| token_value << chars[rand(chars.size-1)] }
+ token_value
+ end
+end
diff --git a/redmine/app/models/tracker.rb b/redmine/app/models/tracker.rb
index 4283f471d..ca37eb939 100644
--- a/redmine/app/models/tracker.rb
+++ b/redmine/app/models/tracker.rb
@@ -19,7 +19,8 @@ class Tracker < ActiveRecord::Base
before_destroy :check_integrity
has_many :issues
has_many :workflows, :dependent => true
-
+ has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_trackers', :association_foreign_key => 'custom_field_id'
+
validates_presence_of :name
validates_uniqueness_of :name
diff --git a/redmine/app/models/user.rb b/redmine/app/models/user.rb
index e0adbb0df..ea313483c 100644
--- a/redmine/app/models/user.rb
+++ b/redmine/app/models/user.rb
@@ -19,7 +19,9 @@ require "digest/sha1"
class User < ActiveRecord::Base
has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true
-
+ has_many :custom_values, :dependent => true, :as => :customized
+ belongs_to :auth_source
+
attr_accessor :password, :password_confirmation
attr_accessor :last_before_login_on
# Prevents unauthorized assignments
@@ -33,6 +35,12 @@ class User < ActiveRecord::Base
# Password length between 4 and 12
validates_length_of :password, :in => 4..12, :allow_nil => true
validates_confirmation_of :password, :allow_nil => true
+ validates_associated :custom_values, :on => :update
+
+ # Account statuses
+ STATUS_ACTIVE = 1
+ STATUS_REGISTERED = 2
+ STATUS_LOCKED = 3
def before_save
# update hashed_password if password was set
@@ -41,23 +49,52 @@ class User < ActiveRecord::Base
# Returns the user that matches provided login and password, or nil
def self.try_to_login(login, password)
- user = find(:first, :conditions => ["login=? and hashed_password=? and locked=?", login, User.hash_password(password), false])
+ user = find(:first, :conditions => ["login=?", login])
if user
- user.last_before_login_on = user.last_login_on
- user.update_attribute(:last_login_on, Time.now)
- end
+ # user is already in local database
+ return nil if !user.active?
+ if user.auth_source
+ # user has an external authentication method
+ return nil unless user.auth_source.authenticate(login, password)
+ else
+ # local authentication
+ return nil unless User.hash_password(password) == user.hashed_password
+ end
+ else
+ # user is not yet registered, try to authenticate with available sources
+ attrs = AuthSource.authenticate(login, password)
+ if attrs
+ onthefly = new(*attrs)
+ onthefly.login = login
+ onthefly.language = $RDM_DEFAULT_LANG
+ if onthefly.save
+ user = find(:first, :conditions => ["login=?", login])
+ end
+ end
+ end
+ user.update_attribute(:last_login_on, Time.now) if user
user
+
+ rescue => text
+ raise text
end
# Return user's full name for display
def display_name
firstname + " " + lastname
end
+
+ def active?
+ self.status == STATUS_ACTIVE
+ end
+
+ def locked?
+ self.status == STATUS_LOCKED
+ end
def check_password?(clear_password)
User.hash_password(clear_password) == self.hashed_password
end
-
def role_for_project(project_id)
@role_for_projects ||=
diff --git a/redmine/app/models/user_custom_field.rb b/redmine/app/models/user_custom_field.rb
new file mode 100644
index 000000000..866234a7f
--- /dev/null
+++ b/redmine/app/models/user_custom_field.rb
@@ -0,0 +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 UserCustomField < CustomField
+ def type_name
+ :label_user_plural
+ end
+end
+
diff --git a/redmine/app/views/account/login.rhtml b/redmine/app/views/account/login.rhtml
index bc2b5a562..2c806b421 100644
--- a/redmine/app/views/account/login.rhtml
+++ b/redmine/app/views/account/login.rhtml
@@ -1,13 +1,25 @@
-<div class="box">
-<h2><%=_('Please login') %></h2>
+<center>
+<div class="box login">
+<h2><%= image_tag 'login' %>&nbsp;&nbsp;<%=l(:label_please_login)%></h2>
-<%= start_form_tag :action=> "login" %>
-<p><label for="login"><%=_ 'Login' %>:</label><br/>
-<%= text_field_tag 'login', nil, :size => 25 %></p>
-
-<p><label for="user_password"><%=_ 'Password' %>:</label><br/>
-<%= password_field_tag 'password', nil, :size => 25 %></p>
+<%= start_form_tag :action=> "login" %>
+<table cellpadding="4">
+ <tr>
+ <td><label for="login"><%=l(:field_login)%>:</label></td>
+ <td><%= text_field_tag 'login', nil, :size => 25 %></td>
+ </tr>
+ <tr>
+ <td><label for="password"><%=l(:field_password)%>:</label></td>
+ <td><%= password_field_tag 'password', nil, :size => 25 %></td>
+ </tr>
+</table>
+
+&nbsp;
-<p><input type="submit" name="login" value="<%=_ 'Log in' %> &#187;" class="primary" /></p>
-<%= end_form_tag %>
-</div> \ No newline at end of file
+<p><center><input type="submit" name="login" value="<%=l(:button_login)%> &#187;" class="primary" /></center></p>
+<%= end_form_tag %>
+<br />
+<% unless $RDM_SELF_REGISTRATION == false %><%= link_to l(:label_register), :action => 'register' %> |<% end %>
+<%= link_to l(:label_password_lost), :action => 'lost_password' %>
+</div>
+</center> \ No newline at end of file
diff --git a/redmine/app/views/account/lost_password.rhtml b/redmine/app/views/account/lost_password.rhtml
new file mode 100644
index 000000000..cd392f243
--- /dev/null
+++ b/redmine/app/views/account/lost_password.rhtml
@@ -0,0 +1,14 @@
+<center>
+<div class="box login">
+<h2><%=l(:label_password_lost)%></h2>
+
+<%= start_form_tag %>
+
+<p><label for="mail"><%=l(:field_mail)%> <span class="required">*</span></label><br/>
+<%= text_field_tag 'mail', nil, :size => 40 %></p>
+
+<p><center><%= submit_tag l(:button_submit) %></center></p>
+
+<%= end_form_tag %>
+</div>
+</center> \ No newline at end of file
diff --git a/redmine/app/views/account/my_account.rhtml b/redmine/app/views/account/my_account.rhtml
index 7248f0e4a..097e23181 100644
--- a/redmine/app/views/account/my_account.rhtml
+++ b/redmine/app/views/account/my_account.rhtml
@@ -1,34 +1,34 @@
-<h2><%=_('My account')%></h2>
+<h2><%=l(:label_my_account)%></h2>
-<p><%=_('Login')%>: <strong><%= @user.login %></strong><br />
-<%=_('Created on')%>: <%= format_time(@user.created_on) %>,
-<%=_('Last update')%>: <%= format_time(@user.updated_on) %></p>
+<p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
+<%=l(:field_created_on)%>: <%= format_time(@user.created_on) %>,
+<%=l(:field_updated_on)%>: <%= format_time(@user.updated_on) %></p>
<%= error_messages_for 'user' %>
<div class="splitcontentleft">
<div class="box">
- <h3><%=_('Information')%></h3>
+ <h3><%=l(:label_information_plural)%></h3>
&nbsp;
<%= start_form_tag :action => 'my_account' %>
<!--[form:user]-->
- <p><label for="user_firstname"><%=_('Firstname')%> <span class="required">*</span></label><br/>
+ <p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label><br/>
<%= text_field 'user', 'firstname' %></p>
- <p><label for="user_lastname"><%=_('Lastname')%> <span class="required">*</span></label><br/>
+ <p><label for="user_lastname"><%=l(:field_lastname)%> <span class="required">*</span></label><br/>
<%= text_field 'user', 'lastname' %></p>
- <p><label for="user_mail"><%=_('Mail')%> <span class="required">*</span></label><br/>
- <%= text_field 'user', 'mail' %></p>
+ <p><label for="user_mail"><%=l(:field_mail)%> <span class="required">*</span></label><br/>
+ <%= text_field 'user', 'mail' %></p>
- <p><label for="user_language"><%=_('Language')%></label><br/>
- <%= select("user", "language", Localization.langs) %></p>
+ <p><label for="user_language"><%=l(:field_language)%></label><br/>
+ <%= select("user", "language", Localization.langs.invert) %></p>
<!--[eoform:user]-->
- <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p>
+ <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=l(:field_mail_notification)%></label></p>
- <center><%= submit_tag _('Save') %></center>
+ <center><%= submit_tag l(:button_save) %></center>
<%= end_form_tag %>
</div>
</div>
@@ -36,20 +36,20 @@
<div class="splitcontentright">
<div class="box">
- <h3><%=_('Password')%></h3>
+ <h3><%=l(:field_password)%></h3>
&nbsp;
<%= start_form_tag :action => 'change_password' %>
- <p><label for="password"><%=_('Password')%> <span class="required">*</span></label><br/>
+ <p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'password', nil, :size => 25 %></p>
- <p><label for="new_password"><%=_('New password')%> <span class="required">*</span></label><br/>
+ <p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'new_password', nil, :size => 25 %></p>
- <p><label for="new_password_confirmation"><%=_('Confirmation')%> <span class="required">*</span></label><br/>
+ <p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
- <center><%= submit_tag _('Save') %></center>
+ <center><%= submit_tag l(:button_save) %></center>
<%= end_form_tag %>
</div>
</div> \ No newline at end of file
diff --git a/redmine/app/views/account/my_page.rhtml b/redmine/app/views/account/my_page.rhtml
index 7f6458262..54b5685e8 100644
--- a/redmine/app/views/account/my_page.rhtml
+++ b/redmine/app/views/account/my_page.rhtml
@@ -1,19 +1,22 @@
-<h2><%=_('My page') %></h2>
+<h2><%=l(:label_my_page)%></h2>
<p>
-<%=_('Welcome')%> <b><%= @user.firstname %></b><br />
<% unless @user.last_before_login_on.nil? %>
- <%=_('Last login')%>: <%= format_time(@user.last_before_login_on) %>
+ <%=l(:label_last_login)%>: <%= format_time(@user.last_before_login_on) %>
<% end %>
</p>
<div class="splitcontentleft">
- <h3><%=_('Reported issues')%></h3>
+ <h3><%=l(:label_reported_issues)%></h3>
<%= render :partial => 'issues/list_simple', :locals => { :issues => @reported_issues } %>
- <%= "<p>(Last #{@reported_issues.length} updated)</p>" if @reported_issues.length > 0 %>
+ <% if @reported_issues.length > 0 %>
+ <p><%=lwr(:label_last_updates, @reported_issues.length)%></p>
+ <% end %>
</div>
<div class="splitcontentright">
-<h3><%=_('Assigned to me')%></h3>
+<h3><%=l(:label_assigned_to_me_issues)%></h3>
<%= render :partial => 'issues/list_simple', :locals => { :issues => @assigned_issues } %>
- <%= "<p>(Last #{@assigned_issues.length} updated)</p>" if @assigned_issues.length > 0 %>
+ <% if @assigned_issues.length > 0 %>
+ <p><%=lwr(:label_last_updates, @assigned_issues.length)%></p>
+ <% end %>
</div> \ No newline at end of file
diff --git a/redmine/app/views/account/password_recovery.rhtml b/redmine/app/views/account/password_recovery.rhtml
new file mode 100644
index 000000000..b4f73d28c
--- /dev/null
+++ b/redmine/app/views/account/password_recovery.rhtml
@@ -0,0 +1,21 @@
+<center>
+<div class="box login">
+<h2><%=l(:label_password_lost)%></h2>
+
+<p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
+
+<%= error_messages_for 'user' %>
+
+ <%= start_form_tag :token => @token.value %>
+
+ <p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label><br/>
+ <%= password_field_tag 'new_password', nil, :size => 25 %></p>
+
+ <p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label><br/>
+ <%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
+
+ <p><center><%= submit_tag l(:button_save) %></center></p>
+ <%= end_form_tag %>
+
+</div>
+</center> \ No newline at end of file
diff --git a/redmine/app/views/account/register.rhtml b/redmine/app/views/account/register.rhtml
new file mode 100644
index 000000000..2bdf380f9
--- /dev/null
+++ b/redmine/app/views/account/register.rhtml
@@ -0,0 +1,46 @@
+<h2><%=l(:label_register)%></h2>
+
+<%= start_form_tag %>
+
+<%= error_messages_for 'user' %>
+
+<div class="box">
+<!--[form:user]-->
+<p><label for="user_login"><%=l(:field_login)%></label> <span class="required">*</span><br/>
+<%= text_field 'user', 'login', :size => 25 %></p>
+
+<p><label for="password"><%=l(:field_password)%></label> <span class="required">*</span><br/>
+<%= password_field_tag 'password', nil, :size => 25 %></p>
+
+<p><label for="password_confirmation"><%=l(:field_password_confirmation)%></label> <span class="required">*</span><br/>
+<%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
+
+<p><label for="user_firstname"><%=l(:field_firstname)%></label> <span class="required">*</span><br/>
+<%= text_field 'user', 'firstname' %></p>
+
+<p><label for="user_lastname"><%=l(:field_lastname)%></label> <span class="required">*</span><br/>
+<%= text_field 'user', 'lastname' %></p>
+
+<p><label for="user_mail"><%=l(:field_mail)%></label> <span class="required">*</span><br/>
+<%= text_field 'user', 'mail' %></p>
+
+<p><label for="user_language"><%=l(:field_language)%></label><br/>
+<%= select("user", "language", Localization.langs.invert) %></p>
+
+<% for custom_value in @custom_values %>
+ <div style="float:left;margin-right:10px;">
+ <p><%= content_tag "label", custom_value.custom_field.name %>
+ <% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
+ <br />
+ <%= custom_field_tag custom_value %></p>
+ </div>
+<% end %>
+
+<div style="clear: both;"></div>
+
+<p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=l(:field_mail_notification)%></label></p>
+<!--[eoform:user]-->
+</div>
+
+ <%= submit_tag l(:button_submit) %>
+<%= end_form_tag %>
diff --git a/redmine/app/views/account/show.rhtml b/redmine/app/views/account/show.rhtml
index df918e5bf..78fe0a679 100644
--- a/redmine/app/views/account/show.rhtml
+++ b/redmine/app/views/account/show.rhtml
@@ -2,10 +2,10 @@
<p>
<%= mail_to @user.mail %><br />
-<%=_('Registered on')%>: <%= format_date(@user.created_on) %>
+<%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %>
</p>
-<h3><%=_('Projects')%></h3>
+<h3><%=l(:label_project_plural)%></h3>
<p>
<% for membership in @user.memberships %>
<%= membership.project.name %> (<%= membership.role.name %>, <%= format_date(membership.created_on) %>)
@@ -13,7 +13,7 @@
<% end %>
</p>
-<h3><%=_('Activity')%></h3>
+<h3><%=l(:label_activity)%></h3>
<p>
-<%=_('Reported issues')%>: <%= Issue.count( [ "author_id=?", @user.id]) %>
+<%=l(:label_reported_issues)%>: <%= Issue.count(["author_id=?", @user.id]) %>
</p> \ No newline at end of file
diff --git a/redmine/app/views/admin/index.rhtml b/redmine/app/views/admin/index.rhtml
index b3607d813..d937e287c 100644
--- a/redmine/app/views/admin/index.rhtml
+++ b/redmine/app/views/admin/index.rhtml
@@ -1,45 +1,50 @@
-<h2><%=_('Administration')%></h2>
+<h2><%=l(:label_administration)%></h2>
<p>
<%= image_tag "projects" %>
-<%= link_to _('Projects'), :controller => 'admin', :action => 'projects' %> |
-<%= link_to _('New'), :controller => 'projects', :action => 'add' %>
+<%= link_to l(:label_project_plural), :controller => 'admin', :action => 'projects' %> |
+<%= link_to l(:label_new), :controller => 'projects', :action => 'add' %>
</p>
<p>
<%= image_tag "users" %>
-<%= link_to _('Users'), :controller => 'users' %> |
-<%= link_to _('New'), :controller => 'users', :action => 'add' %>
+<%= link_to l(:label_user_plural), :controller => 'users' %> |
+<%= link_to l(:label_new), :controller => 'users', :action => 'add' %>
</p>
<p>
<%= image_tag "role" %>
-<%= link_to _('Roles and permissions'), :controller => 'roles' %>
+<%= link_to l(:label_role_and_permissions), :controller => 'roles' %>
</p>
<p>
<%= image_tag "tracker" %>
-<%= link_to _('Trackers'), :controller => 'trackers' %> |
-<%= link_to _('Custom fields'), :controller => 'custom_fields' %>
+<%= link_to l(:label_tracker_plural), :controller => 'trackers' %> |
+<%= link_to l(:label_custom_field_plural), :controller => 'custom_fields' %>
</p>
<p>
<%= image_tag "workflow" %>
-<%= link_to _('Issue Statuses'), :controller => 'issue_statuses' %> |
-<%= link_to _('Workflow'), :controller => 'roles', :action => 'workflow' %>
+<%= link_to l(:label_issue_status_plural), :controller => 'issue_statuses' %> |
+<%= link_to l(:label_workflow), :controller => 'roles', :action => 'workflow' %>
</p>
<p>
<%= image_tag "options" %>
-<%= link_to _('Enumerations'), :controller => 'enumerations' %>
+<%= link_to l(:label_enumerations), :controller => 'enumerations' %>
</p>
<p>
<%= image_tag "mailer" %>
-<%= link_to _('Mail notifications'), :controller => 'admin', :action => 'mail_options' %>
+<%= link_to l(:field_mail_notification), :controller => 'admin', :action => 'mail_options' %>
+</p>
+
+<p>
+<%= image_tag "login" %>
+<%= link_to l(:label_authentication), :controller => 'auth_sources' %>
</p>
<p>
<%= image_tag "help" %>
-<%= link_to _('Information'), :controller => 'admin', :action => 'info' %>
+<%= link_to l(:label_information_plural), :controller => 'admin', :action => 'info' %>
</p> \ No newline at end of file
diff --git a/redmine/app/views/admin/info.rhtml b/redmine/app/views/admin/info.rhtml
index c987805c9..03dddafb6 100644
--- a/redmine/app/views/admin/info.rhtml
+++ b/redmine/app/views/admin/info.rhtml
@@ -1,8 +1,8 @@
<h2><%=_('Information')%></h2>
-<p><%=_('Version')%>: <strong><%= RDM_APP_NAME %> <%= RDM_APP_VERSION %></strong></p>
+<p><%=l(:field_version)%>: <strong><%= RDM_APP_NAME %> <%= RDM_APP_VERSION %></strong></p>
-Environment:
+<%=l(:label_environment)%>:
<ul>
<% Rails::Info.properties.each do |name, value| %>
<li><%= name %>: <%= value %></li>
diff --git a/redmine/app/views/admin/mail_options.rhtml b/redmine/app/views/admin/mail_options.rhtml
index 2d1d80ebb..dcfc619fe 100644
--- a/redmine/app/views/admin/mail_options.rhtml
+++ b/redmine/app/views/admin/mail_options.rhtml
@@ -1,16 +1,16 @@
-<h2><%=_('Mail notifications')%></h2>
+<h2><%=l(:field_mail_notification)%></h2>
-<p><%=_('Select actions for which mail notification should be enabled.')%></p>
+<p><%=l(:text_select_mail_notifications)%></p>
<%= start_form_tag ({}, :id => 'mail_options_form')%>
<% for action in @actions %>
<%= check_box_tag "action_ids[]", action.id, action.mail_enabled? %>
- <%= action.descr %><br />
+ <%= action.description %><br />
<% end %>
<br />
<p>
-<a href="javascript:checkAll('mail_options_form', true)"><%=_('Check all')%></a> |
-<a href="javascript:checkAll('mail_options_form', false)"><%=_('Uncheck all')%></a>
+<a href="javascript:checkAll('mail_options_form', true)"><%=l(:button_check_all)%></a> |
+<a href="javascript:checkAll('mail_options_form', false)"><%=l(:button_uncheck_all)%></a>
</p>
-<%= submit_tag _('Save') %>
+<%= submit_tag l(:button_save) %>
<%= end_form_tag %> \ No newline at end of file
diff --git a/redmine/app/views/admin/projects.rhtml b/redmine/app/views/admin/projects.rhtml
index bcb940b4d..68552fb90 100644
--- a/redmine/app/views/admin/projects.rhtml
+++ b/redmine/app/views/admin/projects.rhtml
@@ -1,25 +1,25 @@
-<h2><%=_('Projects')%></h2>
+<h2><%=l(:label_project_plural)%></h2>
<table width="100%" cellspacing="1" cellpadding="2" class="listTableContent">
<tr class="ListHead">
- <%= sort_header_tag('name', :caption => _('Project')) %>
- <th><%=_('Description')%></th>
- <th><%=_('Public')%></th>
- <th><%=_('Subprojects')%></th>
- <%= sort_header_tag('created_on', :caption => _('Created on')) %>
+ <%= sort_header_tag('name', :caption => l(:label_project)) %>
+ <th><%=l(:field_description)%></th>
+ <th><%=l(:field_is_public)%></th>
+ <th><%=l(:label_subproject_plural)%></th>
+ <%= sort_header_tag('created_on', :caption => l(:field_created_on)) %>
<th></th>
</tr>
<% for project in @projects %>
<tr class="<%= cycle("odd", "even") %>">
<td><%= link_to project.name, :controller => 'projects', :action => 'settings', :id => project %>
- <td><%= project.descr %>
+ <td><%= project.description %>
<td align="center"><%= image_tag 'true' if project.is_public? %>
<td align="center"><%= project.projects_count %>
<td align="center"><%= format_date(project.created_on) %>
<td align="center">
<%= start_form_tag({:controller => 'projects', :action => 'destroy', :id => project}) %>
- <%= submit_tag _('Delete'), :class => "button-small" %>
+ <%= submit_tag l(:button_delete), :class => "button-small" %>
<%= end_form_tag %>
</td>
</tr>
@@ -29,4 +29,4 @@
<p><%= pagination_links_full @project_pages %>
[ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ]</p>
-<p><%= link_to ('&#187; ' + _('New project')), :controller => 'projects', :action => 'add' %></p> \ No newline at end of file
+<p><%= link_to ('&#187; ' + l(:label_project_new)), :controller => 'projects', :action => 'add' %></p> \ No newline at end of file
diff --git a/redmine/app/views/auth_sources/_form.rhtml b/redmine/app/views/auth_sources/_form.rhtml
new file mode 100644
index 000000000..4bb3c3335
--- /dev/null
+++ b/redmine/app/views/auth_sources/_form.rhtml
@@ -0,0 +1,49 @@
+<%= error_messages_for 'auth_source' %>
+
+<div class="box">
+<!--[form:auth_source]-->
+<p><label for="auth_source_name"><%=l(:field_name)%></label> <span class="required">*</span><br/>
+<%= text_field 'auth_source', 'name' %></p>
+
+<p><label for="auth_source_host"><%=l(:field_host)%></label> <span class="required">*</span><br/>
+<%= text_field 'auth_source', 'host' %></p>
+
+<p><label for="auth_source_port"><%=l(:field_port)%></label> <span class="required">*</span><br/>
+<%= text_field 'auth_source', 'port', :size => 6 %></p>
+
+<p><label for="auth_source_account"><%=l(:field_account)%></label><br/>
+<%= text_field 'auth_source', 'account' %></p>
+
+<p><label for="auth_source_account_password"><%=l(:field_password)%></label><br/>
+<%= password_field 'auth_source', 'account_password' %></p>
+
+<p><label for="auth_source_base_dn"><%=l(:field_base_dn)%></label> <span class="required">*</span><br/>
+<%= text_field 'auth_source', 'base_dn', :size => 60 %></p>
+
+<p><%= check_box 'auth_source', 'onthefly_register' %>
+<label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label></p>
+
+<fieldset><legend><%=l(:label_attribute_plural)%></legend>
+<div style="float:left;margin-right:10px;">
+<p><label for="auth_source_attr_login"><%=l(:field_login)%></label> <span class="required">*</span><br/>
+<%= text_field 'auth_source', 'attr_login', :size => 20 %></p>
+</div>
+
+<div style="float:left;margin-right:10px;">
+<p><label for="auth_source_attr_firstname"><%=l(:field_firstname)%></label><br/>
+<%= text_field 'auth_source', 'attr_firstname', :size => 20 %></p>
+</div>
+
+<div style="float:left;margin-right:10px;">
+<p><label for="auth_source_attr_lastname"><%=l(:field_lastname)%></label><br/>
+<%= text_field 'auth_source', 'attr_lastname', :size => 20 %></p>
+</div>
+
+<div>
+<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label><br/>
+<%= text_field 'auth_source', 'attr_mail', :size => 20 %></p>
+</div>
+</fieldset>
+
+<!--[eoform:auth_source]-->
+</div>
diff --git a/redmine/app/views/auth_sources/edit.rhtml b/redmine/app/views/auth_sources/edit.rhtml
new file mode 100644
index 000000000..7e4ee01ce
--- /dev/null
+++ b/redmine/app/views/auth_sources/edit.rhtml
@@ -0,0 +1,7 @@
+<h2><%=l(:label_auth_source)%> (<%= @auth_source.auth_method_name %>)</h2>
+
+<%= start_form_tag :action => 'update', :id => @auth_source %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag l(:button_save) %>
+<%= end_form_tag %>
+
diff --git a/redmine/app/views/auth_sources/list.rhtml b/redmine/app/views/auth_sources/list.rhtml
new file mode 100644
index 000000000..cbaa9c3eb
--- /dev/null
+++ b/redmine/app/views/auth_sources/list.rhtml
@@ -0,0 +1,32 @@
+<h2><%=l(:label_auth_source_plural)%></h2>
+
+<table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
+ <tr class="ListHead">
+ <td><%=l(:field_name)%></td>
+ <td><%=l(:field_type)%></td>
+ <td><%=l(:field_host)%></td>
+ <td></td>
+ <td></td>
+ </tr>
+
+<% for source in @auth_sources %>
+ <tr class="<%= cycle("odd", "even") %>">
+ <td><%= link_to source.name, :action => 'edit', :id => source%></td>
+ <td align="center"><%= source.auth_method_name %></td>
+ <td align="center"><%= source.host %></td>
+ <td align="center">
+ <%= link_to l(:button_test), :action => 'test_connection', :id => source %>
+ </td>
+ <td align="center">
+ <%= start_form_tag :action => 'destroy', :id => source %>
+ <%= submit_tag l(:button_delete), :class => "button-small" %>
+ <%= end_form_tag %>
+ </td>
+ </tr>
+<% end %>
+</table>
+
+<%= pagination_links_full @auth_source_pages %>
+<br />
+<%= link_to '&#187; ' + l(:label_auth_source_new), :action => 'new' %>
+
diff --git a/redmine/app/views/auth_sources/new.rhtml b/redmine/app/views/auth_sources/new.rhtml
new file mode 100644
index 000000000..7cb81dab0
--- /dev/null
+++ b/redmine/app/views/auth_sources/new.rhtml
@@ -0,0 +1,6 @@
+<h2><%=l(:label_auth_source_new)%> (<%= @auth_source.auth_method_name %>)</h2>
+
+<%= start_form_tag :action => 'create' %>
+ <%= render :partial => 'form' %>
+ <%= submit_tag l(:button_create) %>
+<%= end_form_tag %>
diff --git a/redmine/app/views/custom_fields/_form.rhtml b/redmine/app/views/custom_fields/_form.rhtml
index d268461fc..00e36dd36 100644
--- a/redmine/app/views/custom_fields/_form.rhtml
+++ b/redmine/app/views/custom_fields/_form.rhtml
@@ -1,26 +1,53 @@
<%= error_messages_for 'custom_field' %>
<!--[form:custom_field]-->
-<p><label for="custom_field_name"><%=_('Name')%></label><br/>
-<%= text_field 'custom_field', 'name' %></p>
+<div class="box">
+<p><label for="custom_field_name"><%=l(:field_name)%></label> <span class="required">*</span><br/>
+<%= text_field 'custom_field', 'name' %></p>
-<p><label for="custom_field_typ"><%=_('Type')%></label><br/>
-<%= select("custom_field", "typ", CustomField::TYPES) %></p>
+<p><label for="custom_field_typ"><%=l(:field_field_format)%></label><br/>
+<%= select("custom_field", "field_format", custom_field_formats_for_select) %></p>
-<p><%= check_box 'custom_field', 'is_required' %>
-<label for="custom_field_is_required"><%=_('Required')%></label></p>
-
-<p><%= check_box 'custom_field', 'is_for_all' %>
-<label for="custom_field_is_for_all"><%=_('For all projects')%></label></p>
-
-<p><label for="custom_field_min_length"><%=_('Min - max length')%></label> (<%=_('0 means no restriction')%>)<br/>
+<p><label for="custom_field_min_length"><%=l(:label_min_max_length)%></label> (<%=l(:text_min_max_length_info)%>)<br/>
<%= text_field 'custom_field', 'min_length', :size => 5 %> -
<%= text_field 'custom_field', 'max_length', :size => 5 %></p>
-<p><label for="custom_field_regexp"><%=_('Regular expression pattern')%></label> (eg. ^[A-Z0-9]+$)<br/>
+<p><label for="custom_field_regexp"><%=l(:field_regexp)%></label> (<%=l(:text_regexp_info)%>)<br/>
<%= text_field 'custom_field', 'regexp', :size => 50 %></p>
-<p><label for="custom_field_possible_values"><%=_('Possible values')%></label> (separator: |)<br/>
-<%= text_area 'custom_field', 'possible_values', :rows => 5, :cols => 60 %></p>
+<p><label for="custom_field_possible_values"><%=l(:field_possible_values)%></label> (<%=l(:text_possible_values_info)%>)<br/>
+<%= text_area 'custom_field', 'possible_values', :rows => 5, :cols => 60 %></p>
+</div>
<!--[eoform:custom_field]-->
+<div class="box">
+<% case type.to_s
+ when "IssueCustomField" %>
+
+<fieldset><legend><%=l(:label_tracker_plural)%></legend>
+<% for tracker in @trackers %>
+ <input type="checkbox"
+ name="tracker_ids[]"
+ value="<%= tracker.id %>"
+ <%if @custom_field.trackers.include? tracker%>checked="checked"<%end%>
+ > <%= tracker.name %>
+<% end %></fieldset>
+&nbsp;
+
+<p><%= check_box 'custom_field', 'is_required' %>
+<label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
+
+<p><%= check_box 'custom_field', 'is_for_all' %>
+<label for="custom_field_is_for_all"><%=l(:field_is_for_all)%></label></p>
+
+<% when "UserCustomField" %>
+<p><%= check_box 'custom_field', 'is_required' %>
+<label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
+
+<% when "ProjectCustomField" %>
+<p><%= check_box 'custom_field', 'is_required' %>
+<label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
+
+
+<% end %>
+</div>
diff --git a/redmine/app/views/custom_fields/edit.rhtml b/redmine/app/views/custom_fields/edit.rhtml
index ab4ea8b24..c9473fd04 100644
--- a/redmine/app/views/custom_fields/edit.rhtml
+++ b/redmine/app/views/custom_fields/edit.rhtml
@@ -1,6 +1,6 @@
-<h2><%=_('Custom field')%></h2>
+<h2><%=l(:label_custom_field)%> (<%=l(@custom_field.type_name)%>)</h2>
<%= start_form_tag :action => 'edit', :id => @custom_field %>
- <%= render :partial => 'form' %>
- <%= submit_tag _('Save') %>
+ <%= render :partial => 'form', :locals => { :type => @custom_field.type } %>
+ <%= submit_tag l(:button_save) %>
<%= end_form_tag %>
diff --git a/redmine/app/views/custom_fields/list.rhtml b/redmine/app/views/custom_fields/list.rhtml
index 2e654072f..fba952100 100644
--- a/redmine/app/views/custom_fields/list.rhtml
+++ b/redmine/app/views/custom_fields/list.rhtml
@@ -1,32 +1,37 @@
-<h2><%=_('Custom fields')%></h2>
+<h2><%=l(:label_custom_field_plural)%></h2>
<table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
<tr class="ListHead">
- <th><%=_('Name')%></th>
- <th><%=_('Type')%></th>
- <th><%=_('Required')%></th>
- <th><%=_('For all projects')%></th>
+ <th><%=l(:field_name)%></th>
+ <th><%=l(:field_type)%></th>
+ <th><%=l(:field_field_format)%></th>
+ <th><%=l(:field_is_required)%></th>
+ <th><%=l(:field_is_for_all)%></th>
<th><%=_('Used by')%></th>
<th></th>
</tr>
<% for custom_field in @custom_fields %>
<tr class="<%= cycle("odd", "even") %>">
<td><%= link_to custom_field.name, :action => 'edit', :id => custom_field %></td>
- <td align="center"><%= CustomField::TYPES[custom_field.typ][0] %></td>
+ <td align="center"><%= l(custom_field.type_name) %></td>
+ <td align="center"><%= l(CustomField::FIELD_FORMATS[custom_field.field_format]) %></td>
<td align="center"><%= image_tag 'true' if custom_field.is_required? %></td>
<td align="center"><%= image_tag 'true' if custom_field.is_for_all? %></td>
- <td align="center"><%= custom_field.projects.count.to_s + ' ' + _('Project') + '(s)' unless custom_field.is_for_all? %></td>
+ <td align="center"><%= custom_field.projects.count.to_s + ' ' + lwr(:label_project, custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
<td align="center">
<%= start_form_tag :action => 'destroy', :id => custom_field %>
- <%= submit_tag _('Delete'), :class => "button-small" %>
+ <%= submit_tag l(:button_delete), :class => "button-small" %>
<%= end_form_tag %> </td>
</tr>
<% end %>
</table>
-<%= link_to ('&#171; ' + _('Previous')), { :page => @custom_field_pages.current.previous } if @custom_field_pages.current.previous %>
-<%= link_to (_('Next') + ' &#187;'), { :page => @custom_field_pages.current.next } if @custom_field_pages.current.next %>
+<%= pagination_links_full @custom_field_pages %>
<br />
-
-<%= link_to ('&#187; ' + _('New custom field')), :action => 'new' %>
+<%=l(:label_custom_field_new)%>:
+<ul>
+<li><%= link_to l(:label_issue_plural), :action => 'new', :type => 'IssueCustomField' %></li>
+<li><%= link_to l(:label_project_plural), :action => 'new', :type => 'ProjectCustomField' %></li>
+<li><%= link_to l(:label_user_plural), :action => 'new', :type => 'UserCustomField' %></li>
+</ul>
diff --git a/redmine/app/views/custom_fields/new.rhtml b/redmine/app/views/custom_fields/new.rhtml
index 0e6492a28..1605ada2b 100644
--- a/redmine/app/views/custom_fields/new.rhtml
+++ b/redmine/app/views/custom_fields/new.rhtml
@@ -1,7 +1,8 @@
-<h2><%=_('New custom field')%></h2>
+<h2><%=l(:label_custom_field_new)%> (<%=l(@custom_field.type_name)%>)</h2>
<%= start_form_tag :action => 'new' %>
- <%= render :partial => 'form' %>
- <%= submit_tag _('Create') %>
+ <%= render :partial => 'form', :locals => { :type => @custom_field.type } %>
+ <%= hidden_field_tag 'type', @custom_field.type %>
+ <%= submit_tag l(:button_save) %>
<%= end_form_tag %>
diff --git a/redmine/app/views/documents/_form.rhtml b/redmine/app/views/documents/_form.rhtml
index 4440a156e..e4dac38e6 100644
--- a/redmine/app/views/documents/_form.rhtml
+++ b/redmine/app/views/documents/_form.rhtml
@@ -1,15 +1,15 @@
<%= error_messages_for 'document' %>
<!--[form:document]-->
-<p><label for="document_category_id"><%=_('Category')%></label><br />
+<p><label for="document_category_id"><%=l(:field_category)%></label><br />
<select name="document[category_id]">
-<%= options_from_collection_for_select @categories, "id", "name",@document.category_id %>
+<%= options_from_collection_for_select @categories, "id", "name", @document.category_id %>
</select></p>
-<p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br />
+<p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label><br />
<%= text_field 'document', 'title', :size => 60 %></p>
-<p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br />
-<%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p>
+<p><label for="document_description"><%=l(:field_description)%> <span class="required">*</span></label><br />
+<%= text_area 'document', 'description', :cols => 60, :rows => 5 %></p>
<!--[eoform:document]-->
diff --git a/redmine/app/views/documents/show.rhtml b/redmine/app/views/documents/show.rhtml
index 8e09bb2f5..1cadf7c42 100644
--- a/redmine/app/views/documents/show.rhtml
+++ b/redmine/app/views/documents/show.rhtml
@@ -1,6 +1,6 @@
<h2><%= @document.title %></h2>
-<strong><%=_('Description')%>:</strong> <%= @document.descr %><br />
+<strong><%=_('Description')%>:</strong> <%= @document.description %><br />
<strong><%=_('Category')%>:</strong> <%= @document.category.name %><br />
<br />
diff --git a/redmine/app/views/issues/change_status.rhtml b/redmine/app/views/issues/change_status.rhtml
index 58032cefc..aa85ae249 100644
--- a/redmine/app/views/issues/change_status.rhtml
+++ b/redmine/app/views/issues/change_status.rhtml
@@ -5,7 +5,8 @@
<%= hidden_field_tag 'confirm', 1 %>
<%= hidden_field 'history', 'status_id' %>
-
+
+<div class="box">
<p><%=_('New status')%>: <b><%= @history.status.name %></b></p>
<div>
@@ -24,6 +25,8 @@
<p><label for="history_notes"><%=_('Notes')%></label><br />
<%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
+</div>
+
<%= submit_tag _('Save') %>
<%= end_form_tag %>
diff --git a/redmine/app/views/issues/edit.rhtml b/redmine/app/views/issues/edit.rhtml
index 1249cfc8d..876542fbe 100644
--- a/redmine/app/views/issues/edit.rhtml
+++ b/redmine/app/views/issues/edit.rhtml
@@ -1,18 +1,12 @@
-<h2><%=_('Issue')%> #<%= @issue.id %></h2>
+<h2><%=_@issue.tracker.name%> #<%= @issue.id %> - <%= @issue.subject %></h2>
<%= error_messages_for 'issue' %>
<%= start_form_tag :action => 'edit', :id => @issue %>
+<div class="box">
<!--[form:issue]-->
<p><%=_('Status')%>: <b><%= @issue.status.name %></b></p>
-<div style="float:left;margin-right:10px;">
-<p><label for="issue_tracker_id"><%=_('Tracker')%> <span class="required">*</span></label><br/>
-<select name="issue[tracker_id]">
-<%= options_from_collection_for_select @trackers, "id", "name", @issue.tracker_id %></p>
-</select></p>
-</div>
-
<div style="float:left;margin-right:10px;">
<p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/>
<select name="issue[priority_id]">
@@ -39,24 +33,21 @@
<p><label for="issue_subject"><%=_('Subject')%></label><span class="required">*</span><br/>
<%= text_field 'issue', 'subject', :size => 60 %></p>
-<p><label for="issue_descr"><%=_('Description')%></label><span class="required">*</span><br/>
-<%= text_area 'issue', 'descr', :cols => 60, :rows => 10 %></p>
+<p><label for="issue_description"><%=_('Description')%></label><span class="required">*</span><br/>
+<%= text_area 'issue', 'description', :cols => 60, :rows => 10 %></p>
-
-<% for custom_value in @custom_values %>
- <p><%= content_tag "label", custom_value.custom_field.name %>
- <% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
- <br />
- <%= custom_field_tag custom_value %></p>
+<% for custom_value in @custom_values %>
+ <p><%= custom_field_tag_with_label custom_value %></p>
<% end %>
-
<p><label for="issue_fixed_version"><%=_('Fixed in version')%></label><br/>
<select name="issue[fixed_version_id]">
<option value="">--none--</option>
<%= options_from_collection_for_select @project.versions, "id", "name", @issue.fixed_version_id %>
</select></p>
+
<!--[eoform:issue]-->
+</div>
-<center><%= submit_tag _('Save') %></center>
+<%= submit_tag _('Save') %>
<%= end_form_tag %>
diff --git a/redmine/app/views/issues/show.rhtml b/redmine/app/views/issues/show.rhtml
index 58c9b3579..649f9adf9 100644
--- a/redmine/app/views/issues/show.rhtml
+++ b/redmine/app/views/issues/show.rhtml
@@ -1,18 +1,21 @@
-<h2><%=_('Issue')%> #<%= @issue.id %> - <%= @issue.subject %></h2>
+<h2><%=_(@issue.tracker.name)%> #<%= @issue.id %> - <%= @issue.subject %></h2>
<div class="box">
-<p><b><%=_('Tracker')%>:</b> <%= @issue.tracker.name %></p>
+<p><b><%=_('Status')%>:</b> <%= @issue.status.name %></p>
<p><b><%=_('Priority')%>:</b> <%= @issue.priority.name %></p>
<p><b><%=_('Category')%>:</b> <%= @issue.category.name unless @issue.category_id.nil? %></p>
-<p><b><%=_('Status')%>:</b> <%= @issue.status.name %></p>
<p><b><%=_('Author')%>:</b> <%= @issue.author.display_name %></p>
<p><b><%=_('Assigned to')%>:</b> <%= @issue.assigned_to.display_name unless @issue.assigned_to.nil? %></p>
<p><b><%=_('Subject')%>:</b> <%= @issue.subject %></p>
-<p><b><%=_('Description')%>:</b> <%= simple_format auto_link @issue.descr %></p>
+<p><b><%=_('Description')%>:</b> <%= simple_format auto_link @issue.description %></p>
<p><b><%=_('Created on')%>:</b> <%= format_date(@issue.created_on) %></p>
+<% for custom_value in @custom_values %>
+<p><b><%= custom_value.custom_field.name %></b>: <%= show_value custom_value %></p>
+<% end %>
+
<% if authorize_for('issues', 'edit') %>
<%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %>
<%= submit_tag _('Edit') %>
diff --git a/redmine/app/views/layouts/base.rhtml b/redmine/app/views/layouts/base.rhtml
index 21bb036d3..de99a0b4a 100644
--- a/redmine/app/views/layouts/base.rhtml
+++ b/redmine/app/views/layouts/base.rhtml
@@ -1,13 +1,51 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
-<title>redMine</title>
+<title><%= $RDM_HEADER_TITLE %></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="redMine" />
<meta name="keywords" content="issue,bug,tracker" />
<%= stylesheet_link_tag "application" %>
+<%= stylesheet_link_tag "menu" %>
<%= stylesheet_link_tag "rails" %>
<%= javascript_include_tag :defaults %>
+<%= javascript_include_tag 'menu' %>
+
+<script type='text/javascript'>
+var menu_contenu=' \
+<div id="menuAdmin" class="menu" onmouseover="menuMouseover(event)"> \
+<a class="menuItem" href="\/admin\/projects" onmouseover="menuItemMouseover(event,\'menuProjects\');"><span class="menuItemText"><%=_('Projects')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
+<a class="menuItem" href="\/users" onmouseover="menuItemMouseover(event,\'menuUsers\');"><span class="menuItemText"><%=_('Users')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
+<a class="menuItem" href="\/roles"><%=_('Roles and permissions')%><\/a> \
+<a class="menuItem" href="\/trackers" onmouseover="menuItemMouseover(event,\'menuTrackers\');"><span class="menuItemText"><%=_('Trackers')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
+<a class="menuItem" href="\/custom_fields"><%=_('Custom fields')%><\/a> \
+<a class="menuItem" href="\/enumerations"><%=_('Enumerations')%><\/a> \
+<a class="menuItem" href="\/admin\/mail_options"><%=_('Mail notifications')%><\/a> \
+<a class="menuItem" href="\/auth_sources"><%=l(:label_authentication)%><\/a> \
+<a class="menuItem" href="\/admin\/info"><%=_('Information')%><\/a> \
+<\/div> \
+<div id="menuTrackers" class="menu"> \
+<a class="menuItem" href="\/issue_statuses"><%=_('Issue Statuses')%><\/a> \
+<a class="menuItem" href="\/roles\/workflow"><%=_('Workflow')%><\/a> \
+<\/div> \
+<div id="menuProjects" class="menu"><a class="menuItem" href="\/projects\/add"><%=_('New')%><\/a><\/div> \
+<div id="menuUsers" class="menu"><a class="menuItem" href="\/users\/add"><%=_('New')%><\/a><\/div> \
+ \
+<% unless @project.nil? || @project.id.nil? %> \
+<div id="menuProject" class="menu" onmouseover="menuMouseover(event)"> \
+<%= link_to _('Issues'), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %> \
+<%= link_to _('Reports'), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %> \
+<%= link_to _('News'), {:controller => 'projects', :action => 'list_news', :id => @project }, :class => "menuItem" %> \
+<%= link_to _('Change log'), {:controller => 'projects', :action => 'changelog', :id => @project }, :class => "menuItem" %> \
+<%= link_to _('Documents'), {:controller => 'projects', :action => 'list_documents', :id => @project }, :class => "menuItem" %> \
+<%= link_to _('Members'), {:controller => 'projects', :action => 'list_members', :id => @project }, :class => "menuItem" %> \
+<%= link_to _('Files'), {:controller => 'projects', :action => 'list_files', :id => @project }, :class => "menuItem" %> \
+<%= link_to_if_authorized _('Settings'), {:controller => 'projects', :action => 'settings', :id => @project }, :class => "menuItem" %> \
+<\/div> \
+<% end %> \
+';
+</script>
+
</head>
<body>
@@ -15,37 +53,42 @@
<div id="header">
<div style="float: left;">
- <h1><%= RDM_APP_NAME %></h1>
- <h2>Project management</h2>
+ <h1><%= $RDM_HEADER_TITLE %></h1>
+ <h2><%= $RDM_HEADER_SUBTITLE %></h2>
</div>
<div style="float: right; padding-right: 1em; padding-top: 0.2em;">
- <% unless session[:user].nil? %><small><%=_('Logged as')%> <b><%= session[:user].login %></b></small><% end %>
+ <% if loggedin? %><small><%=l(:label_logged_as)%> <b><%= @logged_in_user.login %></b></small><% end %>
</div>
</div>
<div id="navigation">
<ul>
- <li class="selected"><%= link_to _('Home'), { :controller => '' }, :class => "picHome" %></li>
- <li><%= link_to _('My page'), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
- <li><%= link_to _('Projects'), { :controller => 'projects' }, :class => "picProject" %></li>
+ <li class="selected"><%= link_to l(:label_home), { :controller => '' }, :class => "picHome" %></li>
+ <li><%= link_to l(:label_my_page), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
+ <li><%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => "picProject" %></li>
- <% unless session[:user].nil? %>
- <li><%= link_to _('My account'), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
- <% end %>
+ <% unless @project.nil? || @project.id.nil? %>
+ <li><%= link_to @project.name, { :controller => 'projects', :action => 'show', :id => @project }, :class => "picProject", :onmouseover => "buttonMouseover(event, 'menuProject');" %></li>
+ <% end %>
- <% if admin_loggedin? %>
- <li><%= link_to _('Administration'), { :controller => 'admin' }, :class => "picAdmin" %></li>
- <% end %>
+ <% if loggedin? %>
+ <li><%= link_to l(:label_my_account), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
+ <% end %>
- <li class="right"><%= link_to _('Help'), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li>
- <% if session[:user].nil? %>
- <li class="right"><%= link_to _('Log in'), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li>
- <% else %>
- <li class="right"><%= link_to _('Logout'), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li>
- <% end %>
- </ul>
-
+ <% if admin_loggedin? %>
+ <li><%= link_to l(:label_administration), { :controller => 'admin' }, :class => "picAdmin", :onmouseover => "buttonMouseover(event, 'menuAdmin');" %></li>
+ <% end %>
+
+ <li class="right"><%= link_to l(:label_help), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li>
+
+ <% if loggedin? %>
+ <li class="right"><%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li>
+ <% else %>
+ <li class="right"><%= link_to l(:label_login), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li>
+ <% end %>
+ </ul>
</div>
+ <script type='text/javascript'>if(document.getElementById) {document.write(menu_contenu);}</script>
<div id="subcontent">
@@ -64,15 +107,14 @@
</ul>
<% end %>
- <% unless session[:user].nil? %>
+ <% if loggedin? and @logged_in_user.memberships.length > 0 %>
<h2><%=_('My projects') %></h2>
<ul class="menublock">
- <% for membership in session[:user].memberships %>
+ <% for membership in @logged_in_user.memberships %>
<li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %></li>
<% end %>
</ul>
- <% end %>
-
+ <% end %>
</div>
<div id="content">
@@ -81,7 +123,10 @@
</div>
<div id="footer">
- <p><a href="http://redmine.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %></p>
+ <p>
+ <%= auto_link $RDM_FOOTER_SIG %> |
+ <a href="http://redmine.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %>
+ </p>
</div>
</div>
diff --git a/redmine/app/views/mailer/_issue.rhtml b/redmine/app/views/mailer/_issue.rhtml
index 1f238f513..f2ab6fa5f 100644
--- a/redmine/app/views/mailer/_issue.rhtml
+++ b/redmine/app/views/mailer/_issue.rhtml
@@ -1,6 +1,6 @@
<%=_('Issue')%> #<%= issue.id %> - <%= issue.subject %>
<%=_('Author')%>: <%= issue.author.display_name %>
-<%= issue.descr %>
+<%= issue.description %>
-http://<%= RDM_HOST_NAME %>/issues/show/<%= issue.id %> \ No newline at end of file
+http://<%= $RDM_HOST_NAME %>/issues/show/<%= issue.id %> \ No newline at end of file
diff --git a/redmine/app/views/mailer/issue_add.rhtml b/redmine/app/views/mailer/issue_add_en.rhtml
index 9efec9ad9..9efec9ad9 100644
--- a/redmine/app/views/mailer/issue_add.rhtml
+++ b/redmine/app/views/mailer/issue_add_en.rhtml
diff --git a/redmine/app/views/mailer/issue_add_fr.rhtml b/redmine/app/views/mailer/issue_add_fr.rhtml
new file mode 100644
index 000000000..628ecae12
--- /dev/null
+++ b/redmine/app/views/mailer/issue_add_fr.rhtml
@@ -0,0 +1,3 @@
+Une nouvelle demande (#<%= @issue.id %>) a été soumise.
+----------------------------------------
+<%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> \ No newline at end of file
diff --git a/redmine/app/views/mailer/issue_change_status.rhtml b/redmine/app/views/mailer/issue_change_status_en.rhtml
index e3612ea81..e3612ea81 100644
--- a/redmine/app/views/mailer/issue_change_status.rhtml
+++ b/redmine/app/views/mailer/issue_change_status_en.rhtml
diff --git a/redmine/app/views/mailer/issue_change_status_fr.rhtml b/redmine/app/views/mailer/issue_change_status_fr.rhtml
new file mode 100644
index 000000000..831f301d5
--- /dev/null
+++ b/redmine/app/views/mailer/issue_change_status_fr.rhtml
@@ -0,0 +1,3 @@
+La demande #<%= @issue.id %> a été mise à jour au statut "<%= @issue.status.name %>".
+----------------------------------------
+<%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> \ No newline at end of file
diff --git a/redmine/app/views/mailer/lost_password_en.rhtml b/redmine/app/views/mailer/lost_password_en.rhtml
new file mode 100644
index 000000000..2593edbda
--- /dev/null
+++ b/redmine/app/views/mailer/lost_password_en.rhtml
@@ -0,0 +1,3 @@
+To change your password, use the following link:
+
+http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %> \ No newline at end of file
diff --git a/redmine/app/views/mailer/lost_password_fr.rhtml b/redmine/app/views/mailer/lost_password_fr.rhtml
new file mode 100644
index 000000000..30996f118
--- /dev/null
+++ b/redmine/app/views/mailer/lost_password_fr.rhtml
@@ -0,0 +1,3 @@
+Pour changer votre mot de passe, utilisez le lien suivant:
+
+http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %> \ No newline at end of file
diff --git a/redmine/app/views/mailer/register_en.rhtml b/redmine/app/views/mailer/register_en.rhtml
new file mode 100644
index 000000000..2c0341b24
--- /dev/null
+++ b/redmine/app/views/mailer/register_en.rhtml
@@ -0,0 +1,3 @@
+To activate your redMine account, use the following link:
+
+http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %> \ No newline at end of file
diff --git a/redmine/app/views/mailer/register_fr.rhtml b/redmine/app/views/mailer/register_fr.rhtml
new file mode 100644
index 000000000..3f5d0ccaf
--- /dev/null
+++ b/redmine/app/views/mailer/register_fr.rhtml
@@ -0,0 +1,3 @@
+Pour activer votre compte sur redMine, utilisez le lien suivant:
+
+http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %> \ No newline at end of file
diff --git a/redmine/app/views/news/_form.rhtml b/redmine/app/views/news/_form.rhtml
index 609b15cd9..ea6d5df7f 100644
--- a/redmine/app/views/news/_form.rhtml
+++ b/redmine/app/views/news/_form.rhtml
@@ -4,10 +4,10 @@
<p><label for="news_title"><%=_('Title')%></label> <span class="required">*</span><br/>
<%= text_field 'news', 'title', :size => 60 %></p>
-<p><label for="news_shortdescr"><%=_('Summary')%> <span class="required">*</span></label><br/>
-<%= text_area 'news', 'shortdescr', :cols => 60, :rows => 2 %></p>
+<p><label for="news_summary"><%=_('Summary')%></label><br/>
+<%= text_area 'news', 'summary', :cols => 60, :rows => 2 %></p>
-<p><label for="news_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
-<%= text_area 'news', 'descr', :cols => 60, :rows => 10 %></p>
+<p><label for="news_description"><%=_('Description')%> <span class="required">*</span></label><br/>
+<%= text_area 'news', 'description', :cols => 60, :rows => 10 %></p>
<!--[eoform:news]-->
diff --git a/redmine/app/views/news/show.rhtml b/redmine/app/views/news/show.rhtml
index d6773cda9..f571b54ca 100644
--- a/redmine/app/views/news/show.rhtml
+++ b/redmine/app/views/news/show.rhtml
@@ -1,10 +1,10 @@
<h2><%= @news.title %></h2>
<p>
-<b><%=_('Summary')%></b>: <%= @news.shortdescr %><br />
+<b><%=_('Summary')%></b>: <%= @news.summary %><br />
<b><%=_('By')%></b>: <%= @news.author.display_name %><br />
<b><%=_('Date')%></b>: <%= format_time(@news.created_on) %>
</p>
-<%= simple_format auto_link @news.descr %>
+<%= simple_format auto_link @news.description %>
diff --git a/redmine/app/views/projects/_form.rhtml b/redmine/app/views/projects/_form.rhtml
index 89f58354e..9623a9d46 100644
--- a/redmine/app/views/projects/_form.rhtml
+++ b/redmine/app/views/projects/_form.rhtml
@@ -1,10 +1,11 @@
<%= error_messages_for 'project' %>
+<div class="box">
<!--[form:project]-->
<p><label for="project_name"><%=_('Name')%> <span class="required">*</span></label><br/>
<%= text_field 'project', 'name' %></p>
-<% if session[:user].admin %>
+<% if admin_loggedin? %>
<p><label for="project_parent_id"><%=_('Subproject of')%></label><br/>
<select name="project[parent_id]">
<option value=""></option>
@@ -12,15 +13,19 @@
</select></p>
<% end %>
-<p><label for="project_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
-<%= text_area 'project', 'descr', :cols => 60, :rows => 3 %></p>
+<p><label for="project_description"><%=_('Description')%> <span class="required">*</span></label><br/>
+<%= text_area 'project', 'description', :cols => 60, :rows => 3 %></p>
<p><label for="project_homepage"><%=_('Homepage')%></label><br/>
<%= text_field 'project', 'homepage', :size => 40 %></p>
<p><%= check_box 'project', 'is_public' %>
<label for="project_is_public"><%=_('Public')%></label></p>
-
+
+<% for custom_value in @custom_values %>
+ <p><%= custom_field_tag_with_label custom_value %></p>
+<% end %>
+
<fieldset><legend><%=_('Custom fields')%></legend>
<% for custom_field in @custom_fields %>
<input type="checkbox"
@@ -31,6 +36,6 @@
> <%= custom_field.name %>
<% end %></fieldset>
-<br />
-
+
+</div>
<!--[eoform:project]-->
diff --git a/redmine/app/views/projects/add.rhtml b/redmine/app/views/projects/add.rhtml
index 6344705b0..bdfe0862e 100644
--- a/redmine/app/views/projects/add.rhtml
+++ b/redmine/app/views/projects/add.rhtml
@@ -4,4 +4,3 @@
<%= render :partial => 'form' %>
<%= submit_tag _('Create') %>
<%= end_form_tag %>
-
diff --git a/redmine/app/views/projects/add_document.rhtml b/redmine/app/views/projects/add_document.rhtml
index 13e75dd77..f1adc8d4d 100644
--- a/redmine/app/views/projects/add_document.rhtml
+++ b/redmine/app/views/projects/add_document.rhtml
@@ -12,8 +12,8 @@
<p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br />
<%= text_field 'document', 'title', :size => 60 %></p>
-<p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br />
-<%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p>
+<p><label for="document_description"><%=_('Description')%> <span class="required">*</span></label><br />
+<%= text_area 'document', 'description', :cols => 60, :rows => 5 %></p>
<p><label for="attachment_file"><%=_('File')%></label><br/>
<%= file_field 'attachment', 'file' %></p>
diff --git a/redmine/app/views/projects/add_issue.rhtml b/redmine/app/views/projects/add_issue.rhtml
index a6b37cc46..5e4d450ec 100644
--- a/redmine/app/views/projects/add_issue.rhtml
+++ b/redmine/app/views/projects/add_issue.rhtml
@@ -1,16 +1,12 @@
-<h2><%=_('New issue')%></h2>
+<h2><%=_('New issue')%>: <%=_(@tracker.name)%></h2>
<%= start_form_tag( { :action => 'add_issue', :id => @project }, :multipart => true) %>
<%= error_messages_for 'issue' %>
+<div class="box">
<!--[form:issue]-->
-
-<div style="float:left;margin-right:10px;">
-<p><label for="issue_tracker_id"><%=_('Tracker')%> <span class="required">*</span></label><br/>
-<select name="issue[tracker_id]">
-<%= options_from_collection_for_select @trackers, "id", "name", @issue.tracker_id %></p>
-</select></p>
-</div>
+
+<%= hidden_field_tag 'tracker_id', @tracker.id %>
<div style="float:left;margin-right:10px;">
<p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/>
@@ -30,33 +26,26 @@
<div>
<p><label for="issue_category_id"><%=_('Category')%></label><br/>
<select name="issue[category_id]">
-<option value=""></option>
-<%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %></p>
+<option value=""></option><%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %>
</select></p>
</div>
<p><label for="issue_subject"><%=_('Subject')%> <span class="required">*</span></label><br/>
<%= text_field 'issue', 'subject', :size => 80 %></p>
-<p><label for="issue_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
-<%= text_area 'issue', 'descr', :cols => 60, :rows => 10 %></p>
-
+<p><label for="issue_description"><%=_('Description')%> <span class="required">*</span></label><br/>
+<%= text_area 'issue', 'description', :cols => 60, :rows => 10 %></p>
-<% for custom_value in @custom_values %>
- <div style="float:left;margin-right:10px;">
- <p><%= content_tag "label", custom_value.custom_field.name %>
- <% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
- <br />
- <%= custom_field_tag custom_value %></p>
- </div>
+<% for custom_value in @custom_values %>
+ <p><%= custom_field_tag_with_label custom_value %></p>
<% end %>
-<div style="clear: both;">
<p><label for="attachment_file"><%=_('Attachment')%></label><br/>
<%= file_field 'attachment', 'file' %></p>
-</div>
<!--[eoform:issue]-->
+</div>
+
<%= submit_tag _('Create') %>
<%= end_form_tag %> \ No newline at end of file
diff --git a/redmine/app/views/projects/changelog.rhtml b/redmine/app/views/projects/changelog.rhtml
index 3be8fb0dc..5d2a588ea 100644
--- a/redmine/app/views/projects/changelog.rhtml
+++ b/redmine/app/views/projects/changelog.rhtml
@@ -3,7 +3,7 @@
<% fixed_issues = @fixed_issues.group_by {|i| i.fixed_version } %>
<% fixed_issues.each do |version, issues| %>
<p><strong><%= version.name %></strong> - <%= format_date(version.effective_date) %><br />
- <%=h version.descr %></p>
+ <%=h version.description %></p>
<ul>
<% issues.each do |i| %>
<li><%= link_to i.long_id, :controller => 'issues', :action => 'show', :id => i %> [<%= i.tracker.name %>]: <%= i.subject %></li>
diff --git a/redmine/app/views/projects/list.rhtml b/redmine/app/views/projects/list.rhtml
index bee507af6..1c7cd4374 100644
--- a/redmine/app/views/projects/list.rhtml
+++ b/redmine/app/views/projects/list.rhtml
@@ -10,7 +10,7 @@
<% for project in @projects %>
<tr class="<%= cycle("odd", "even") %>">
<td><%= link_to project.name, :action => 'show', :id => project %>
- <td><%= project.descr %>
+ <td><%= project.description %>
<td align="center"><%= format_date(project.created_on) %>
</tr>
<% end %>
diff --git a/redmine/app/views/projects/list_documents.rhtml b/redmine/app/views/projects/list_documents.rhtml
index 1c7db5ec9..aa7670964 100644
--- a/redmine/app/views/projects/list_documents.rhtml
+++ b/redmine/app/views/projects/list_documents.rhtml
@@ -8,7 +8,7 @@
<li>
<b><%= link_to d.title, :controller => 'documents', :action => 'show', :id => d %></b>
<br />
- <%=_('Desciption')%>: <%= d.descr %><br />
+ <%=_('Desciption')%>: <%= d.description %><br />
<%= format_time(d.created_on) %>
</li>
diff --git a/redmine/app/views/projects/list_issues.rhtml b/redmine/app/views/projects/list_issues.rhtml
index 7e32fb257..652ad6bc5 100644
--- a/redmine/app/views/projects/list_issues.rhtml
+++ b/redmine/app/views/projects/list_issues.rhtml
@@ -7,6 +7,7 @@
<td><small><%=_('Tracker')%>:</small><br /><%= search_filter_tag 'tracker_id', :class => 'select-small' %></td>
<td><small><%=_('Priority')%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td>
<td><small><%=_('Category')%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td>
+ <td><small><%=_('Fixed in version')%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td>
<td><small><%=_('Assigned to')%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td>
<td><small><%=_('Subprojects')%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td>
@@ -52,9 +53,4 @@
<p>
<%= pagination_links_full @issue_pages %>
[ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
- </p>
-
-
-<p>
-<%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
-</p> \ No newline at end of file
+ </p> \ No newline at end of file
diff --git a/redmine/app/views/projects/list_news.rhtml b/redmine/app/views/projects/list_news.rhtml
index 7db53391e..aee4146bf 100644
--- a/redmine/app/views/projects/list_news.rhtml
+++ b/redmine/app/views/projects/list_news.rhtml
@@ -6,7 +6,7 @@
<%= link_to_if_authorized image_tag('edit_small'), :controller => 'news', :action => 'edit', :id => news %>
<%= link_to_if_authorized image_tag('delete'), { :controller => 'news', :action => 'destroy', :id => news }, :confirm => 'Are you sure?' %>
<br />
- <%= news.shortdescr %>
+ <%= news.summary %>
<small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small>
</p>
<% end %>
diff --git a/redmine/app/views/projects/settings.rhtml b/redmine/app/views/projects/settings.rhtml
index c130ed036..f6b5e169f 100644
--- a/redmine/app/views/projects/settings.rhtml
+++ b/redmine/app/views/projects/settings.rhtml
@@ -1,11 +1,11 @@
<h2><%=_('Settings')%></h2>
-<div class="box">
<%= start_form_tag :action => 'edit', :id => @project %>
<%= render :partial => 'form' %>
<center><%= submit_tag _('Save') %></center>
<%= end_form_tag %>
-</div>
+
+&nbsp;
<div class="box">
<h3><%=_('Members')%></h3>
@@ -54,7 +54,7 @@
<% for version in @project.versions %>
<tr>
<td><%= link_to version.name, :controller => 'versions', :action => 'edit', :id => version %></td>
- <td><%=h version.descr %></td>
+ <td><%=h version.description %></td>
<td>
<%= start_form_tag :controller => 'versions', :action => 'destroy', :id => version %>
<%= submit_tag _('Delete'), :class => "button-small" %>
diff --git a/redmine/app/views/projects/show.rhtml b/redmine/app/views/projects/show.rhtml
index 4fdbe51b4..985142f3e 100644
--- a/redmine/app/views/projects/show.rhtml
+++ b/redmine/app/views/projects/show.rhtml
@@ -1,16 +1,21 @@
<h2><%=_('Overview')%></h2>
<div class="splitcontentleft">
- <%= @project.descr %>
+ <%= @project.description %>
<ul>
<li><%=_('Homepage')%>: <%= link_to @project.homepage, @project.homepage %></li>
<li><%=_('Created on')%>: <%= format_date(@project.created_on) %></li>
+ <% for custom_value in @custom_values %>
+ <% if !custom_value.value.empty? %>
+ <li><%= custom_value.custom_field.name%>: <%= custom_value.value%></li>
+ <% end %>
+ <% end %>
</ul>
<div class="box">
<h3><%= image_tag "tracker" %> <%=_('Trackers')%></h3>
<ul>
- <% for tracker in Tracker.find_all %>
+ <% for tracker in @trackers %>
<li><%= link_to tracker.name, :controller => 'projects', :action => 'list_issues', :id => @project,
:set_filter => 1,
"tracker_id" => tracker.id %>:
@@ -18,8 +23,14 @@
</li>
<% end %>
</ul>
- <%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
- <br />
+ <% if authorize_for 'projects', 'add_issue' %>
+ &#187; <%=_('Report an issue')%>:
+ <ul>
+ <% @trackers.each do |tracker| %>
+ <li><%= link_to _(tracker.name), :controller => 'projects', :action => 'add_issue', :id => @project, :tracker_id => tracker %></li>
+ <% end %>
+ </ul>
+ <% end %>
<center><small>[ <%= link_to _('View all issues'), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %> ]</small></center>
</div>
</div>
@@ -46,7 +57,7 @@
<% for news in @news %>
<p>
<b><%= news.title %></b> <small>(<%= link_to_user news.author %> <%= format_time(news.created_on) %>)</small><br />
- <%= news.shortdescr %>
+ <%= news.summary %>
<small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small>
</p>
<hr />
diff --git a/redmine/app/views/roles/_form.rhtml b/redmine/app/views/roles/_form.rhtml
index 02eef4717..cc30e82b0 100644
--- a/redmine/app/views/roles/_form.rhtml
+++ b/redmine/app/views/roles/_form.rhtml
@@ -1,5 +1,6 @@
<%= error_messages_for 'role' %>
+<div class="box">
<!--[form:role]-->
<p><label for="role_name"><%=_('Name')%> <span class="required">*</span></label><br />
<%= text_field 'role', 'name' %></p>
@@ -10,7 +11,7 @@
<fieldset><legend><%= _(Permission::GROUPS[group_id]) %></legend>
<% permissions[group_id].each do |p| %>
<div style="width:200px;float:left;"><%= check_box_tag "permission_ids[]", p.id, (@role.permissions.include? p) %>
- <%= _(p.descr) %>
+ <%= _(p.description) %>
</div>
<% end %>
</fieldset>
@@ -19,4 +20,4 @@
<a href="javascript:checkAll('role_form', true)"><%=_('Check all')%></a> |
<a href="javascript:checkAll('role_form', false)"><%=_('Uncheck all')%></a><br />
<!--[eoform:role]-->
-
+</div>
diff --git a/redmine/app/views/trackers/_form.rhtml b/redmine/app/views/trackers/_form.rhtml
index 95d06d777..0eab8e96a 100644
--- a/redmine/app/views/trackers/_form.rhtml
+++ b/redmine/app/views/trackers/_form.rhtml
@@ -1,7 +1,7 @@
<%= error_messages_for 'tracker' %>
<!--[form:tracker]-->
-<p><label for="tracker_name"><%=_('Name')%></label><br/>
+<p><label for="tracker_name"><%=_('Name')%></label> <span class="required">*</span><br/>
<%= text_field 'tracker', 'name' %></p>
<p><%= check_box 'tracker', 'is_in_chlog' %>
diff --git a/redmine/app/views/users/_form.rhtml b/redmine/app/views/users/_form.rhtml
index 6574cb026..84cc6f171 100644
--- a/redmine/app/views/users/_form.rhtml
+++ b/redmine/app/views/users/_form.rhtml
@@ -1,31 +1,37 @@
<%= error_messages_for 'user' %>
+<div class="box">
<!--[form:user]-->
-<p><label for="user_login"><%=_('Login')%></label><br/>
+<p><label for="user_login"><%=_('Login')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'login', :size => 25 %></p>
-<p><label for="password"><%=_('Password')%></label><br/>
+<p><label for="password"><%=_('Password')%></label> <span class="required">*</span><br/>
<%= password_field_tag 'password', nil, :size => 25 %></p>
-<p><label for="password_confirmation"><%=_('Confirmation')%></label><br/>
+<p><label for="password_confirmation"><%=_('Confirmation')%></label> <span class="required">*</span><br/>
<%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
-<p><label for="user_firstname"><%=_('Firstname')%></label><br/>
+<p><label for="user_firstname"><%=_('Firstname')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'firstname' %></p>
-<p><label for="user_lastname"><%=_('Lastname')%></label><br/>
+<p><label for="user_lastname"><%=_('Lastname')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'lastname' %></p>
-<p><label for="user_mail"><%=_('Mail')%></label><br/>
+<p><label for="user_mail"><%=_('Mail')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'mail' %></p>
<p><label for="user_language"><%=_('Language')%></label><br/>
-<%= select("user", "language", Localization.langs) %></p>
+<%= select("user", "language", Localization.langs.invert) %></p>
+
+<% for custom_value in @custom_values %>
+ <p><%= custom_field_tag_with_label custom_value %></p>
+<% end %>
+
+<div style="clear: both;"></div>
<p><%= check_box 'user', 'admin' %> <label for="user_admin"><%=_('Administrator')%></label></p>
<p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p>
-<p><%= check_box 'user', 'locked' %> <label for="user_locked"><%=_('Locked')%></label></p>
<!--[eoform:user]-->
-
+</div>
diff --git a/redmine/app/views/users/list.rhtml b/redmine/app/views/users/list.rhtml
index 3e3c21659..7263000aa 100644
--- a/redmine/app/views/users/list.rhtml
+++ b/redmine/app/views/users/list.rhtml
@@ -7,7 +7,7 @@
<%= sort_header_tag('lastname', :caption => _('Lastname')) %>
<th><%=_('Mail')%></th>
<%= sort_header_tag('admin', :caption => _('Admin')) %>
- <%= sort_header_tag('locked', :caption => _('Locked')) %>
+ <%= sort_header_tag('status', :caption => _('Status')) %>
<%= sort_header_tag('created_on', :caption => _('Created on')) %>
<%= sort_header_tag('last_login_on', :caption => _('Last login')) %>
<th></th>
@@ -25,10 +25,10 @@
<td align="center">
<%= start_form_tag :action => 'edit', :id => user %>
<% if user.locked? %>
- <%= hidden_field_tag 'user[locked]', 0 %>
+ <%= hidden_field_tag 'user[status]', User::STATUS_ACTIVE %>
<%= submit_tag _('Unlock'), :class => "button-small" %>
<% else %>
- <%= hidden_field_tag 'user[locked]', 1 %>
+ <%= hidden_field_tag 'user[status]', User::STATUS_LOCKED %>
<%= submit_tag _('Lock'), :class => "button-small" %>
<% end %>
<%= end_form_tag %>
diff --git a/redmine/app/views/versions/_form.rhtml b/redmine/app/views/versions/_form.rhtml
index 71c761e3d..a62d22d84 100644
--- a/redmine/app/views/versions/_form.rhtml
+++ b/redmine/app/views/versions/_form.rhtml
@@ -4,8 +4,8 @@
<p><label for="version_name"><%=_('Version')%></label> <span class="required">*</span><br/>
<%= text_field 'version', 'name', :size => 20 %></p>
-<p><label for="version_descr"><%=_('Description')%></label><br/>
-<%= text_field 'version', 'descr', :size => 60 %></p>
+<p><label for="version_description"><%=_('Description')%></label><br/>
+<%= text_field 'version', 'description', :size => 60 %></p>
<p><label for="version_effective_date"><%=_('Date')%></label><br/>
<%= date_select 'version', 'effective_date' %></p>
diff --git a/redmine/app/views/welcome/index.rhtml b/redmine/app/views/welcome/index.rhtml
index 89a18f105..694de9b7b 100644
--- a/redmine/app/views/welcome/index.rhtml
+++ b/redmine/app/views/welcome/index.rhtml
@@ -1,12 +1,13 @@
<div class="splitcontentleft">
- <h2><%=_('Welcome')%> !</h2>
-
+ <h2><%= $RDM_WELCOME_TITLE || _('Welcome') %> !</h2>
+ <p><%= $RDM_WELCOME_TEXT %></p>
+
<div class="box">
<h3><%=_('Latest news')%></h3>
<% for news in @news %>
<p>
<b><%= news.title %></b> (<%= link_to_user news.author %> <%= format_time(news.created_on) %> - <%= news.project.name %>)<br />
- <%= news.shortdescr %><br />
+ <%= news.summary %><br />
[<%= link_to 'Read...', :controller => 'news', :action => 'show', :id => news %>]
</p>
<hr />
@@ -21,7 +22,7 @@
<% for project in @projects %>
<li>
<%= link_to project.name, :controller => 'projects', :action => 'show', :id => project %> (added <%= format_time(project.created_on) %>)<br />
- <%= project.descr %>
+ <%= project.description %>
</li>
<% end %>
</ul>