]> source.dussan.org Git - redmine.git/commitdiff
* new report: project activity
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 12 Nov 2006 18:50:30 +0000 (18:50 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 12 Nov 2006 18:50:30 +0000 (18:50 +0000)
* "start date" and "% done" fields added on issues
* project calendar added
* gantt chart added (exportable to pdf)
* multiple file upload for issues attachments
* user custom field displayed on account/show
* default configuration improved (default roles, trackers, status, permissions and workflows)
* fixed: project settings now displayed according to user's permissions

git-svn-id: http://redmine.rubyforge.org/svn/trunk@44 e93f8b46-1217-0410-a6f0-8f06a7374b81

61 files changed:
redmine/app/controllers/account_controller.rb
redmine/app/controllers/issues_controller.rb
redmine/app/controllers/projects_controller.rb
redmine/app/controllers/users_controller.rb
redmine/app/helpers/application_helper.rb
redmine/app/models/issue.rb
redmine/app/views/account/show.rhtml
redmine/app/views/issues/change_status.rhtml
redmine/app/views/issues/edit.rhtml
redmine/app/views/issues/show.rhtml
redmine/app/views/layouts/base.rhtml
redmine/app/views/news/_form.rhtml
redmine/app/views/news/show.rhtml
redmine/app/views/projects/_form.rhtml
redmine/app/views/projects/activity.rhtml
redmine/app/views/projects/add_issue.rhtml
redmine/app/views/projects/calendar.rhtml [new file with mode: 0644]
redmine/app/views/projects/gantt.rfpdf [new file with mode: 0644]
redmine/app/views/projects/gantt.rhtml [new file with mode: 0644]
redmine/app/views/projects/list_issues.rhtml
redmine/app/views/projects/list_news.rhtml
redmine/app/views/projects/settings.rhtml
redmine/app/views/projects/show.rhtml
redmine/app/views/reports/issue_report.rhtml
redmine/app/views/users/_form.rhtml
redmine/config/config_custom.example.rb [new file with mode: 0644]
redmine/config/config_custom.rb [deleted file]
redmine/config/environment.rb
redmine/db/migrate/005_issue_start_date.rb [new file with mode: 0644]
redmine/db/migrate/006_calendar_and_activity.rb [new file with mode: 0644]
redmine/doc/CHANGELOG
redmine/doc/INSTALL
redmine/lang/de.yml
redmine/lang/en.yml
redmine/lang/es.yml
redmine/lang/fr.yml
redmine/lib/tasks/load_default_data.rake
redmine/public/images/add.png [new file with mode: 0644]
redmine/public/images/arrow_bw.png [new file with mode: 0644]
redmine/public/images/arrow_from.png [new file with mode: 0644]
redmine/public/images/arrow_to.png [new file with mode: 0644]
redmine/public/images/attachment.png [new file with mode: 0644]
redmine/public/images/details.png [new file with mode: 0644]
redmine/public/images/gantt.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_br.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_code.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_del.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_em.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_ins.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_link.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_ol.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_quote.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_strong.png [new file with mode: 0644]
redmine/public/images/jstoolbar/bt_ul.png [new file with mode: 0644]
redmine/public/images/zoom_in.png [new file with mode: 0644]
redmine/public/images/zoom_in_g.png [new file with mode: 0644]
redmine/public/images/zoom_out.png [new file with mode: 0644]
redmine/public/images/zoom_out_g.png [new file with mode: 0644]
redmine/public/javascripts/application.js
redmine/public/javascripts/jstoolbar.js
redmine/public/stylesheets/application.css

index 22ac8609a6d594a2d0155932291acd05e659e4e2..7031d71ec2fda5ea3bc69fafc40d1a99d61dfec5 100644 (file)
@@ -27,6 +27,7 @@ class AccountController < ApplicationController
   # Show user's account\r
   def show\r
     @user = User.find(params[:id])\r
+    @custom_values = @user.custom_values.find(:all, :include => :custom_field)\r
   end\r
 \r
   # Login request and validation\r
index d428c75bfee95ed9071bbfd598005f1ee232c0df..c279e64301d142ad8882fc4b6536091de2f572c2 100644 (file)
@@ -81,6 +81,7 @@ class IssuesController < ApplicationController
         @issue.status = @history.status\r
         @issue.fixed_version_id = (params[:issue][:fixed_version_id])\r
         @issue.assigned_to_id = (params[:issue][:assigned_to_id])\r
+        @issue.done_ratio = (params[:issue][:done_ratio])\r
         @issue.lock_version = (params[:issue][:lock_version])\r
         if @issue.save\r
           flash[:notice] = l(:notice_successful_update)\r
@@ -124,5 +125,6 @@ private
   def find_project\r
     @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])\r
     @project = @issue.project\r
+    @html_title = "#{@project.name} - #{@issue.tracker.name} ##{@issue.id}"\r
   end  
 end
index 9e1dc14ef23d696ec23fc8558fd5e809d3c7a5b4..0198e975fa8d2bb3adb97139a52051ff48521a02 100644 (file)
@@ -182,7 +182,8 @@ class ProjectsController < ApplicationController
     @tracker = Tracker.find(params[:tracker_id])\r
     @priorities = Enumeration::get_values('IPRI')\r
     @issue = Issue.new(:project => @project, :tracker => @tracker)\r
-    if request.get?      \r
+    if request.get?\r
+      @issue.start_date = Date.today\r
       @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }\r
     else\r
       @issue.attributes = params[:issue]\r
@@ -214,7 +215,7 @@ class ProjectsController < ApplicationController
       @results_per_page = params[:per_page].to_i\r
       session[:results_per_page] = @results_per_page\r
     else\r
-      @results_per_page = session[:results_per_page] || @results_per_page_options.first\r
+      @results_per_page = session[:results_per_page] || 25\r
     end\r
 \r
     @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)           \r
@@ -356,16 +357,22 @@ class ProjectsController < ApplicationController
   end\r
 \r
   def activity\r
-    @date_from = begin\r
-      params[:date_from].to_date\r
-    rescue\r
-    end || Date.today\r
-    @days_back = params[:days_back] ? params[:days_back].to_i : 15\r
-    @date_to = @date_from - @days_back\r
+    if params[:year] and params[:year].to_i > 1900\r
+      @year = params[:year].to_i\r
+      if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13\r
+        @month = params[:month].to_i\r
+      end    \r
+    end\r
+    @year ||= Date.today.year\r
+    @month ||= Date.today.month\r
+\r
+    @date_from = Date.civil(@year, @month, 1)\r
+    @date_to = (@date_from >> 1)-1\r
+    \r
     @events_by_day = {}    \r
     \r
     unless params[:show_issues] == "0"\r
-      @project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on<=? and issues.created_on>=?", @date_from+1, @date_to], :order => "issues.created_on asc" ).each { |i|\r
+      @project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on>=? and issues.created_on<=?", @date_from, @date_to] ).each { |i|\r
         @events_by_day[i.created_on.to_date] ||= []\r
         @events_by_day[i.created_on.to_date] << i\r
       }\r
@@ -373,7 +380,7 @@ class ProjectsController < ApplicationController
     end\r
     \r
     unless params[:show_news] == "0"\r
-      @project.news.find(:all, :conditions => ["news.created_on<=? and news.created_on>=?", @date_from+1, @date_to], :order => "news.created_on asc" ).each { |i|\r
+      @project.news.find(:all, :conditions => ["news.created_on>=? and news.created_on<=?", @date_from, @date_to] ).each { |i|\r
         @events_by_day[i.created_on.to_date] ||= []\r
         @events_by_day[i.created_on.to_date] << i\r
       }\r
@@ -381,7 +388,7 @@ class ProjectsController < ApplicationController
     end\r
     \r
     unless params[:show_files] == "0"\r
-      Attachment.find(:all, :joins => "LEFT JOIN versions ON versions.id = attachments.container_id", :conditions => ["attachments.container_type='Version' and versions.project_id=? and attachments.created_on<=? and attachments.created_on>=?", @project.id, @date_from+1, @date_to], :order => "attachments.created_on asc" ).each { |i|\r
+      Attachment.find(:all, :joins => "LEFT JOIN versions ON versions.id = attachments.container_id", :conditions => ["attachments.container_type='Version' and versions.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to] ).each { |i|\r
         @events_by_day[i.created_on.to_date] ||= []\r
         @events_by_day[i.created_on.to_date] << i\r
       }\r
@@ -389,7 +396,7 @@ class ProjectsController < ApplicationController
     end\r
     \r
     unless params[:show_documentss] == "0"\r
-      Attachment.find(:all, :joins => "LEFT JOIN documents ON documents.id = attachments.container_id", :conditions => ["attachments.container_type='Document' and documents.project_id=? and attachments.created_on<=? and attachments.created_on>=?", @project.id, @date_from+1, @date_to], :order => "attachments.created_on asc" ).each { |i|\r
+      Attachment.find(:all, :joins => "LEFT JOIN documents ON documents.id = attachments.container_id", :conditions => ["attachments.container_type='Document' and documents.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to] ).each { |i|\r
         @events_by_day[i.created_on.to_date] ||= []\r
         @events_by_day[i.created_on.to_date] << i\r
       }\r
@@ -397,12 +404,64 @@ class ProjectsController < ApplicationController
     end\r
 \r
   end\r
+  \r
+  def calendar\r
+    if params[:year] and params[:year].to_i > 1900\r
+      @year = params[:year].to_i\r
+      if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13\r
+        @month = params[:month].to_i\r
+      end    \r
+    end\r
+    @year ||= Date.today.year\r
+    @month ||= Date.today.month\r
+    \r
+    @date_from = Date.civil(@year, @month, 1)\r
+    @date_to = (@date_from >> 1)-1\r
+    # start on monday\r
+    @date_from = @date_from - (@date_from.cwday-1)\r
+    # finish on sunday\r
+    @date_to = @date_to + (7-@date_to.cwday)  \r
+      \r
+    @issues = @project.issues.find(:all, :include => :tracker, :conditions => ["((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", @date_from, @date_to, @date_from, @date_to])\r
+    render :layout => false if request.xhr?\r
+  end  \r
+\r
+  def gantt\r
+    if params[:year] and params[:year].to_i >0\r
+      @year_from = params[:year].to_i\r
+      if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12\r
+        @month_from = params[:month].to_i\r
+      else\r
+        @month_from = 1\r
+      end\r
+    else\r
+      @month_from ||= (Date.today << 1).month\r
+      @year_from ||= (Date.today << 1).year\r
+    end\r
+    \r
+    @zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2\r
+    @months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6\r
+    \r
+    @date_from = Date.civil(@year_from, @month_from, 1)\r
+    @date_to = (@date_from >> @months) - 1\r
+    @issues = @project.issues.find(:all, :order => "start_date, due_date", :conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null)", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to])\r
+    \r
+    if params[:output]=='pdf'\r
+      @options_for_rfpdf ||= {}\r
+      @options_for_rfpdf[:file_name] = "gantt.pdf"\r
+      render :template => "projects/gantt.rfpdf", :layout => false\r
+    else\r
+      render :template => "projects/gantt.rhtml"\r
+    end\r
+  end\r
+  \r
 private\r
   # Find project of id params[:id]\r
   # if not found, redirect to project list\r
   # Used as a before_filter\r
   def find_project\r
-    @project = Project.find(params[:id])               \r
+    @project = Project.find(params[:id])\r
+    @html_title = @project.name\r
   rescue
     redirect_to :action => 'list'                      \r
   end\r
index dee9e9d6be13c779d3f0802a14c6723f0860d4dd..47d0e51c94462d9a8a7a86729afa3708ac91641a 100644 (file)
@@ -51,14 +51,15 @@ class UsersController < ApplicationController
       @user = User.new(params[:user])\r
       @user.admin = params[:user][:admin] || false\r
       @user.login = params[:user][:login]\r
-      @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]\r
+      @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id\r
       @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }\r
       @user.custom_values = @custom_values                     \r
       if @user.save
         flash[:notice] = l(:notice_successful_create)
         redirect_to :action => 'list'
       end\r
-    end
+    end\r
+    @auth_sources = AuthSource.find(:all)
   end
 
   def edit
@@ -68,7 +69,7 @@ class UsersController < ApplicationController
     else\r
       @user.admin = params[:user][:admin] if params[:user][:admin]\r
       @user.login = params[:user][:login] if params[:user][:login]\r
-      @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty?\r
+      @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty? or @user.auth_source_id\r
       if params[:custom_fields]\r
         @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }\r
         @user.custom_values = @custom_values\r
@@ -78,6 +79,7 @@ class UsersController < ApplicationController
         redirect_to :action => 'list'
       end\r
     end
+    @auth_sources = AuthSource.find(:all)\r
   end
 
   def destroy
index 835ac485913bf6b7943049d4793a5c383f438b83..378545eb19726f8f0b7471c4b7d689645c15ce56 100644 (file)
@@ -57,6 +57,10 @@ module ApplicationHelper
   def format_time(time)\r
     l_datetime(time) if time\r
   end\r
+  \r
+  def day_name(day)\r
+    l(:general_day_names).split(',')[day-1]\r
+  end\r
 \r
   def pagination_links_full(paginator, options={}, html_options={})\r
     html = ''    \r
@@ -76,6 +80,10 @@ module ApplicationHelper
     html  \r
   end\r
   \r
+  def textilizable(text)\r
+    $RDM_TEXTILE_DISABLED ? text : textilize(text)\r
+  end\r
+  \r
   def error_messages_for(object_name, options = {})\r
     options = options.symbolize_keys\r
     object = instance_variable_get("@#{object_name}")\r
index 5f2a600e158f6a16144edd6fa0e2dcae76708614..4834e069f4a09f03ae6d6f7cca9903436afe2420 100644 (file)
@@ -33,6 +33,7 @@ class Issue < ActiveRecord::Base
   has_many :custom_fields, :through => :custom_values\r
 \r
   validates_presence_of :subject, :description, :priority, :tracker, :author, :status\r
+  validates_inclusion_of :done_ratio, :in => 0..100\r
   validates_associated :custom_values, :on => :update\r
 \r
   # set default status for new issues\r
@@ -44,6 +45,10 @@ class Issue < ActiveRecord::Base
     if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?\r
       errors.add :due_date, :activerecord_error_not_a_date\r
     end\r
+    \r
+    if self.due_date and self.start_date and self.due_date < self.start_date\r
+      errors.add :due_date, :activerecord_error_greater_than_start_date\r
+    end\r
   end\r
 \r
   def before_create\r
index 78fe0a679eb45f714067edbb7bd27bb7cd2e9579..4fa3067649434a645fe26f26a2969238c67e75bf 100644 (file)
@@ -1,8 +1,15 @@
 <h2><%= @user.display_name %></h2>\r
 \r
 <p>\r
-<%= mail_to @user.mail %><br />\r
-<%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %>\r
+<%= mail_to @user.mail %>\r
+<ul>\r
+    <li><%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %></li>\r
+<% for custom_value in @custom_values %>\r
+<% if !custom_value.value.empty? %>\r
+    <li><%= custom_value.custom_field.name%>: <%= show_value(custom_value) %></li>\r
+<% end %>\r
+<% end %>\r
+</ul>\r
 </p>\r
 \r
 <h3><%=l(:label_project_plural)%></h3>\r
index e525de60d4b59401311e11dfb658a412b70eef6a..0fe07ad23980fa00cf89a70a5bd2668a919e416e 100644 (file)
 <option value=""></option>\r
 <%= options_from_collection_for_select @assignable_to, "id", "display_name", @issue.assigned_to_id %></p>
 </select></p>\r
+
+
+<p><label for="issue_done_ratio"><%=l(:field_done_ratio)%></label>
+<%= select("issue", "done_ratio", ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) ) %>
+</select></p>
+
 \r
 <p><label for="issue_fixed_version"><%=l(:field_fixed_version)%></label>
 <select name="issue[fixed_version_id]">\r
index 3d6da398422bed6ad977746d4a907b9c19f44056..6044fa9fde419b572c686e037b9b72002cd81b4a 100644 (file)
@@ -4,14 +4,22 @@
 <%= error_messages_for 'issue' %>
 <div class="box">
 <!--[form:issue]-->
+<div class="splitcontentleft">
 <p><label><%=l(:field_status)%></label> <%= @issue.status.name %></p>
-
 <p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
 <p><%= f.select :assigned_to_id, (@issue.project.members.collect {|m| [m.name, m.user_id]}), :include_blank => true %></p>
 <p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}) %></p>
+</div>
+
+<div class="splitcontentright">
+<p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
+<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
+<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
+</div>
+
+<div class="clear">
 <p><%= f.text_field :subject, :size => 80, :required => true %></p>
 <p><%= f.text_area :description, :cols => 60, :rows => 10, :required => true %></p>
-<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
 
 <% for @custom_value in @custom_values %>
        <p><%= custom_field_tag_with_label @custom_value %></p>
 
 <p><%= f.select :fixed_version_id, (@project.versions.collect {|v| [v.name, v.id]}), { :include_blank => true } %>
 </select></p>
+</div>
 <!--[eoform:issue]-->
 </div>
 <%= f.hidden_field :lock_version %>
 <%= submit_tag l(:button_save) %>
 <% end %>
 
+<% unless $RDM_TEXTILE_DISABLED %>
 <%= javascript_include_tag 'jstoolbar' %>
 <script type="text/javascript">
 //<![CDATA[
-jsToolBar.prototype.base_url = 'http://callmepep.org'; 
-jsToolBar.prototype.legend_msg = 'You can use the following shortcuts to format your text.'; 
-jsToolBar.prototype.elements.strong.title = 'Strong emphasis'; 
-jsToolBar.prototype.elements.em.title = 'Emphasis'; 
-jsToolBar.prototype.elements.ins.title = 'Inserted'; 
-jsToolBar.prototype.elements.del.title = 'Deleted'; 
-jsToolBar.prototype.elements.quote.title = 'Inline quote'; 
-jsToolBar.prototype.elements.code.title = 'Code'; 
-jsToolBar.prototype.elements.br.title = 'Line break'; 
-jsToolBar.prototype.elements.ul.title = 'Unordered list'; 
-jsToolBar.prototype.elements.ol.title = 'Ordered list'; 
-jsToolBar.prototype.elements.link.title = 'Link'; 
-jsToolBar.prototype.elements.link.href_prompt = 'URL?'; 
-jsToolBar.prototype.elements.link.hreflang_prompt = 'Language?'; 
-
 if (document.getElementById) { 
        if (document.getElementById('issue_description')) { 
                var commentTb = new jsToolBar(document.getElementById('issue_description')); 
                commentTb.draw(); 
        }
 }
-
 //]]>
-</script>
\ No newline at end of file
+</script>
+<% end %>
\ No newline at end of file
index 104d33654dbae756a0b683c9d98501fadaa1cc7d..43b7d0449f4d0b5c916b5d359c7846b63a9f23de 100644 (file)
     <td width="15%"><b><%=l(:field_priority)%> :</b></td><td width="35%"><%= @issue.priority.name %></td>\r
 </tr>\r
 <tr>\r
-    <td><b><%=l(:field_author)%> :</b></td><td><%= link_to_user @issue.author %></td>\r
+    <td><b><%=l(:field_assigned_to)%> :</b></td><td><%= @issue.assigned_to ? @issue.assigned_to.name : "-" %></td>\r
     <td><b><%=l(:field_category)%> :</b></td><td><%= @issue.category ? @issue.category.name : "-" %></td>\r
 </tr>\r
+<tr>\r
+    <td><b><%=l(:field_author)%> :</b></td><td><%= link_to_user @issue.author %></td>\r
+    <td><b><%=l(:field_start_date)%> :</b></td><td><%= format_date(@issue.start_date) %></td>\r
+</tr>\r
 <tr>\r
     <td><b><%=l(:field_created_on)%> :</b></td><td><%= format_date(@issue.created_on) %></td>\r
-    <td><b><%=l(:field_assigned_to)%> :</b></td><td><%= @issue.assigned_to ? @issue.assigned_to.name : "-" %></td>\r
+    <td><b><%=l(:field_due_date)%> :</b></td><td><%= format_date(@issue.due_date) %></td>\r
 </tr>\r
 <tr>\r
     <td><b><%=l(:field_updated_on)%> :</b></td><td><%= format_date(@issue.updated_on) %></td>\r
-    <td><b><%=l(:field_due_date)%> :</b></td><td><%= format_date(@issue.due_date) %></td>\r
+    <td><b><%=l(:field_done_ratio)%> :</b></td><td><%= @issue.done_ratio %> %</td>\r
 </tr>\r
 <tr>\r
 <% n = 0\r
@@ -39,7 +43,7 @@ end %>
 <br />\r
 \r
 <b><%=l(:field_description)%> :</b><br /><br />\r
-<%= textilize @issue.description %>\r
+<%= textilizable @issue.description %>\r
 \r
 <p>\r
 <% if authorize_for('issues', 'edit') %>\r
@@ -98,7 +102,7 @@ end %>
 <table width="100%">\r
 <% for attachment in @issue.attachments %>\r
 <tr>\r
-<td><%= link_to attachment.filename, :action => 'download', :id => @issue, :attachment_id => attachment %> (<%= human_size(attachment.filesize) %>)</td>\r
+<td><%= image_tag('attachment') %> <%= link_to attachment.filename, :action => 'download', :id => @issue, :attachment_id => attachment %> (<%= human_size(attachment.filesize) %>)</td>\r
 <td><%= format_date(attachment.created_on) %></td>\r
 <td><%= attachment.author.display_name %></td>\r
 <% if authorize_for('issues', 'destroy_attachment') %>\r
@@ -114,8 +118,8 @@ end %>
 <br />\r
 <% if authorize_for('issues', 'add_attachment') %>\r
   <%= start_form_tag ({ :controller => 'issues', :action => 'add_attachment', :id => @issue }, :multipart => true, :class => "tabular") %>\r
-  <p id="attachments_p"><label><%=l(:label_attachment_new)%>\r
-  <%= link_to_function image_tag('add', :align => "top"), "addFileField()" %></label>\r
+  <p id="attachments_p"><label><%=l(:label_attachment_new)%>&nbsp;\r
+  <%= link_to_function image_tag('add'), "addFileField()" %></label>\r
   <%= file_field_tag 'attachments[]', :size => 30  %></p>\r
   <%= submit_tag l(:button_add) %>\r
   <%= end_form_tag %> \r
index 7825442ffb955e6693202f0ce53f4743efd971c4..e04d3cdeacec65b9bbe31e60bab51fd692442121 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
 <head>\r
-<title><%= $RDM_HEADER_TITLE %></title>\r
+<title><%= $RDM_HEADER_TITLE + (@html_title ? ": #{@html_title}" : "") %></title>\r
 <meta http-equiv="content-type" content="text/html; charset=utf-8" />\r
 <meta name="description" content="redMine" />\r
 <meta name="keywords" content="issue,bug,tracker" />\r
@@ -37,6 +37,7 @@ var menu_contenu=' \
  \\r
 <% unless @project.nil? || @project.id.nil? %> \\r
 <div id="menuProject" class="menu" onmouseover="menuMouseover(event)"> \\r
+<%= link_to l(:label_calendar), {:controller => 'projects', :action => 'calendar', :id => @project }, :class => "menuItem" %> \\r
 <%= link_to l(:label_issue_plural), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %> \\r
 <%= link_to l(:label_report_plural), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %> \\r
 <%= link_to l(:label_activity), {:controller => 'projects', :action => 'activity', :id => @project }, :class => "menuItem" %> \\r
@@ -101,6 +102,7 @@ var menu_contenu=' \
                        <h2><%= @project.name %></h2>\r
                        <ul class="menublock">\r
                                <li><%= link_to l(:label_overview), :controller => 'projects', :action => 'show', :id => @project %></li>\r
+                               <li><%= link_to l(:label_calendar), :controller => 'projects', :action => 'calendar', :id => @project %></li>\r
                                <li><%= link_to l(:label_issue_plural), :controller => 'projects', :action => 'list_issues', :id => @project %></li>\r
                                <li><%= link_to l(:label_report_plural), :controller => 'reports', :action => 'issue_report', :id => @project %></li>\r
                                <li><%= link_to l(:label_activity), :controller => 'projects', :action => 'activity', :id => @project %></li>\r
@@ -120,7 +122,7 @@ var menu_contenu=' \
                                        <li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %></li>\r
                                <% end %>\r
                        </ul>\r
-               <% end %>               \r
+               <% end %>\r
        </div>\r
 \r
        <div id="content">\r
index 02bb824d9c700c637814fe51a1837ad3ba590437..c04c3b242a9d661030130785dc1d02e4e03aca49 100644 (file)
@@ -3,4 +3,18 @@
 <p><%= f.text_field :title, :required => true, :size => 60 %></p>
 <p><%= f.text_area :summary, :cols => 60, :rows => 2 %></p>
 <p><%= f.text_area :description, :required => true, :cols => 60, :rows => 10 %></p>
-</div>
\ No newline at end of file
+</div>
+
+<% unless $RDM_TEXTILE_DISABLED %>
+<%= javascript_include_tag 'jstoolbar' %>
+<script type="text/javascript">
+//<![CDATA[
+if (document.getElementById) { 
+       if (document.getElementById('news_description')) { 
+               var commentTb = new jsToolBar(document.getElementById('news_description')); 
+               commentTb.draw(); 
+       }
+}
+//]]>
+</script>
+<% end %>
\ No newline at end of file
index bea9af4fb55539fea96edde3f8f4c470cbaf8948..fcc206072ff0b654830cfb1e40ed49473f601834 100644 (file)
@@ -6,7 +6,7 @@
 <b><%=l(:field_created_on)%></b>: <%= format_time(@news.created_on) %>\r
 </p>\r
 \r
-<%= simple_format auto_link @news.description %>
+<%= textilizable auto_link @news.description %>
 \r
 <% if authorize_for('news', 'edit') %>\r
   <%= start_form_tag ({:controller => 'news', :action => 'edit', :id => @news}, :method => 'get' ) %>\r
index 889404bbc2d66b00253d3ec334aad30bc57834eb..ab0b35fabc45cb7040b301d29bfaec14578433ba 100644 (file)
@@ -3,7 +3,7 @@
 <!--[form:project]-->
 <p><%= f.text_field :name, :required => true %></p>
 
-<% if admin_loggedin? %>
+<% if admin_loggedin? and !@root_projects.empty? %>
     <p><%= f.select :parent_id, (@root_projects.collect {|p| [p.name, p.id]}), { :include_blank => true } %></p>
 <% end %>
 
 <% for @custom_value in @custom_values %>
        <p><%= custom_field_tag_with_label @custom_value %></p>
 <% end %>\r
-\r
-<p><label><%=l(:label_custom_field_plural)%></label>\r
+
+<% unless @custom_fields.empty? %>
+<p><label><%=l(:label_custom_field_plural)%></label>
 <% for custom_field in @custom_fields %>
-       <%= check_box_tag "custom_field_ids[]", custom_field.id, (@project.custom_fields.include? custom_field) %>\r
+       <%= check_box_tag "custom_field_ids[]", custom_field.id, ((@project.custom_fields.include? custom_field) or custom_field.is_for_all?), (custom_field.is_for_all? ? {:disabled => "disabled"} : {}) %>\r
        <%= custom_field.name %>        \r
-<% end %></p>\r
+<% end %></p>
+<% end %>\r
 <!--[eoform:project]-->\r
 </div>
index 9f5a5d3c911cc1745a14c53c5ad329c6c25f2ced..84275a6e6a59212d959cc81bb55db238866a3241 100644 (file)
@@ -3,8 +3,8 @@
 <div>\r
 <div class="rightbox">\r
   <%= start_form_tag %>\r
-    <p>From <%= text_field_tag 'date_from', @date_from, :size => 10, :class => 'button-small' %>\r
-    and <%= text_field_tag 'days_back', @days_back, :size => 2, :class => 'button-small' %> days back</p>\r
+<p><%= select_month(@month, :prefix => "month", :discard_type => true) %>\r
+<%= select_year(@year, :prefix => "year", :discard_type => true) %></p>\r
     <%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0 %> <%=l(:label_issue_plural)%><br />\r
     <%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0 %> <%=l(:label_news_plural)%><br />\r
     <%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0 %> <%=l(:label_attachment_plural)%><br />\r
@@ -15,7 +15,7 @@
 <% @events_by_day.keys.sort {|x,y| y <=> x }.each do |day| %>\r
   <h3><%= format_date(day) %></h3>\r
   <ul>\r
-  <% @events_by_day[day].each do |e| %>\r
+  <% @events_by_day[day].sort {|x,y| y.created_on <=> x.created_on }.each do |e| %>\r
     <li><p>\r
     <% if e.is_a? Issue %>\r
       <%= e.created_on.strftime("%H:%M") %> <%= e.tracker.name %> <%= link_to e.long_id, :controller => 'issues', :action => 'show', :id => e %> (<%= e.status.name %>): <%= e.subject %><br />\r
@@ -36,8 +36,6 @@
   <% end %>\r
   </ul>\r
 <% end %>\r
-  <br />\r
-\r
-\r
-\r
+<% if @events_by_day.empty? %><p><i><%= l(:label_no_data) %></i></p><% end %>\r
+<br />\r
 </div>
\ No newline at end of file
index 3e22940b3b365f10fcd986bda3ff4958e48de880..b60f91a2e988786f47dc76ad07189d85757e36a1 100644 (file)
@@ -5,23 +5,46 @@
 <div class="box">
 <!--[form:issue]-->
 <%= hidden_field_tag 'tracker_id', @tracker.id %>
-\r
+
+<div class="splitcontentleft">
 <p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>\r
 <p><%= f.select :assigned_to_id, (@issue.project.members.collect {|m| [m.name, m.user_id]}), :include_blank => true %></p>\r
 <p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %></p>\r
+</div>
+<div class="splitcontentright">
+<p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
+<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
+<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
+</div>
+
+<div class="clear">
 <p><%= f.text_field :subject, :size => 80, :required => true %></p>
 <p><%= f.text_area :description, :cols => 60, :rows => 10, :required => true %></p>
-<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
 \r
 <% for @custom_value in @custom_values %>
        <p><%= custom_field_tag_with_label @custom_value %></p>
 <% end %>\r
 \r
-<p id="attachments_p"><label for="attachment_file"><%=l(:label_attachment)%>
-<%= link_to_function image_tag('add', :align => "top"), "addFileField()" %></label>
+<p id="attachments_p"><label for="attachment_file"><%=l(:label_attachment)%>&nbsp;
+<%= link_to_function image_tag('add'), "addFileField()" %></label>
 <%= file_field_tag 'attachments[]', :size => 30  %></p>
-<!--[eoform:issue]-->\r
-</div>
 
+</div>
+<!--[eoform:issue]-->
+</div>
 <%= submit_tag l(:button_create) %>\r
+<% end %>
+
+<% unless $RDM_TEXTILE_DISABLED %>
+<%= javascript_include_tag 'jstoolbar' %>
+<script type="text/javascript">
+//<![CDATA[
+if (document.getElementById) { 
+       if (document.getElementById('issue_description')) { 
+               var commentTb = new jsToolBar(document.getElementById('issue_description')); 
+               commentTb.draw(); 
+       }
+}
+//]]>
+</script>
 <% end %>
\ No newline at end of file
diff --git a/redmine/app/views/projects/calendar.rhtml b/redmine/app/views/projects/calendar.rhtml
new file mode 100644 (file)
index 0000000..236184f
--- /dev/null
@@ -0,0 +1,71 @@
+<h2><%= l(:label_calendar) %></h2>\r
+\r
+<table width="100%">\r
+<tr>\r
+<td align="left">\r
+<%= start_form_tag :action => 'calendar', :id => @project %>\r
+<%= select_month(@month, :prefix => "month", :discard_type => true) %>\r
+<%= select_year(@year, :prefix => "year", :discard_type => true) %>\r
+<%= submit_tag l(:button_submit), :class => "button-small" %>\r
+<%= end_form_tag %>\r
+</td>\r
+<td align="right">\r
+<%= image_tag 'gantt' %>\r
+<%= link_to l(:label_gantt_chart), :action => 'gantt', :id => @project %>&nbsp;\r
+</td>\r
+</tr>\r
+</table>\r
+<br />\r
+\r
+<table class="calenderTable">\r
+<tr class="ListHead">\r
+<td></td>\r
+<% 1.upto(7) do |d| %>\r
+    <td align="center" width="14%"><%= day_name(d) %></td>\r
+<% end %>\r
+</tr>\r
+<tr height="100">\r
+<% day = @date_from\r
+while day <= @date_to\r
+       if day.cwday == 1 %>\r
+       <td valign="middle"><%= day.cweek %></td>\r
+       <% end %>       \r
+       <td valign="top" width="14%" class="<%= day.month==@month ? "even" : "odd" %>">\r
+       <p align="right"><%= day==Date.today ? "<b>#{day.day}</b>" : day.day %></p>     \r
+       <% day_issues = []\r
+       @issues.each { |i| day_issues << i if i.start_date == day or i.due_date == day } \r
+       day_issues.each do |i| %>       \r
+               <%= if day == i.start_date and day == i.due_date\r
+                   image_tag('arrow_bw')\r
+               elsif day == i.start_date\r
+                   image_tag('arrow_from') \r
+               elsif day == i.due_date\r
+                   image_tag('arrow_to') \r
+               end %>\r
+               <%= i.tracker.name %> <%= link_to i.id, :controller => 'issues', :action => 'show', :id => i %>: <small><%= i.subject.sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)') %></small><br />\r
+       <% end %>\r
+    </td>\r
+       <%= '</tr><tr height="100">' if day.cwday >= 7 and day!=@date_to %>\r
+       <%\r
+       day = day + 1\r
+end %>\r
+</tr>\r
+</table>\r
+\r
+<table width="100%">\r
+<tr>\r
+<td align="left">\r
+<%= link_to_remote ('&#171; ' + l(:label_previous)), \r
+                    {:update => "content", :url => { :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1) }},\r
+                    {:href => url_for(:action => 'calendar', :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1))}\r
+                    %>\r
+</td>\r
+<td align="right">\r
+<%= link_to_remote (l(:label_next) + ' &#187;'), \r
+                    {:update => "content", :url => { :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1) }},\r
+                    {:href => url_for(:action => 'calendar', :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1))}\r
+                    %>\r
+&nbsp;\r
+</td>\r
+</tr>\r
+</table>\r
diff --git a/redmine/app/views/projects/gantt.rfpdf b/redmine/app/views/projects/gantt.rfpdf
new file mode 100644 (file)
index 0000000..0ac0d75
--- /dev/null
@@ -0,0 +1,161 @@
+<%\r
+pdf=IfpdfHelper::IFPDF.new\r
+pdf.AliasNbPages\r
+pdf.AddPage("L")\r
+pdf.SetFont('Arial','B',9)\r
+\r
+subject_width = 70\r
+header_heigth = 5\r
+\r
+headers_heigth = header_heigth\r
+show_weeks = false\r
+show_days = false\r
+\r
+if @months < 7\r
+    show_weeks = true\r
+    headers_heigth = 2*header_heigth\r
+    if @months < 3\r
+        show_days = true\r
+        headers_heigth = 3*header_heigth\r
+    end\r
+end\r
+\r
+g_width = 210\r
+zoom = (g_width) / (@date_to - @date_from + 1)\r
+g_height = 120\r
+t_height = g_height + headers_heigth\r
+\r
+\r
+#\r
+# Months headers\r
+#\r
+month_f = @date_from\r
+left = subject_width\r
+height = header_heigth\r
+@months.times do \r
+       width = ((month_f >> 1) - month_f) * zoom \r
+       pdf.SetY(20)\r
+       pdf.SetX(left)\r
+       pdf.Cell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C")\r
+       left = left + width\r
+       month_f = month_f >> 1\r
+end  \r
+\r
+#\r
+# Weeks headers\r
+#\r
+if show_weeks\r
+       left = subject_width\r
+       height = header_heigth\r
+       if @date_from.cwday == 1\r
+           # @date_from is monday\r
+        week_f = @date_from\r
+       else\r
+           # find next monday after @date_from\r
+               week_f = @date_from + (7 - @date_from.cwday + 1)\r
+               width = (7 - @date_from.cwday + 1) * zoom-1\r
+               pdf.SetY(25)\r
+               pdf.SetX(left)\r
+               pdf.Cell(width + 1, height, "", "LTR")\r
+               left = left + width+1\r
+       end\r
+       while week_f < @date_to\r
+               width = (week_f + 6 <= @date_to) ? 7 * zoom : (@date_to - week_f + 1) * zoom\r
+               pdf.SetY(25)\r
+               pdf.SetX(left)\r
+               pdf.Cell(width, height, week_f.cweek.to_s, "LTR", 0, "C")\r
+               left = left + width\r
+               week_f = week_f+7\r
+       end\r
+end\r
+\r
+#\r
+# Days headers\r
+#\r
+if show_days\r
+       left = subject_width\r
+       height = header_heigth\r
+       wday = @date_from.cwday\r
+       pdf.SetFont('Arial','B',7)\r
+       (@date_to - @date_from + 1).to_i.times do \r
+               width = zoom\r
+               pdf.SetY(30)\r
+               pdf.SetX(left)\r
+               pdf.Cell(width, height, day_name(wday)[0,1], "LTR", 0, "C")\r
+               left = left + width\r
+               wday = wday + 1\r
+               wday = 1 if wday > 7\r
+       end\r
+end\r
+\r
+pdf.SetY(20)\r
+pdf.SetX(15)\r
+pdf.Cell(subject_width+g_width-15, headers_heigth, "", 1)\r
+\r
+\r
+#\r
+# Tasks\r
+#\r
+top = headers_heigth + 20\r
+pdf.SetFont('Arial','B',7)\r
+@issues.each do |i|\r
+       pdf.SetY(top)\r
+       pdf.SetX(15)\r
+       pdf.Cell(subject_width-15, 5, i.id.to_s + " " + i.subject.sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)'), "LR")\r
+\r
+       pdf.SetY(top)\r
+       pdf.SetX(subject_width)\r
+       pdf.Cell(g_width, 5, "", "LR")\r
+       \r
+       i_start_date = (i.start_date >= @date_from ? i.start_date : @date_from )\r
+       i_end_date = (i.due_date <= @date_to ? i.due_date : @date_to )\r
+       \r
+       i_done_date = i.start_date + ((i.due_date - i.start_date)*i.done_ratio/100).floor\r
+       i_done_date = (i_done_date <= @date_from ? @date_from : i_done_date )\r
+       i_done_date = (i_done_date >= @date_to ? @date_to : i_done_date )\r
+       \r
+       i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today\r
+       \r
+       i_left = ((i_start_date - @date_from)*zoom) \r
+       i_width = ((i_end_date - i_start_date + 1)*zoom)\r
+       d_width = ((i_done_date - i_start_date)*zoom)\r
+       l_width = ((i_late_date - i_start_date+1)*zoom) if i_late_date\r
+       l_width ||= 0\r
+\r
+       pdf.SetY(top+1.5)\r
+       pdf.SetX(subject_width + i_left)\r
+       pdf.SetFillColor(200,200,200)\r
+       pdf.Cell(i_width, 2, "", 0, 0, "", 1)\r
+\r
+       if l_width > 0\r
+               pdf.SetY(top+1.5)\r
+               pdf.SetX(subject_width + i_left)\r
+               pdf.SetFillColor(255,100,100)\r
+               pdf.Cell(l_width, 2, "", 0, 0, "", 1)\r
+       end \r
+       if d_width > 0\r
+               pdf.SetY(top+1.5)\r
+               pdf.SetX(subject_width + i_left)\r
+               pdf.SetFillColor(100,100,255)\r
+               pdf.Cell(d_width, 2, "", 0, 0, "", 1)\r
+       end\r
+       \r
+       pdf.SetY(top+1.5)\r
+       pdf.SetX(subject_width + i_left + i_width)\r
+       pdf.Cell(30, 2, "#{i.status.name} #{i.done_ratio}%")\r
+       \r
+       top = top + 5\r
+       pdf.SetDrawColor(200, 200, 200)\r
+       pdf.Line(15, top, subject_width+g_width, top)\r
+       if pdf.GetY() > 180\r
+               pdf.AddPage("L")\r
+               top = 20\r
+               pdf.Line(15, top, subject_width+g_width, top)\r
+       end\r
+       pdf.SetDrawColor(0, 0, 0)\r
+end\r
+\r
+pdf.Line(15, top, subject_width+g_width, top)\r
+\r
+%>\r
+<%= pdf.Output %>
\ No newline at end of file
diff --git a/redmine/app/views/projects/gantt.rhtml b/redmine/app/views/projects/gantt.rhtml
new file mode 100644 (file)
index 0000000..5133466
--- /dev/null
@@ -0,0 +1,241 @@
+<h2><%= l(:label_gantt_chart) %></h2>\r
+<div class="topright">\r
+<small>\r
+<%= link_to 'PDF ', :zoom => @zoom, :year => @year_from, :month => @month_from, :months => @months, :output => 'pdf' %>\r
+</small>\r
+</div>\r
+\r
+<table width="100%">\r
+<tr>\r
+<td align="left">\r
+<%= start_form_tag %>\r
+<input type="text" name="months" size="2" value="<%= @months %>">\r
+<%= l(:label_months_from) %>\r
+<%= select_month(@month_from, :prefix => "month", :discard_type => true) %>\r
+<%= select_year(@year_from, :prefix => "year", :discard_type => true) %>\r
+<%= hidden_field_tag 'zoom', @zoom %>\r
+<%= submit_tag l(:button_submit), :class => "button-small" %>\r
+<%= end_form_tag %>\r
+</td>\r
+<td align="right">\r
+<%= if @zoom < 4\r
+    link_to image_tag('zoom_in'), {:zoom => (@zoom+1), :year => @year_from, :month => @month_from, :months => @months}\r
+  else\r
+    image_tag 'zoom_in_g'\r
+  end %>\r
+<%= if @zoom > 1\r
+    link_to image_tag('zoom_out'), :zoom => (@zoom-1), :year => @year_from, :month => @month_from, :months => @months\r
+  else\r
+    image_tag 'zoom_out_g'\r
+  end %>\r
+</td>\r
+</tr>\r
+</table>\r
+<br />\r
+\r
+<style>\r
+.m_bg {\r
+  position:absolute;\r
+  top:0;\r
+  height:16px;\r
+  border-top: 1px solid #c0c0c0;\r
+  border-bottom: 1px solid #c0c0c0;\r
+  border-right: 1px solid #c0c0c0;\r
+  text-align: center;\r
+}\r
+\r
+.task {\r
+  position: absolute;\r
+  height:8px;\r
+  font-size:0.8em;\r
+  color:#888;\r
+  background:#aaa;\r
+  padding:0;\r
+  margin:0;\r
+  line-height:0.8em;\r
+}\r
+\r
+.task_late {\r
+  background:#f66;\r
+}\r
+\r
+.task_done {\r
+  background:#66f;\r
+}  \r
+</style>\r
+\r
+<% zoom = 1\r
+@zoom.times { zoom = zoom * 2 }\r
+\r
+subject_width = 260\r
+header_heigth = 18\r
+\r
+headers_heigth = header_heigth\r
+show_weeks = false\r
+show_days = false\r
+\r
+if @zoom >1\r
+    show_weeks = true\r
+    headers_heigth = 2*header_heigth\r
+    if @zoom > 2\r
+        show_days = true\r
+        headers_heigth = 3*header_heigth\r
+    end\r
+end\r
+\r
+g_width = (@date_to - @date_from + 1)*zoom\r
+g_height = [(20 * @issues.length + 6), 206].max\r
+t_height = g_height + headers_heigth\r
+%>\r
+\r
+<table width="100%" border=0 cellspacing=0 cellpading=0>\r
+<tr>\r
+<td width=260>\r
+\r
+<div style="position:relative;height:<%= t_height + 24 %>px;width:<%= subject_width + 1 %>px;">\r
+<div style="right:-2px;width:<%= subject_width %>px;height:<%= headers_heigth %>px;" class="m_bg"></div>\r
+<div style="right:-2px;width:<%= subject_width %>px;height:<%= t_height %>px;border-left: 1px solid #c0c0c0;" class="m_bg"></div>\r
+<%\r
+#\r
+# Tasks subjects\r
+#\r
+top = headers_heigth + 8\r
+@issues.each do |i| %>\r
+       <div style="position: absolute;line-height:1em;height:16px;top:<%= top %>px;left:4px;width:<%= subject_width - 5 %>px;overflow:hidden;">\r
+       <small><%= link_to i.id, :controller => 'issues', :action => 'show', :id => i %>\r
+       <%= i.subject.sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)') %></small>\r
+       </div>\r
+<% top = top + 20\r
+end %>\r
+</div>\r
+</td>\r
+<td>\r
+\r
+<div style="position:relative;height:<%= t_height + 24 %>px;width:<%= subject_width %>;overflow:auto;">\r
+<div style="width:<%= g_width-1 %>px;height:<%= headers_heigth %>px;" class="m_bg">&nbsp;</div>\r
+<% \r
+#\r
+# Months headers\r
+#\r
+month_f = @date_from\r
+left = 0\r
+height = (show_weeks ? header_heigth : header_heigth + g_height)\r
+@months.times do \r
+       width = ((month_f >> 1) - month_f) * zoom - 1\r
+       %>\r
+       <div style="left:<%= left %>px;width:<%= width %>px;height:<%= height %>px;" class="m_bg">\r
+       <%= link_to "#{month_f.year}-#{month_f.month}", :year => month_f.year, :month => month_f.month, :zoom => @zoom, :months => @months %>\r
+       </div>\r
+       <% \r
+       left = left + width + 1\r
+       month_f = month_f >> 1\r
+end %>\r
+\r
+<% \r
+#\r
+# Weeks headers\r
+#\r
+if show_weeks\r
+       left = 0\r
+       height = (show_days ? header_heigth-1 : header_heigth-1 + g_height)\r
+       if @date_from.cwday == 1\r
+           # @date_from is monday\r
+        week_f = @date_from\r
+       else\r
+           # find next monday after @date_from\r
+               week_f = @date_from + (7 - @date_from.cwday + 1)\r
+               width = (7 - @date_from.cwday + 1) * zoom-1\r
+               %>\r
+               <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="m_bg">&nbsp;</div>\r
+               <% \r
+               left = left + width+1\r
+       end %>\r
+       <%\r
+       while week_f < @date_to\r
+               width = (week_f + 6 <= @date_to) ? 7 * zoom -1 : (@date_to - week_f + 1) * zoom-1\r
+               %>\r
+               <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="m_bg">\r
+               <small><%= week_f.cweek %></small>\r
+               </div>\r
+               <% \r
+               left = left + width+1\r
+               week_f = week_f+7\r
+       end\r
+end %>\r
+\r
+<% \r
+#\r
+# Days headers\r
+#\r
+if show_days\r
+       left = 0\r
+       height = g_height + header_heigth - 1\r
+       wday = @date_from.cwday\r
+       (@date_to - @date_from + 1).to_i.times do \r
+       width =  zoom - 1\r
+       %>\r
+       <div style="left:<%= left %>px;top:37px;width:<%= width %>px;height:<%= height %>px;font-size:0.7em;<%= "background:#f1f1f1;" if wday > 5 %>" class="m_bg">\r
+       <%= day_name(wday)[0,1] %>\r
+       </div>\r
+       <% \r
+       left = left + width+1\r
+       wday = wday + 1\r
+       wday = 1 if wday > 7\r
+       end\r
+end %>\r
+\r
+<%\r
+#\r
+# Today red line\r
+#\r
+if Date.today >= @date_from and Date.today <= @date_to %>\r
+    <div style="position: absolute;height:<%= g_height %>px;top:<%= headers_heigth + 1 %>px;left:<%= ((Date.today-@date_from+1)*zoom).floor()-1 %>px;width:10px;border-left: 1px dashed red;">&nbsp;</div>\r
+<% end %>\r
+\r
+<%\r
+#\r
+# Tasks\r
+#\r
+top = headers_heigth + 12\r
+@issues.each do |i| %>\r
+       <%\r
+       i_start_date = (i.start_date >= @date_from ? i.start_date : @date_from )\r
+       i_end_date = (i.due_date <= @date_to ? i.due_date : @date_to )\r
+       \r
+       i_done_date = i.start_date + ((i.due_date - i.start_date)*i.done_ratio/100).floor\r
+       i_done_date = (i_done_date <= @date_from ? @date_from : i_done_date )\r
+       i_done_date = (i_done_date >= @date_to ? @date_to : i_done_date )\r
+       \r
+       i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today\r
+       \r
+       i_left = ((i_start_date - @date_from)*zoom).floor \r
+       i_width = ((i_end_date - i_start_date + 1)*zoom).floor\r
+       d_width = ((i_done_date - i_start_date)*zoom).floor\r
+       l_width = ((i_late_date - i_start_date+1)*zoom).floor if i_late_date\r
+       l_width ||= 0\r
+       %>      \r
+       <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= i_width %>px;" class="task">&nbsp;</div>\r
+       <% if l_width > 0 %>\r
+           <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= l_width %>px;" class="task task_late">&nbsp;</div>\r
+       <% end %>\r
+       <% if d_width > 0 %>\r
+           <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= d_width %>px;" class="task task_done">&nbsp;</div>\r
+       <% end %>\r
+       <div style="top:<%= top %>px;left:<%= i_left + i_width + 5 %>px;background:#fff;" class="task">\r
+       <%= i.status.name %>\r
+       <%= (i.done_ratio).to_i %>%\r
+       </div>  \r
+       <% top = top + 20\r
+end %>\r
+</div>\r
+</td>\r
+</tr>\r
+</table>\r
+\r
+<table width="100%">\r
+<tr>\r
+<td align="left"><%= link_to ('&#171; ' + l(:label_previous)), :year => (@date_from << @months).year, :month => (@date_from << @months).month, :zoom => @zoom, :months => @months %></td>\r
+<td>\r
+<td align="right"><%= link_to (l(:label_next) + ' &#187;'), :year => (@date_from >> @months).year, :month => (@date_from >> @months).month, :zoom => @zoom, :months => @months %></td>\r
+</tr>\r
+</table>
\ No newline at end of file
index 3075d077a9b325253e6ad34e547c22ada6afbde3..ba6f40f860e7c1d8e9bea0783fbd58aff38d658a 100644 (file)
@@ -41,7 +41,7 @@
     </td>\r
     </tr>\r
 </table>\r
-<%= start_form_tag ({:controller => 'projects', :action => 'move_issues', :id => @project}, :id => 'issues_form' ) %>  \r
+<%= start_form_tag({:controller => 'projects', :action => 'move_issues', :id => @project}, :id => 'issues_form' ) %>   \r
 <table class="listTableContent">\r
 \r
     <tr class="ListHead">\r
index 31a5f86a42eae52b23c325404344679f1f2cae05..ae7ae0f8630fb22fa32f19d8f3b9c2bb0232038f 100644 (file)
@@ -5,7 +5,7 @@
 <% for news in @news %>\r
        <p>\r
        <b><%= news.title %></b> <small>(<%= link_to_user news.author %> <%= format_time(news.created_on) %>)</small><br />\r
-       <%= news.summary %><br />\r
+       <% unless news.summary.empty? %><%= news.summary %><br /><% end %>\r
        <small>[<%= link_to l(:label_read), :controller => 'news', :action => 'show', :id => news %>]</small>\r
        </p>\r
 <% end %>
index cb6864a23cbe98d0a5b4f82ac13768d8c34414fa..3f9cba0a06791261cf72bea482b2fac0b143b691 100644 (file)
@@ -1,11 +1,12 @@
 <h2><%=l(:label_settings)%></h2>
-\r
-<% labelled_tabular_form_for :project, @project, :url => { :action => "edit", :id => @project } do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<% end %>
 
-&nbsp;
+<% if authorize_for('projects', 'edit') %>\r
+       <% labelled_tabular_form_for :project, @project, :url => { :action => "edit", :id => @project } do |f| %>
+       <%= render :partial => 'form', :locals => { :f => f } %>
+       <%= submit_tag l(:button_save) %>
+       <% end %>
+       <br />&nbsp;
+<% end %>
 \r
 <div class="box">
 <h3><%=l(:label_member_plural)%></h3>\r
 <% for member in @project.members.find(:all, :include => :user) %>\r
        <% unless member.new_record? %>\r
        <tr>\r
-               <td><%= member.user.display_name %></td>\r
+       <td><%= member.user.display_name %></td>\r
     <td>\r
-      <%= start_form_tag :controller => 'members', :action => 'edit', :id => member %>\r
-      <select name="member[role_id]">\r
+        <% if authorize_for('members', 'edit') %>
+        <%= start_form_tag :controller => 'members', :action => 'edit', :id => member %>\r
+        <select name="member[role_id]">\r
         <%= options_from_collection_for_select @roles, "id", "name", member.role_id %>
-      </select>\r
+        </select>\r
+        <%= submit_tag l(:button_change), :class => "button-small" %>
+        <%= end_form_tag %>
+        <% end %>
     </td>\r
-    <td>\r
-      <%= submit_tag l(:button_change), :class => "button-small" %>\r
-      <%= end_form_tag %>\r
+    <td>
+               <% if authorize_for('members', 'destroy') %>\r
+               <%= start_form_tag :controller => 'members', :action => 'destroy', :id => member %>\r
+               <%= submit_tag l(:button_delete), :class => "button-small" %>\r
+               <%= end_form_tag %>
+        <% end %>\r
     </td>\r
-               <td>\r
-      <%= start_form_tag :controller => 'members', :action => 'destroy', :id => member %>\r
-      <%= submit_tag l(:button_delete), :class => "button-small" %>\r
-      <%= end_form_tag %>\r
-               </td>\r
        </tr>\r
        <% end %>\r
 <% end %>\r
-</table>\r
-<hr />\r
+</table>
+<% if authorize_for('projects', 'add_member') %>\r
+    <hr />\r
     <label><%=l(:label_member_new)%></label><br/>\r
-      <%= start_form_tag :controller => 'projects', :action => 'add_member', :id => @project %>\r
-      <select name="member[user_id]">\r
-        <%= options_from_collection_for_select @users, "id", "display_name", @member.user_id %>
-      </select>\r
-      <select name="member[role_id]">\r
-        <%= options_from_collection_for_select @roles, "id", "name", @member.role_id %>
-      </select>\r
-      <%= submit_tag l(:button_add) %>\r
-      <%= end_form_tag %>\r
+    <%= start_form_tag :controller => 'projects', :action => 'add_member', :id => @project %>\r
+    <select name="member[user_id]">\r
+    <%= options_from_collection_for_select @users, "id", "display_name", @member.user_id %>
+    </select>\r
+    <select name="member[role_id]">\r
+    <%= options_from_collection_for_select @roles, "id", "name", @member.role_id %>
+    </select>\r
+    <%= submit_tag l(:button_add) %>\r
+    <%= end_form_tag %>
+<% end %>\r
 </div>\r
 \r
 <div class="box">\r
 <h3><%=l(:label_version_plural)%></h3>\r
-\r
 <table>\r
 <% for version in @project.versions %>\r
   <tr>\r
-  <td><%= link_to version.name, :controller => 'versions', :action => 'edit', :id => version %></td>\r
-  <td><%=h version.description %></td>\r
-  <td>\r
+  <td width="100"><strong><%=h version.name %></strong></td>\r
+  <td width="100"><%= format_date(version.effective_date) %></td>\r
+  <td><%=h version.description %></td>
+  <td>&nbsp;&nbsp;&nbsp;
+      <%= link_to_if_authorized l(:button_edit), :controller => 'versions', :action => 'edit', :id => version %>
+      <% if authorize_for('versions', 'destroy') %>
+      &nbsp;\r
       <%= start_form_tag :controller => 'versions', :action => 'destroy', :id => version %>\r
       <%= submit_tag l(:button_delete), :class => "button-small" %>\r
-      <%= end_form_tag %>  \r
+      <%= end_form_tag %>  
+      <% end %>\r
   </td>\r
   </tr>\r
 <% end %>\r
-</table>\r
-<hr />\r
-      <%= start_form_tag ({ :controller => 'projects', :action => 'add_version', :id => @project }, :method => 'get' ) %>\r
-      <%= submit_tag l(:label_version_new) %>\r
-      <%= end_form_tag %>  \r
+</table>
+<% if authorize_for('projects', 'add_version') %>\r
+    <hr />
+    <%= link_to l(:label_version_new), :controller => 'projects', :action => 'add_version', :id => @project %>\r
+<% end %>\r
 </div>\r
 \r
 \r
 <% for @category in @project.issue_categories %>\r
        <% unless @category.new_record? %>\r
        <tr>\r
-               <td>\r
-      <%= start_form_tag :controller => 'issue_categories', :action => 'edit', :id => @category %>\r
-      <%= text_field 'category', 'name', :size => 25  %>\r
+    <td>\r
+        <%= start_form_tag :controller => 'issue_categories', :action => 'edit', :id => @category %>\r
+        <%= text_field 'category', 'name', :size => 25  %>\r
     </td>\r
-               <td>\r
-      <%= submit_tag l(:button_save), :class => "button-small" %>\r
-      <%= end_form_tag %>\r
+    <td>
+        <% if authorize_for('issue_categories', 'edit') %>\r
+        <%= submit_tag l(:button_save), :class => "button-small" %>\r
+        <%= end_form_tag %>
+        <% end %>\r
+    </td>\r
+    <td>
+        <% if authorize_for('issue_categories', 'destroy') %>\r
+        <%= start_form_tag :controller => 'issue_categories', :action => 'destroy', :id => @category %>\r
+        <%= submit_tag l(:button_delete), :class => "button-small" %>\r
+        <%= end_form_tag %>
+        <% end %>\r
     </td>\r
-    <td>\r
-      <%= start_form_tag :controller => 'issue_categories', :action => 'destroy', :id => @category %>\r
-      <%= submit_tag l(:button_delete), :class => "button-small" %>\r
-      <%= end_form_tag %>\r
-               </td>\r
        </tr>\r
        <% end %>\r
 <% end %>\r
-</table>\r
-<hr />\r
-\r
-<%= start_form_tag :action => 'add_issue_category', :id => @project %>
-<label for="issue_category_name"><%=l(:label_issue_category_new)%></label><br/>
-<%= error_messages_for 'issue_category' %>\r
-<%= text_field 'issue_category', 'name', :size => 25 %>
-<%= submit_tag l(:button_create) %>\r
-<%= end_form_tag %>\r
-\r
+</table>
+<% if authorize_for('projects', 'add_issue_category') %>\r
+    <hr />\r
+    <%= start_form_tag :action => 'add_issue_category', :id => @project %>
+    <label for="issue_category_name"><%=l(:label_issue_category_new)%></label><br/>
+    <%= error_messages_for 'issue_category' %>\r
+    <%= text_field 'issue_category', 'name', :size => 25 %>
+    <%= submit_tag l(:button_create) %>\r
+    <%= end_form_tag %>\r
+<% end %>\r
 </div>\r
index 2cf01239048185f19aa9a63a972e8704655acf2e..79e36a5862b9d63e108f37456ddf01f28318de09 100644 (file)
@@ -3,7 +3,7 @@
 <div class="splitcontentleft">\r
        <%= simple_format(auto_link(@project.description)) %>   \r
        <ul>\r
-       <% unless @project.homepage.empty? %><li><%=l(:field_homepage)%>: <%= link_to @project.homepage, @project.homepage %></li><% end %>\r
+       <% unless @project.homepage.empty? %><li><%=l(:field_homepage)%>: <%= auto_link @project.homepage %></li><% end %>\r
        <li><%=l(:field_created_on)%>: <%= format_date(@project.created_on) %></li>\r
        <% for custom_value in @custom_values %>\r
        <% if !custom_value.value.empty? %>\r
index c13ea8c1b3a397d59cba7babcdf6706deefbfcec..9cde01c0c71ca9da6b57e868b3f4284d2ef7ba02 100644 (file)
@@ -1,19 +1,19 @@
 <h2><%=l(:label_report_plural)%></h2>\r
 \r
 <div class="splitcontentleft">\r
-<strong><%=l(:field_tracker)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'author' %> ]</small>\r
+<strong><%=l(:field_tracker)%></strong> <%= link_to image_tag('details'), :detail => 'author' %>\r
 <%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %>\r
 <br />\r
-<strong><%=l(:field_priority)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'priority' %> ]</small>\r
+<strong><%=l(:field_priority)%></strong> <%= link_to image_tag('details'), :detail => 'priority' %>\r
 <%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %>\r
 <br />\r
-<strong><%=l(:field_author)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'author' %> ]</small>\r
+<strong><%=l(:field_author)%></strong> <%= link_to image_tag('details'), :detail => 'author' %>\r
 <%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %>\r
 <br />\r
 </div>\r
 \r
 <div class="splitcontentright">\r
-<strong><%=l(:field_category)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'category' %> ]</small>\r
+<strong><%=l(:field_category)%></strong> <%= link_to image_tag('details'), :detail => 'category' %>\r
 <%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %>\r
 <br />\r
 </div>\r
index 6a714a7b02e36701c8bc644421d8ce5cc8ada9f0..089d4d23c9ddb1e6a2f615fa1abce4d34b3488ff 100644 (file)
@@ -1,15 +1,9 @@
 <%= error_messages_for 'user' %>
 
-<div class="box">
 <!--[form:user]-->
+<div class="box">
+<h3><%=l(:label_information_plural)%></h3>
 <p><%= f.text_field :login, :required => true, :size => 25  %></p>
-\r
-<p><label for="password"><%=l(:field_password)%><span class="required"> *</span></label>
-<%= password_field_tag 'password', nil, :size => 25  %></p>
-
-<p><label for="password_confirmation"><%=l(:field_password_confirmation)%><span class="required"> *</span></label>
-<%= password_field_tag 'password_confirmation', nil, :size => 25  %></p>
-
 <p><%= f.text_field :firstname, :required => true %></p>\r
 <p><%= f.text_field :lastname, :required => true %></p>
 <p><%= f.text_field :mail, :required => true %></p>\r
 \r
 <p><%= f.check_box :admin %></p>\r
 <p><%= f.check_box :mail_notification %></p>\r
-\r
-<!--[eoform:user]-->
 </div>
+
+<div class="box">
+<h3><%=l(:label_authentication)%></h3>
+<% unless @auth_sources.empty? %>
+<p><%= f.select :auth_source_id, [[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] } %></p>
+<% end %>
+<p><label for="password"><%=l(:field_password)%><span class="required"> *</span></label>
+<%= password_field_tag 'password', nil, :size => 25  %></p>
+<p><label for="password_confirmation"><%=l(:field_password_confirmation)%><span class="required"> *</span></label>
+<%= password_field_tag 'password_confirmation', nil, :size => 25  %></p>
+</div>
+<!--[eoform:user]-->
diff --git a/redmine/config/config_custom.example.rb b/redmine/config/config_custom.example.rb
new file mode 100644 (file)
index 0000000..689d9da
--- /dev/null
@@ -0,0 +1,65 @@
+# redMine - project management software\r
+# Copyright (C) 2006  Jean-Philippe Lang\r
+#\r
+# This program is free software; you can redistribute it and/or\r
+# modify it under the terms of the GNU General Public License\r
+# as published by the Free Software Foundation; either version 2\r
+# of the License, or (at your option) any later version.\r
+# \r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+# GNU General Public License for more details.\r
+# \r
+# You should have received a copy of the GNU General Public License\r
+# along with this program; if not, write to the Free Software\r
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+\r
+\r
+# To set your own configuration, rename this file to config_custom.rb\r
+# and edit parameters below\r
+# Don't forget to restart the application after any change.\r
+\r
+\r
+# Application host name\r
+# Used to provide absolute links in mail notifications\r
+# $RDM_HOST_NAME = "somenet.foo"\r
+\r
+# File storage path\r
+# Directory used to store uploaded files\r
+# #{RAILS_ROOT} represents application's home directory\r
+# $RDM_STORAGE_PATH = "#{RAILS_ROOT}/files"\r
+\r
+# Set $RDM_LOGIN_REQUIRED to true if you want to force users to login\r
+# to access any page of the application\r
+# $RDM_LOGIN_REQUIRED = false\r
+\r
+# Uncomment to disable user self-registration\r
+# $RDM_SELF_REGISTRATION = false\r
+\r
+# Default langage ('en', 'es', 'de', 'fr' are available)\r
+# $RDM_DEFAULT_LANG = 'en'\r
+\r
+# Email adress used to send mail notifications\r
+# $RDM_MAIL_FROM = "redmine@somenet.foo"\r
+\r
+# Page title\r
+# $RDM_HEADER_TITLE = "Title"\r
+\r
+# Page sub-title\r
+# $RDM_HEADER_SUBTITLE = "Sub title"\r
+\r
+# Welcome page title\r
+# $RDM_WELCOME_TITLE = "Welcome"\r
+\r
+# Welcome page text\r
+# $RDM_WELCOME_TEXT = ""\r
+\r
+# Signature displayed in footer\r
+# Email adresses will be automatically displayed as a mailto link\r
+# $RDM_FOOTER_SIG = "admin@somenet.foo"\r
+\r
+# Textile formatting (only available if RedCloth is installed)\r
+# Textile formatting is automativaly disabled if RedCloth is not available\r
+# Set to true to manually disable.\r
+# $RDM_TEXTILE_DISABLED = true\r
diff --git a/redmine/config/config_custom.rb b/redmine/config/config_custom.rb
deleted file mode 100644 (file)
index 1af1faf..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# redMine - project management software\r
-# Copyright (C) 2006  Jean-Philippe Lang\r
-#\r
-# This program is free software; you can redistribute it and/or\r
-# modify it under the terms of the GNU General Public License\r
-# as published by the Free Software Foundation; either version 2\r
-# of the License, or (at your option) any later version.\r
-# \r
-# This program is distributed in the hope that it will be useful,\r
-# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-# GNU General Public License for more details.\r
-# \r
-# You should have received a copy of the GNU General Public License\r
-# along with this program; if not, write to the Free Software\r
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
-\r
-\r
-# To set your own configuration, rename this file to config_custom.rb\r
-# and edit parameters below\r
-# Don't forget to restart the application after any change.\r
-\r
-\r
-# Application host name\r
-# Used to provide absolute links in mail notifications\r
-# $RDM_HOST_NAME = "somenet.foo"\r
-\r
-# File storage path\r
-# Directory used to store uploaded files\r
-# #{RAILS_ROOT} represents application's home directory\r
-# $RDM_STORAGE_PATH = "#{RAILS_ROOT}/files"\r
-\r
-# Set $RDM_LOGIN_REQUIRED to true if you want to force users to login\r
-# to access any page of the application\r
-# $RDM_LOGIN_REQUIRED = false\r
-\r
-# Uncomment to disable user self-registration\r
-# $RDM_SELF_REGISTRATION = false\r
-\r
-# Default langage ('en', 'es', 'fr' are available)\r
-# $RDM_DEFAULT_LANG = 'en'\r
-\r
-# Email adress used to send mail notifications\r
-# $RDM_MAIL_FROM = "redmine@somenet.foo"\r
-\r
-# Page title\r
-# $RDM_HEADER_TITLE = "Title"\r
-\r
-# Page sub-title\r
-# $RDM_HEADER_SUBTITLE = "Sub title"\r
-\r
-# Welcome page title\r
-# $RDM_WELCOME_TITLE = "Welcome"\r
-\r
-# Welcome page text\r
-# $RDM_WELCOME_TEXT = ""\r
-\r
-# Signature displayed in footer\r
-# Email adresses will be automatically displayed as a mailto link\r
-# $RDM_FOOTER_SIG = "admin@somenet.foo"\r
index f13942ffa62c74e39ea0b0aba62b8340e3fabc6c..359293b6eac51d51e3a10f47962e79bc9baa59d7 100644 (file)
@@ -105,6 +105,10 @@ $RDM_HEADER_SUBTITLE ||= "Project management"
 # footer signature
 $RDM_FOOTER_SIG = "admin@somenet.foo"
 
+# textile formatting
+# automaticaly disabled if 'textile' method is not defined (RedCloth unavailable)
+$RDM_TEXTILE_DISABLED = true unless ActionView::Helpers::TextHelper.method_defined? "textilize"
+
 # application name
 RDM_APP_NAME = "redMine" 
 # application version
diff --git a/redmine/db/migrate/005_issue_start_date.rb b/redmine/db/migrate/005_issue_start_date.rb
new file mode 100644 (file)
index 0000000..3d1693f
--- /dev/null
@@ -0,0 +1,11 @@
+class IssueStartDate < ActiveRecord::Migration
+  def self.up
+    add_column :issues, :start_date, :date
+    add_column :issues, :done_ratio, :integer, :default => 0, :null => false
+  end
+
+  def self.down
+    remove_column :issues, :start_date
+    remove_column :issues, :done_ratio
+  end
+end
diff --git a/redmine/db/migrate/006_calendar_and_activity.rb b/redmine/db/migrate/006_calendar_and_activity.rb
new file mode 100644 (file)
index 0000000..5d8474f
--- /dev/null
@@ -0,0 +1,13 @@
+class CalendarAndActivity < ActiveRecord::Migration
+  def self.up
+    Permission.create :controller => "projects", :action => "activity", :description => "label_activity", :sort => 160, :is_public => true, :mail_option => 0, :mail_enabled => 0
+    Permission.create :controller => "projects", :action => "calendar", :description => "label_calendar", :sort => 165, :is_public => true, :mail_option => 0, :mail_enabled => 0
+    Permission.create :controller => "projects", :action => "gantt", :description => "label_gantt", :sort => 166, :is_public => true, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'activity']).destroy
+    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'calendar']).destroy
+    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'gantt']).destroy
+  end
+end
index ea0048c5d561b39bd73f1ebe472ac6e99a9a629b..f310f63c38c783da04517c6c66a8e6bf4ecb7042 100644 (file)
@@ -5,7 +5,31 @@ Copyright (C) 2006  Jean-Philippe Lang
 http://redmine.org/\r
 \r
 \r
-== xx/xx/2006 v0.3.0\r
+== xx/xx/2006 v0.x.x\r
+\r
+* new functionality: move an issue to another project or tracker\r
+* new functionality: add a note to an issue\r
+* new report: project activity\r
+* "start date" and "% done" fields added on issues\r
+* project calendar added\r
+* gantt chart added (exportable to pdf)\r
+* single/multiple issues pdf export added\r
+* issues reports improvements\r
+* multiple file upload for issues attachments\r
+* textile formating of issue and news descritions (RedCloth required)\r
+* integration of DotClear jstoolbar for textile formatting\r
+* calendar date picker for date fields (LGPL DHTML Calendar http://sourceforge.net/projects/jscalendar)\r
+* new filter in issues list: Author\r
+* ajaxified paginators\r
+* option to set number of results per page on issues list\r
+* localized csv separator (comma/semicolon)\r
+* csv output encoded to ISO-8859-1\r
+* user custom field displayed on account/show\r
+* default configuration improved (default roles, trackers, status, permissions and workflows)\r
+* fixed: custom fields not in csv exports\r
+* fixed: project settings now displayed according to user's permissions\r
+\r
+== 10/08/2006 v0.3.0\r
 \r
 * user authentication against multiple LDAP (optional)\r
 * token based "lost password" functionality\r
index e75d4e52508a21e780fbe8bdd3dd6f6fd57bd336..9e29b6ddca08352f09b5974cc161e6119a83ed7a 100644 (file)
@@ -9,18 +9,21 @@ http://redmine.org/
 \r
 * Ruby on Rails 1.1\r
 * Iconv\r
-* Net::LDAP for Ruby (for LDAP authentication)\r
 * a database (see compatibility below)\r
 * (recommended) Apache/Lighttpd with FCGI support \r
 \r
-Supported databases:\r
+Optional:\r
+* RedCloth (for textile formatting)\r
+* Net::LDAP for Ruby (for LDAP authentication)\r
 \r
+Supported databases:\r
 * MySQL (tested with MySQL 5)\r
 * PostgreSQL (tested with PostgreSQL 8.1)\r
 * Oracle (tested with Oracle 10g)\r
 * SQL Server (tested with SQL Server 2005)\r
 * SQLite (tested with SQLite 3)\r
 \r
+\r
 == Upgrade\r
 \r
 Due to major database changes, there is no migration support from beta 0.2.0.\r
index 8d0044e2c252b501fdf5863aaf4793eba66f1e3e..bc10248d8c14fe5e4017bad51f15b1dcc1861863 100644 (file)
@@ -31,7 +31,8 @@ activerecord_error_too_short: ist zu kurz
 activerecord_error_wrong_length: ist die falsche Länge\r
 activerecord_error_taken: ist bereits genommen worden\r
 activerecord_error_not_a_number: ist nicht eine Zahl\r
-#activerecord_error_not_a_date: is not a valid date\r
+activerecord_error_not_a_date: ist nicht ein gültiges Datum\r
+activerecord_error_greater_than_start_date: muß als grösser sein beginnen Datum\r
 \r
 general_fmt_age: %d yr\r
 general_fmt_age_plural: %d yrs\r
@@ -45,6 +46,7 @@ general_text_no: 'nein'
 general_text_yes: 'ja'\r
 general_lang_de: 'Deutsch'\r
 general_csv_separator: ';'\r
+general_day_names: Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag\r
 \r
 notice_account_updated: Konto wurde erfolgreich aktualisiert.\r
 notice_account_invalid_creditentials: Unzulässiger Benutzer oder Passwort\r
@@ -62,8 +64,8 @@ notice_successful_connection: Erfolgreicher Anschluß.
 notice_file_not_found: Erbetene Akte besteht nicht oder ist gelöscht worden.\r
 notice_locking_conflict: Data have been updated by another user.\r
 \r
-#mail_subject_lost_password: Your redMine password\r
-#mail_subject_register: redMine account activation\r
+mail_subject_lost_password: Dein redMine Kennwort\r
+mail_subject_register: redMine Kontoaktivierung\r
 \r
 gui_validation_error: 1 Störung\r
 gui_validation_error_plural: %d Störungen\r
@@ -91,15 +93,15 @@ field_value: Wert
 field_category: Kategorie\r
 field_title: Títel\r
 field_project: Projekt\r
-#field_issue: Issue\r
+field_issue: Antrag\r
 field_status: Status\r
 field_notes: Anmerkungen\r
 field_is_closed: Problem erledigt\r
-#field_is_default: Default status\r
+field_is_default: Rückstellung status\r
 field_html_color: Farbe\r
 field_tracker: Tracker\r
 field_subject: Thema\r
-#field_due_date: Due date\r
+field_due_date: Abgabedatum\r
 field_assigned_to: Zugewiesen an\r
 field_priority: Priorität\r
 field_fixed_version: Erledigt in Version\r
@@ -107,11 +109,11 @@ field_user: Benutzer
 field_role: Rolle\r
 field_homepage: Startseite\r
 field_is_public: Öffentlich\r
-#field_parent: Subprojekt von\r
+field_parent: Subprojekt von\r
 field_is_in_chlog: Ansicht der Issues in der Historie\r
 field_login: Mitgliedsname\r
 field_mail_notification: Mailbenachrichtigung\r
-#field_admin: Administrator\r
+field_admin: Administrator\r
 field_locked: Gesperrt\r
 field_last_login_on: Letzte Anmeldung\r
 field_language: Sprache\r
@@ -122,14 +124,16 @@ field_password_confirmation: Bestätigung
 field_version: Version\r
 field_type: Typ\r
 field_host: Host\r
-#field_port: Port\r
-#field_account: Account\r
-#field_base_dn: Base DN\r
-#field_attr_login: Login attribute\r
-#field_attr_firstname: Firstname attribute\r
-#field_attr_lastname: Lastname attribute\r
-#field_attr_mail: Email attribute\r
-#field_onthefly: On-the-fly user creation\r
+field_port: Port\r
+field_account: Konto\r
+field_base_dn: Base DN\r
+field_attr_login: Mitgliedsnameattribut\r
+field_attr_firstname: Vornamensattribut\r
+field_attr_lastname: Namenattribut\r
+field_attr_mail: Emailattribut\r
+field_onthefly: On-the-fly Benutzerkreation\r
+field_start_date: Beginn\r
+field_done_ratio: %% Getan\r
 \r
 label_user: Benutzer\r
 label_user_plural: Benutzer\r
@@ -137,11 +141,11 @@ label_user_new: Neuer Benutzer
 label_project: Projekt\r
 label_project_new: Neues Projekt\r
 label_project_plural: Projekte\r
-#label_project_latest: Latest projects\r
-#label_issue: Issue\r
-#label_issue_new: New issue\r
-#label_issue_plural: Issues\r
-#label_issue_view_all: View all issues\r
+label_project_latest: Neueste Projekte\r
+label_issue: Antrag\r
+label_issue_new: Neue Antrag\r
+label_issue_plural: Anträge\r
+label_issue_view_all: Alle Anträge ansehen\r
 label_document: Dokument\r
 label_document_new: Neues Dokument\r
 label_document_plural: Dokumente\r
@@ -156,11 +160,11 @@ label_tracker: Tracker
 label_tracker_plural: Tracker\r
 label_tracker_new: Neuer Tracker\r
 label_workflow: Workflow\r
-label_issue_status: Problem Status\r
-label_issue_status_plural: Problem Stati\r
+label_issue_status: Antrag Status\r
+label_issue_status_plural: Antrag Stati\r
 label_issue_status_new: Neuer Status\r
-label_issue_category: Problem Kategorie\r
-label_issue_category_plural: Problem Kategorien\r
+label_issue_category: Antrag Kategorie\r
+label_issue_category_plural: Antrag Kategorien\r
 label_issue_category_new: Neue Kategorie\r
 label_custom_field: Benutzerdefiniertes Feld\r
 label_custom_field_plural: Benutzerdefinierte Felder\r
@@ -169,7 +173,7 @@ label_enumerations: Enumerationen
 label_enumeration_new: Neuer Wert\r
 label_information: Information\r
 label_information_plural: Informationen\r
-#label_please_login: Please login\r
+label_please_login: Anmelden\r
 label_register: Anmelden\r
 label_password_lost: Passwort vergessen\r
 label_home: Hauptseite\r
@@ -183,42 +187,42 @@ label_help: Hilfe
 label_reported_issues: Gemeldete Issues\r
 label_assigned_to_me_issues: Mir zugewiesen\r
 label_last_login: Letzte Anmeldung\r
-#label_last_updates: Last updated\r
-#label_last_updates_plural: %d last updated\r
+label_last_updates: Letztes aktualisiertes\r
+label_last_updates_plural: %d Letztes aktualisiertes\r
 label_registered_on: Angemeldet am\r
 label_activity: Aktivität\r
 label_new: Neue\r
 label_logged_as: Angemeldet als\r
-#label_environment: Environment\r
+label_environment: Environment\r
 label_authentication: Authentisierung\r
-#label_auth_source: Authentification mode\r
-#label_auth_source_new: New authentication mode\r
-#label_auth_source_plural: Authentification modes\r
-#label_subproject: Subproject\r
-#label_subproject_plural: Subprojects\r
+label_auth_source: Authentisierung Modus\r
+label_auth_source_new: Neuer Authentisierung Modus\r
+label_auth_source_plural: Authentisierung Modi\r
+label_subproject: Vorprojekt von\r
+label_subproject_plural: Vorprojekte\r
 label_min_max_length: Min - Max Länge\r
 label_list: Liste\r
 label_date: Date\r
 label_integer: Zahl\r
 label_boolean: Boolesch\r
-#label_string: String\r
-label_text: Text\r
+label_string: Text\r
+label_text: Langer Text\r
 label_attribute: Attribut\r
 label_attribute_plural: Attribute\r
-#label_download: %d Download\r
-#label_download_plural: %d Downloads\r
+label_download: %d Herunterlade\r
+label_download_plural: %d Herunterlade\r
 label_no_data: Nichts anzuzeigen\r
 label_change_status: Statuswechsel\r
 label_history: Historie\r
 label_attachment: Datei\r
 label_attachment_new: Neue Datei\r
-#label_attachment_delete: Delete file\r
+label_attachment_delete: Löschungakten\r
 label_attachment_plural: Dateien\r
 label_report: Bericht\r
 label_report_plural: Berichte\r
-#label_news: Neuigkeiten\r
-#label_news_new: Add news\r
-#label_news_plural: Neuigkeiten\r
+label_news: Neuigkeit\r
+label_news_new: Neuigkeite addieren\r
+label_news_plural: Neuigkeiten\r
 label_news_latest: Letzte Neuigkeiten\r
 label_news_view_all: Alle Neuigkeiten anzeigen\r
 label_change_log: Change log\r
@@ -228,14 +232,14 @@ label_version: Version
 label_version_new: Neue Version\r
 label_version_plural: Versionen\r
 label_confirmation: Bestätigung\r
-#label_export_csv: Export to CSV\r
-#label_export_pdf: Export to PDF\r
+label_export_csv: Export zu CSV\r
+label_export_pdf: Export zu PDF\r
 label_read: Lesen...\r
 label_public_projects: Öffentliche Projekte\r
-#label_open_issues: Open\r
-#label_open_issues_plural: Open\r
-#label_closed_issues: Closed\r
-#label_closed_issues_plural: Closed\r
+label_open_issues: Geöffnet\r
+label_open_issues_plural: Geöffnet\r
+label_closed_issues: Geschlossen\r
+label_closed_issues_plural: Geschlossen\r
 label_total: Gesamtzahl\r
 label_permissions: Berechtigungen\r
 label_current_status: Gegenwärtiger Status\r
@@ -245,9 +249,13 @@ label_none: Kein
 label_next: Weiter\r
 label_previous: Zurück\r
 label_used_by: Benutzt von\r
-#label_details: Details...\r
-#label_add_note: Add a note\r
-#label_per_page: Per page\r
+label_details: Details...\r
+label_add_note: Eine Anmerkung addieren\r
+label_per_page: Pro Seite\r
+label_calendar: Kalender\r
+label_months_from: Monate von\r
+label_gantt_chart: Gantt Diagramm\r
+label_internal: Intern\r
 \r
 button_login: Einloggen\r
 button_submit: Einreichen\r
@@ -268,12 +276,12 @@ button_download: Fernzuladen
 button_list: Aufzulisten\r
 button_view: Siehe\r
 button_move: Bewegen\r
-#button_back: Back\r
+button_back: Rückkehr\r
 \r
 text_select_mail_notifications: Aktionen für die Mailbenachrichtigung aktiviert werden soll.\r
 text_regexp_info: eg. ^[A-Z0-9]+$\r
 text_min_max_length_info: 0 heisst keine Beschränkung\r
-#text_possible_values_info: values separated with |\r
+text_possible_values_info: Werte trennten sich mit |\r
 text_project_destroy_confirmation: Sind sie sicher, daß sie das Projekt löschen wollen ?\r
 text_workflow_edit: Auswahl Workflow zum Bearbeiten\r
 text_are_you_sure: Sind sie sicher ?\r
index 9e20f7f2a92aa2ace96a255d878229588f9cb4da..e30e6c7a071a178b7834a42f99d461b3c3724bcc 100644 (file)
@@ -32,6 +32,7 @@ activerecord_error_wrong_length: is the wrong length
 activerecord_error_taken: has already been taken\r
 activerecord_error_not_a_number: is not a number\r
 activerecord_error_not_a_date: is not a valid date\r
+activerecord_error_greater_than_start_date: must be greater than start date\r
 \r
 general_fmt_age: %d yr\r
 general_fmt_age_plural: %d yrs\r
@@ -45,6 +46,7 @@ general_text_no: 'no'
 general_text_yes: 'yes'\r
 general_lang_en: 'English'\r
 general_csv_separator: ','\r
+general_day_names: Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday\r
 \r
 notice_account_updated: Account was successfully updated.\r
 notice_account_invalid_creditentials: Invalid user or password\r
@@ -130,6 +132,8 @@ field_attr_firstname: Firstname attribute
 field_attr_lastname: Lastname attribute\r
 field_attr_mail: Email attribute\r
 field_onthefly: On-the-fly user creation\r
+field_start_date: Start\r
+field_done_ratio: %% Done\r
 \r
 label_user: User\r
 label_user_plural: Users\r
@@ -191,9 +195,9 @@ label_new: New
 label_logged_as: Logged as\r
 label_environment: Environment\r
 label_authentication: Authentication\r
-label_auth_source: Authentification mode\r
+label_auth_source: Authentication mode\r
 label_auth_source_new: New authentication mode\r
-label_auth_source_plural: Authentification modes\r
+label_auth_source_plural: Authentication modes\r
 label_subproject: Subproject\r
 label_subproject_plural: Subprojects\r
 label_min_max_length: Min - Max length\r
@@ -201,8 +205,8 @@ label_list: List
 label_date: Date\r
 label_integer: Integer\r
 label_boolean: Boolean\r
-label_string: String\r
-label_text: Text\r
+label_string: Text\r
+label_text: Long text\r
 label_attribute: Attribute\r
 label_attribute_plural: Attributes\r
 label_download: %d Download\r
@@ -248,6 +252,10 @@ label_used_by: Used by
 label_details: Details...\r
 label_add_note: Add a note\r
 label_per_page: Per page\r
+label_calendar: Calendar\r
+label_months_from: months from\r
+label_gantt_chart: Gantt chart\r
+label_internal: Internal\r
 \r
 button_login: Login\r
 button_submit: Submit\r
index 92de4dc93139e4d39ade1e7bb7461195437ad296..7c1c6e122b1ecdbae191215bc3691dec201d860f 100644 (file)
@@ -31,7 +31,8 @@ activerecord_error_too_short: is too short
 activerecord_error_wrong_length: is the wrong length\r
 activerecord_error_taken: has already been taken\r
 activerecord_error_not_a_number: is not a number\r
-#activerecord_error_not_a_date: is not a valid date\r
+activerecord_error_not_a_date: no es una fecha válida\r
+activerecord_error_greater_than_start_date: debe ser la fecha mayor que del comienzo\r
 \r
 general_fmt_age: %d año\r
 general_fmt_age_plural: %d años\r
@@ -45,6 +46,7 @@ general_text_no: 'no'
 general_text_yes: 'sí'\r
 general_lang_es: 'Español'\r
 general_csv_separator: ';'\r
+general_day_names: Lunes,Martes,Miércoles,Jueves,Viernes,Sábado,Domingo\r
 \r
 notice_account_updated: Account was successfully updated.\r
 notice_account_invalid_creditentials: Invalid user or password\r
@@ -62,8 +64,8 @@ notice_successful_connection: Successful connection.
 notice_file_not_found: Requested file doesn't exist or has been deleted.\r
 notice_locking_conflict: Data have been updated by another user.\r
 \r
-#mail_subject_lost_password: Your redMine password\r
-#mail_subject_register: redMine account activation\r
+mail_subject_lost_password: Tu contraseña del redMine\r
+mail_subject_register: Activación de la cuenta del redMine\r
 \r
 gui_validation_error: 1 error\r
 gui_validation_error_plural: %d errores\r
@@ -85,8 +87,8 @@ field_field_format: Formato
 field_is_for_all: Para todos los proyectos\r
 field_possible_values: Valores posibles\r
 field_regexp: Expresión regular\r
-#field_min_length: Minimum length\r
-#field_max_length: Maximum length\r
+field_min_length: Longitud mínima\r
+field_max_length: Longitud máxima\r
 field_value: Valor\r
 field_category: Categoría\r
 field_title: Título\r
@@ -99,7 +101,7 @@ field_is_default: Estatuto por defecto
 field_html_color: Color\r
 field_tracker: Tracker\r
 field_subject: Tema\r
-#field_due_date: Due date\r
+field_due_date: Fecha debida\r
 field_assigned_to: Asignado a\r
 field_priority: Prioridad\r
 field_fixed_version: Versión corregida\r
@@ -107,7 +109,7 @@ field_user: Usuario
 field_role: Papel\r
 field_homepage: Sitio web\r
 field_is_public: Público\r
-#field_parent: Subproject de\r
+field_parent: Proyecto secundario de\r
 field_is_in_chlog: Consultar las peticiones en el histórico\r
 field_login: Identificador\r
 field_mail_notification: Notificación por mail\r
@@ -121,15 +123,17 @@ field_new_password: Nueva contraseña
 field_password_confirmation: Confirmación\r
 field_version: Versión\r
 field_type: Tipo\r
-#field_host: Host\r
-#field_port: Port\r
-#field_account: Account\r
-#field_base_dn: Base DN\r
-#field_attr_login: Login attribute\r
-#field_attr_firstname: Firstname attribute\r
-#field_attr_lastname: Lastname attribute\r
-#field_attr_mail: Email attribute\r
-#field_onthefly: On-the-fly user creation\r
+field_host: Anfitrión\r
+field_port: Puerto\r
+field_account: Cuenta\r
+field_base_dn: Base DN\r
+field_attr_login: Cualidad del identificador\r
+field_attr_firstname: Cualidad del nombre\r
+field_attr_lastname: Cualidad del apellido\r
+field_attr_mail: Cualidad del Email\r
+field_onthefly: Creación del usuario On-the-fly\r
+field_start_date: Comienzo\r
+field_done_ratio: %% Realizado\r
 \r
 label_user: Usuario\r
 label_user_plural: Usuarios\r
@@ -137,7 +141,7 @@ label_user_new: Nuevo usuario
 label_project: Proyecto\r
 label_project_new: Nuevo proyecto\r
 label_project_plural: Proyectos\r
-#label_project_latest: Latest projects\r
+label_project_latest: Los proyectos más últimos\r
 label_issue: Petición\r
 label_issue_new: Nueva petición\r
 label_issue_plural: Peticiones\r
@@ -170,7 +174,7 @@ label_enumeration_new: Nuevo valor
 label_information: Informacion\r
 label_information_plural: Informaciones\r
 label_please_login: Conexión\r
-#label_register: Register\r
+label_register: Registrar\r
 label_password_lost: ¿Olvidaste la contraseña?\r
 label_home: Acogida\r
 label_my_page: Mi página\r
@@ -189,33 +193,33 @@ label_registered_on: Inscrito el
 label_activity: Actividad\r
 label_new: Nuevo\r
 label_logged_as: Conectado como\r
-#label_environment: Environment\r
-#label_authentication: Authentication\r
-#label_auth_source: Authentification mode\r
-#label_auth_source_new: New authentication mode\r
-#label_auth_source_plural: Authentification modes\r
-#label_subproject: Subproject\r
-#label_subproject_plural: Subprojects\r
-#label_min_max_length: Min - Max length\r
-#label_list: List\r
+label_environment: Environment\r
+label_authentication: Autentificación\r
+label_auth_source: Modo de la autentificación\r
+label_auth_source_new: Nuevo modo de la autentificación\r
+label_auth_source_plural: Modos de la autentificación\r
+label_subproject: Proyecto secundario\r
+label_subproject_plural: Proyectos secundarios\r
+label_min_max_length: Longitud mín - máx\r
+label_list: Lista\r
 label_date: Fecha\r
-#label_integer: Integer\r
-#label_boolean: Boolean\r
-#label_string: String\r
-#label_text: Text\r
-#label_attribute: Attribute\r
-#label_attribute_plural: Attributes\r
+label_integer: Número\r
+label_boolean: Boleano\r
+label_string: Texto\r
+label_text: Texto largo\r
+label_attribute: Cualidad\r
+label_attribute_plural: Cualidades\r
 label_download: %d Telecarga\r
 label_download_plural: %d Telecargas\r
-#label_no_data: No data to display\r
+label_no_data: Ningunos datos a exhibir\r
 label_change_status: Cambiar el estatuto\r
 label_history: Histórico\r
 label_attachment: Fichero\r
 label_attachment_new: Nuevo fichero\r
-#label_attachment_delete: Delete file\r
+label_attachment_delete: Suprimir el fichero\r
 label_attachment_plural: Ficheros\r
-#label_report: Report\r
-#label_report_plural: Reports\r
+label_report: Informe\r
+label_report_plural: Informes\r
 label_news: Noticia\r
 label_news_new: Nueva noticia\r
 label_news_plural: Noticias\r
@@ -238,16 +242,20 @@ label_closed_issues: Cerrada
 label_closed_issues_plural: Cerradas\r
 label_total: Total\r
 label_permissions: Permisos\r
-#label_current_status: Current status\r
+label_current_status: Estado actual\r
 label_new_statuses_allowed: Nuevos estatutos autorizados\r
 label_all: Todos\r
 label_none: Ninguno\r
 label_next: Próximo\r
 label_previous: Precedente\r
 label_used_by: Utilizado por\r
-#label_details: Details...\r
-#label_add_note: Add a note\r
-#label_per_page: Per page\r
+label_details: Detalles...\r
+label_add_note: Agregar una nota\r
+label_per_page: Por la página\r
+label_calendar: Calendario\r
+label_months_from: meses de\r
+label_gantt_chart: Diagrama de Gantt\r
+label_internal: Interno\r
 \r
 button_login: Conexión\r
 button_submit: Someter\r
@@ -268,12 +276,12 @@ button_download: Telecargar
 button_list: Listar\r
 button_view: Ver\r
 button_move: Mover\r
-#button_back: Back\r
+button_back: Atrás\r
 \r
 text_select_mail_notifications: Seleccionar las actividades que necesitan la activación de la notificación por mail.\r
 text_regexp_info: eg. ^[A-Z0-9]+$\r
 text_min_max_length_info: 0 para ninguna restricción\r
-#text_possible_values_info: values separated with |\r
+text_possible_values_info: Los valores se separaron con |\r
 text_project_destroy_confirmation: ¿ Estás seguro de querer eliminar el proyecto ?\r
 text_workflow_edit: Seleccionar un workflow para actualizar\r
 text_are_you_sure: ¿ Estás seguro ?\r
index 04b246bbcc146bd9d140a48c427a85dc421b7048..5802558ab8d6abb3ef0f378b97d55623197c1501 100644 (file)
@@ -32,6 +32,7 @@ activerecord_error_wrong_length: n'est pas de la bonne longueur
 activerecord_error_taken: est déjà utilisé\r
 activerecord_error_not_a_number: n'est pas un nombre\r
 activerecord_error_not_a_date: n'est pas une date valide\r
+activerecord_error_greater_than_start_date: doit être postérieur à la date de début\r
 \r
 general_fmt_age: %d an\r
 general_fmt_age_plural: %d ans\r
@@ -45,6 +46,7 @@ general_text_no: 'non'
 general_text_yes: 'oui'\r
 general_lang_fr: 'Français'\r
 general_csv_separator: ';'\r
+general_day_names: Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi,Dimanche\r
 \r
 notice_account_updated: Le compte a été mis à jour avec succès.\r
 notice_account_invalid_creditentials: Identifiant ou mot de passe invalide.\r
@@ -130,6 +132,9 @@ field_attr_firstname: Attribut Prénom
 field_attr_lastname: Attribut Nom\r
 field_attr_mail: Attribut Email\r
 field_onthefly: Création des utilisateurs à la volée\r
+field_start_date: Début\r
+field_done_ratio: %% Réalisé\r
+field_auth_source: Mode d'authentification\r
 \r
 label_user: Utilisateur\r
 label_user_plural: Utilisateurs\r
@@ -201,8 +206,8 @@ label_list: Liste
 label_date: Date\r
 label_integer: Entier\r
 label_boolean: Booléen\r
-label_string: Chaîne\r
-label_text: Texte\r
+label_string: Texte\r
+label_text: Texte long\r
 label_attribute: Attribut\r
 label_attribute_plural: Attributs\r
 label_download: %d Téléchargement\r
@@ -248,6 +253,10 @@ label_used_by: Utilisé par
 label_details: Détails...\r
 label_add_note: Ajouter une note\r
 label_per_page: Par page\r
+label_calendar: Calendrier\r
+label_months_from: mois depuis\r
+label_gantt_chart: Diagramme de Gantt\r
+label_internal: Interne\r
 \r
 button_login: Connexion\r
 button_submit: Soumettre\r
index 1cf0f8fe1b1f43b350acae5f1f5053a0e862982a..d672802db4f66eebef72841617fc121f7179405a 100644 (file)
@@ -3,35 +3,75 @@ desc 'Load default configuration data (using default language)'
 task :load_default_data => :environment do\r
   include GLoc\r
   set_language_if_valid($RDM_DEFAULT_LANG)\r
-  \r
+\r
+begin\r
+  # check that no data already exists\r
+  if Role.find(:first)\r
+    raise "Some roles are already defined."\r
+  end\r
+  if Tracker.find(:first)\r
+    raise "Some trackers are already defined."\r
+  end\r
+  if IssueStatus.find(:first)\r
+    raise "Some statuses are already defined."\r
+  end\r
+  if Enumeration.find(:first)\r
+    raise "Some enumerations are already defined."\r
+  end\r
+    \r
+  puts "Loading default configuration for language: #{current_language}"\r
\r
   # roles\r
-  r = Role.create :name => l(:default_role_manager) \r
-  r.permissions = Permission.find(:all, :conditions => ["is_public=?", false])\r
-  r = Role.create :name => l(:default_role_developper)\r
-  r.permissions = Permission.find(:all, :conditions => ["is_public=?", false])\r
-  r = Role.create :name => l(:default_role_reporter)\r
-  r.permissions = Permission.find(:all, :conditions => ["is_public=?", false])\r
+  manager = Role.create :name => l(:default_role_manager) \r
+  manager.permissions = Permission.find(:all, :conditions => ["is_public=?", false])\r
+  \r
+  developper = Role.create :name => l(:default_role_developper)\r
+  perms = [150, 320, 321, 322, 420, 421, 422, 1050, 1060, 1070, 1075, 1220, 1221, 1222, 1223, 1224, 1320, 1322, 1061, 1057]\r
+  developper.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"])\r
+  \r
+  reporter = Role.create :name => l(:default_role_reporter)\r
+  perms = [1050, 1060, 1070, 1057]\r
+  reporter.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"])\r
+  \r
   # trackers\r
   Tracker.create(:name => l(:default_tracker_bug), :is_in_chlog => true)\r
   Tracker.create(:name => l(:default_tracker_feature), :is_in_chlog => true)\r
   Tracker.create(:name => l(:default_tracker_support), :is_in_chlog => false)\r
+  \r
   # issue statuses\r
-  IssueStatus.create(:name => l(:default_issue_status_new), :is_closed => false, :is_default => true, :html_color => 'F98787')\r
-  IssueStatus.create(:name => l(:default_issue_status_assigned), :is_closed => false, :is_default => false, :html_color => 'C0C0FF')\r
-  IssueStatus.create(:name => l(:default_issue_status_resolved), :is_closed => false, :is_default => false, :html_color => '88E0B3')\r
-  IssueStatus.create(:name => l(:default_issue_status_feedback), :is_closed => false, :is_default => false, :html_color => 'F3A4F4')\r
-  IssueStatus.create(:name => l(:default_issue_status_closed), :is_closed => true, :is_default => false, :html_color => 'DBDBDB')\r
-  IssueStatus.create(:name => l(:default_issue_status_rejected), :is_closed => true, :is_default => false, :html_color => 'F5C28B')\r
+  new       = IssueStatus.create(:name => l(:default_issue_status_new), :is_closed => false, :is_default => true, :html_color => 'F98787')\r
+  assigned  = IssueStatus.create(:name => l(:default_issue_status_assigned), :is_closed => false, :is_default => false, :html_color => 'C0C0FF')\r
+  resolved  = IssueStatus.create(:name => l(:default_issue_status_resolved), :is_closed => false, :is_default => false, :html_color => '88E0B3')\r
+  feedback  = IssueStatus.create(:name => l(:default_issue_status_feedback), :is_closed => false, :is_default => false, :html_color => 'F3A4F4')\r
+  closed    = IssueStatus.create(:name => l(:default_issue_status_closed), :is_closed => true, :is_default => false, :html_color => 'DBDBDB')\r
+  rejected  = IssueStatus.create(:name => l(:default_issue_status_rejected), :is_closed => true, :is_default => false, :html_color => 'F5C28B')\r
+  \r
   # workflow\r
   Tracker.find(:all).each { |t|\r
-    Role.find(:all).each { |r|\r
-      IssueStatus.find(:all).each { |os|\r
-        IssueStatus.find(:all).each { |ns|\r
-          Workflow.create(:tracker_id => t.id, :role_id => r.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns\r
-        }        \r
-      }      \r
+    IssueStatus.find(:all).each { |os|\r
+      IssueStatus.find(:all).each { |ns|\r
+        Workflow.create(:tracker_id => t.id, :role_id => manager.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns\r
+      }        \r
+    }      \r
+  }\r
+  \r
+  Tracker.find(:all).each { |t|\r
+    [new, assigned, resolved, feedback].each { |os|\r
+      [assigned, resolved, feedback, closed].each { |ns|\r
+        Workflow.create(:tracker_id => t.id, :role_id => developper.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns\r
+      }        \r
+    }      \r
+  }\r
+  \r
+  Tracker.find(:all).each { |t|\r
+    [new, assigned, resolved, feedback].each { |os|\r
+      [closed].each { |ns|\r
+        Workflow.create(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns\r
+      }        \r
     }\r
-  }    \r
+    Workflow.create(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => resolved.id, :new_status_id => feedback.id)\r
+  }\r
+\r
   # enumerations\r
   Enumeration.create(:opt => "DCAT", :name => l(:default_doc_category_user))\r
   Enumeration.create(:opt => "DCAT", :name => l(:default_doc_category_tech))\r
@@ -40,4 +80,9 @@ task :load_default_data => :environment do
   Enumeration.create(:opt => "IPRI", :name => l(:default_priority_high))\r
   Enumeration.create(:opt => "IPRI", :name => l(:default_priority_urgent))\r
   Enumeration.create(:opt => "IPRI", :name => l(:default_priority_immediate))\r
+  \r
+rescue => error\r
+  puts "Error: " + error\r
+  puts "Default configuration can't be loaded."\r
+end\r
 end
\ No newline at end of file
diff --git a/redmine/public/images/add.png b/redmine/public/images/add.png
new file mode 100644 (file)
index 0000000..90032e9
Binary files /dev/null and b/redmine/public/images/add.png differ
diff --git a/redmine/public/images/arrow_bw.png b/redmine/public/images/arrow_bw.png
new file mode 100644 (file)
index 0000000..52dfc96
Binary files /dev/null and b/redmine/public/images/arrow_bw.png differ
diff --git a/redmine/public/images/arrow_from.png b/redmine/public/images/arrow_from.png
new file mode 100644 (file)
index 0000000..4d5eeb9
Binary files /dev/null and b/redmine/public/images/arrow_from.png differ
diff --git a/redmine/public/images/arrow_to.png b/redmine/public/images/arrow_to.png
new file mode 100644 (file)
index 0000000..4f96971
Binary files /dev/null and b/redmine/public/images/arrow_to.png differ
diff --git a/redmine/public/images/attachment.png b/redmine/public/images/attachment.png
new file mode 100644 (file)
index 0000000..eea2692
Binary files /dev/null and b/redmine/public/images/attachment.png differ
diff --git a/redmine/public/images/details.png b/redmine/public/images/details.png
new file mode 100644 (file)
index 0000000..7c813b0
Binary files /dev/null and b/redmine/public/images/details.png differ
diff --git a/redmine/public/images/gantt.png b/redmine/public/images/gantt.png
new file mode 100644 (file)
index 0000000..2673d23
Binary files /dev/null and b/redmine/public/images/gantt.png differ
diff --git a/redmine/public/images/jstoolbar/bt_br.png b/redmine/public/images/jstoolbar/bt_br.png
new file mode 100644 (file)
index 0000000..f8211a9
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_br.png differ
diff --git a/redmine/public/images/jstoolbar/bt_code.png b/redmine/public/images/jstoolbar/bt_code.png
new file mode 100644 (file)
index 0000000..52924ab
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_code.png differ
diff --git a/redmine/public/images/jstoolbar/bt_del.png b/redmine/public/images/jstoolbar/bt_del.png
new file mode 100644 (file)
index 0000000..c6f3a8b
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_del.png differ
diff --git a/redmine/public/images/jstoolbar/bt_em.png b/redmine/public/images/jstoolbar/bt_em.png
new file mode 100644 (file)
index 0000000..f08de4f
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_em.png differ
diff --git a/redmine/public/images/jstoolbar/bt_ins.png b/redmine/public/images/jstoolbar/bt_ins.png
new file mode 100644 (file)
index 0000000..f6697db
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_ins.png differ
diff --git a/redmine/public/images/jstoolbar/bt_link.png b/redmine/public/images/jstoolbar/bt_link.png
new file mode 100644 (file)
index 0000000..9b3acba
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_link.png differ
diff --git a/redmine/public/images/jstoolbar/bt_ol.png b/redmine/public/images/jstoolbar/bt_ol.png
new file mode 100644 (file)
index 0000000..2dfaec7
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_ol.png differ
diff --git a/redmine/public/images/jstoolbar/bt_quote.png b/redmine/public/images/jstoolbar/bt_quote.png
new file mode 100644 (file)
index 0000000..25b2b8a
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_quote.png differ
diff --git a/redmine/public/images/jstoolbar/bt_strong.png b/redmine/public/images/jstoolbar/bt_strong.png
new file mode 100644 (file)
index 0000000..7e200d3
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_strong.png differ
diff --git a/redmine/public/images/jstoolbar/bt_ul.png b/redmine/public/images/jstoolbar/bt_ul.png
new file mode 100644 (file)
index 0000000..6e20851
Binary files /dev/null and b/redmine/public/images/jstoolbar/bt_ul.png differ
diff --git a/redmine/public/images/zoom_in.png b/redmine/public/images/zoom_in.png
new file mode 100644 (file)
index 0000000..d9abe7f
Binary files /dev/null and b/redmine/public/images/zoom_in.png differ
diff --git a/redmine/public/images/zoom_in_g.png b/redmine/public/images/zoom_in_g.png
new file mode 100644 (file)
index 0000000..72b271c
Binary files /dev/null and b/redmine/public/images/zoom_in_g.png differ
diff --git a/redmine/public/images/zoom_out.png b/redmine/public/images/zoom_out.png
new file mode 100644 (file)
index 0000000..906e4a4
Binary files /dev/null and b/redmine/public/images/zoom_out.png differ
diff --git a/redmine/public/images/zoom_out_g.png b/redmine/public/images/zoom_out_g.png
new file mode 100644 (file)
index 0000000..7f2416b
Binary files /dev/null and b/redmine/public/images/zoom_out_g.png differ
index 3625914ab7e2dd2fdf60793556b2c6e48c483119..46649130eb919223b470d7cc2300ae0da79f8f48 100644 (file)
@@ -15,5 +15,6 @@ function addFileField() {
         \r
     p = document.getElementById("attachments_p");\r
     p.appendChild(document.createElement("br"));\r
+    p.appendChild(document.createElement("br"));\r
     p.appendChild(f);\r
 }
\ No newline at end of file
index ee7948bb6f76038ee5b288cc958964b2d5044e4b..cf9454619d90d4c89797adb871ab6595b5682597 100644 (file)
@@ -20,6 +20,8 @@
  * ***** END LICENSE BLOCK *****\r
 */\r
 \r
+/* Modified by JP LANG for textile formatting */\r
+\r
 function jsToolBar(textarea) {\r
        if (!document.createElement) { return; }\r
        \r
@@ -344,13 +346,13 @@ jsToolBar.prototype.elements.del = {
 }\r
 \r
 // quote\r
-jsToolBar.prototype.elements.quote = {\r
-       type: 'button',\r
-       title: 'Inline quote',\r
-       fn: {\r
-               wiki: function() { this.singleTag('{{','}}') }\r
-       }\r
-}\r
+//jsToolBar.prototype.elements.quote = {\r
+//     type: 'button',\r
+//     title: 'Inline quote',\r
+//     fn: {\r
+//             wiki: function() { this.singleTag('{{','}}') }\r
+//     }\r
+//}\r
 \r
 // code\r
 jsToolBar.prototype.elements.code = {\r
@@ -362,16 +364,16 @@ jsToolBar.prototype.elements.code = {
 }\r
 \r
 // spacer\r
-jsToolBar.prototype.elements.space1 = {type: 'space'}\r
+//jsToolBar.prototype.elements.space1 = {type: 'space'}\r
 \r
 // br\r
-jsToolBar.prototype.elements.br = {\r
-       type: 'button',\r
-       title: 'Line break',\r
-       fn: {\r
-               wiki: function() { this.encloseSelection("%%%\n",'') }\r
-       }\r
-}\r
+//jsToolBar.prototype.elements.br = {\r
+//     type: 'button',\r
+//     title: 'Line break',\r
+//     fn: {\r
+//             wiki: function() { this.encloseSelection("%%%\n",'') }\r
+//     }\r
+//}\r
 \r
 // spacer\r
 jsToolBar.prototype.elements.space2 = {type: 'space'}\r
@@ -422,8 +424,7 @@ jsToolBar.prototype.elements.link = {
                href = window.prompt(this.elements.link.href_prompt,href);\r
                if (!href) { return false; }\r
                \r
-               hreflang = window.prompt(this.elements.link.hreflang_prompt,\r
-               hreflang);\r
+               hreflang = ""\r
                \r
                return { href: this.stripBaseURL(href), hreflang: hreflang };\r
        }\r
@@ -432,11 +433,8 @@ jsToolBar.prototype.elements.link = {
 jsToolBar.prototype.elements.link.fn.wiki = function() {\r
        var link = this.elements.link.prompt.call(this);\r
        if (link) {\r
-               var stag = '[';\r
-               var etag = '|'+link.href;\r
-               if (link.hreflang) { etag = etag+'|'+link.hreflang; }\r
-               etag = etag+']';\r
-               \r
+               var stag = '"';\r
+               var etag = '":'+link.href;\r
                this.encloseSelection(stag,etag);\r
        }\r
 };\r
index ef9736bd00292a77d1ecf2a8e315695d7225f9fc..c9f3041c9ddbbc1ea827769d478791ed967e4972 100644 (file)
@@ -130,14 +130,14 @@ background-color: #80b0da;
 \r
 html>body #content {\r
 height: auto;\r
-min-height: 300px;\r
+min-height: 500px;\r
 } \r
 \r
 #content{\r
 /*float:right;*/\r
 /*width:530px;*/\r
 width: auto;\r
-height:300px;\r
+height:500px;\r
 font-size:0.9em;\r
 padding:20px 10px 10px 20px;\r
 /*position: absolute;*/\r
@@ -198,7 +198,6 @@ textarea {
 \r
 input {\r
        vertical-align: middle;\r
-       margin-bottom: 4px;\r
 }\r
 \r
 input.button-small \r
@@ -263,10 +262,10 @@ tr.ListHead a {
        text-decoration:underline;\r
 }\r
 \r
-tr.odd {\r
+.odd {\r
        background-color:#f0f1f2;\r
 }\r
-tr.even {\r
+.even {\r
        background-color: #fff;\r
 }\r
 \r
@@ -280,14 +279,24 @@ table.reportTableContent td {
        padding:2px;\r
 }\r
 \r
+table.calenderTable {\r
+       border:1px solid #578bb8;\r
+       width:99%;\r
+       border-collapse: collapse;\r
+}\r
+\r
+table.calenderTable td {\r
+       border:1px solid #578bb8;\r
+}\r
+\r
 hr { border:none; border-bottom: dotted 2px #c0c0c0; }\r
 \r
 \r
 /**************** Sidebar styles ****************/\r
 \r
 #subcontent{\r
-float:left;\r
-clear:both;\r
+position: absolute;\r
+left: 0px;\r
 width:110px;\r
 padding:20px 20px 10px 5px;\r
 }\r