changeset 1210:16826c3afbba redmine-2.2-integration

Merge from branch "live"
author Chris Cannam
date Wed, 23 Jan 2013 13:15:33 +0000
parents ad10dc713462 (current diff) e60f4ccfdc70 (diff)
children 1186340b4ad4
files app/controllers/my_controller.rb app/controllers/projects_controller.rb app/helpers/projects_helper.rb app/views/layouts/base.html.erb app/views/my/page.html.erb app/views/projects/index.html.erb app/views/welcome/index.html.erb config/environment.rb config/locales/en.yml plugins/redmine_bibliography/app/models/publication.rb plugins/redmine_bibliography/app/views/activities/_recent.html.erb plugins/redmine_bibliography/app/views/activities/index.html.erb plugins/redmine_bibliography/init.rb plugins/redmine_tags/app/views/projects/_my.html.erb plugins/redmine_tags/app/views/projects/_tagcloud.html.erb plugins/redmine_tags/app/views/projects/index.html.erb plugins/redmine_tags/lib/redmine_tags/patches/projects_controller_patch.rb public/stylesheets/application.css public/themes/soundsoftware/stylesheets/application.css
diffstat 24 files changed, 394 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/app/controllers/my_controller.rb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/controllers/my_controller.rb	Wed Jan 23 13:15:33 2013 +0000
@@ -21,6 +21,7 @@
   helper :issues
   helper :users
   helper :custom_fields
+  helper :projects
 
   BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
              'issuesreportedbyme' => :label_reported_issues,
@@ -30,11 +31,12 @@
              'tipoftheday' => :label_tipoftheday,
              'calendar' => :label_calendar,
              'documents' => :label_document_plural,
-             'timelog' => :label_spent_time
+             'timelog' => :label_spent_time,
+             'myprojects' => :label_my_projects
            }.merge(Redmine::Views::MyPage::Block.additional_blocks).freeze
 
-  DEFAULT_LAYOUT = {  'left' => ['tipoftheday', 'activitymyprojects'], 
-                      'right' => ['issueswatched'] 
+  DEFAULT_LAYOUT = {  'left' => ['myprojects', 'activitymyprojects'], 
+                      'right' => ['tipoftheday', 'issueswatched'] 
                    }.freeze
 
   def index
--- a/app/controllers/projects_controller.rb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/controllers/projects_controller.rb	Wed Jan 23 13:15:33 2013 +0000
@@ -58,11 +58,6 @@
         @project_pages = Paginator.new self, @project_count, @limit, params['page']
         @offset ||= @project_pages.current.offset
         @projects = Project.visible_roots.all(:offset => @offset, :limit => @limit, :order => sort_clause)
-        if User.current.logged?
-          # seems sort_by gives us case-sensitive ordering, which we don't want
-#          @user_projects = User.current.projects.sort_by(&:name)
-          @user_projects = User.current.projects.all(:order => :name)
-        end
         render :template => 'projects/index.html.erb', :layout => !request.xhr?
 
 ## Redmine 2.2:
--- a/app/helpers/activities_helper.rb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/helpers/activities_helper.rb	Wed Jan 23 13:15:33 2013 +0000
@@ -1,14 +1,52 @@
 
 module ActivitiesHelper
 
+  def date_of_event(e)
+    if e.respond_to? :updated_at
+      e.updated_at
+    elsif e.respond_to? :updated_on
+      e.updated_on
+    elsif e.respond_to? :created_on
+      e.created_on
+    elsif e.respond_to? :committed_on
+      e.committed_on
+    else
+      nil 
+    end
+  end
+
   def busy_projects(events, count)
-    # Transform events list into hash from project id to number of
-    # occurrences of project in list (there is surely a tidier way
-    # to do this, e.g. chunk() in Ruby 1.9 but not in 1.8)
-    phash = events.map { |e| e.project unless !e.respond_to?(:project) }.sort.group_by { |p| p.id }
-    phash = phash.merge(phash) { |k,v| v.length }
-    threshold = phash.values.sort.last(count).first
-    busy = phash.keys.select { |k| phash[k] >= threshold }.sample(count)
+
+    # Score each project for which there are any events, by giving
+    # each event a score based on how long ago it was (the more recent
+    # the better).
+
+    projhash = Hash.new
+    
+    events.each do |e|
+      if e.respond_to?(:project)
+        p = e.project
+        d = date_of_event e
+        if !d.nil?
+          dd = Date.parse d.to_s
+          age = Date.today - dd
+          score = (age < 14 ? 15-age : 1)
+          if projhash.key? p
+            projhash[p] += score
+          else
+            projhash[p] = score
+          end
+        end
+      end
+    end
+
+    # pick N highest values and use cutoff value as selection threshold
+    threshold = projhash.values.sort.last(count).first
+
+    # select projects above threshold and pick N from them randomly
+    busy = projhash.keys.select { |k| projhash[k] >= threshold }.sample(count)
+
+    # return projects rather than just ids
     busy.map { |pid| Project.find(pid) }
   end
 
--- a/app/helpers/projects_helper.rb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/helpers/projects_helper.rb	Wed Jan 23 13:15:33 2013 +0000
@@ -263,4 +263,38 @@
     sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing)
     l("label_version_sharing_#{sharing}")
   end
+
+  def score_maturity(project)
+    nr_changes = (project.repository.nil? ? 0 : project.repository.changesets.count)
+    downloadables = [project.attachments,
+                     project.versions.collect { |v| v.attachments },
+                     project.documents.collect { |d| d.attachments }].flatten
+    nr_downloadables = downloadables.count
+    nr_downloads = downloadables.map do |d| d.downloads end.sum
+    nr_members = project.members.count
+    nr_publications = if project.respond_to? :publications
+                      then project.publications.count else 0 end
+    Math.log(1 + nr_changes) +
+      Math.log(1 + nr_downloadables) +
+      Math.log(1 + nr_downloads) +
+      Math.sqrt(nr_members > 1 ? (nr_members - 1) : 0) +
+      Math.sqrt(nr_publications)
+  end
+
+  def all_maturity_scores()
+    phash = Hash.new
+    pp = Project.visible(User.anonymous)
+    pp.each do |p| 
+      phash[p] = score_maturity p
+    end
+    phash
+  end
+
+  def mature_projects(count)
+    phash = all_maturity_scores
+    scores = phash.values.sort
+    threshold = scores[scores.length / 2]
+    if threshold == 0 then threshold = 1 end
+    phash.keys.select { |k| phash[k] > threshold }.sample(count)
+  end
 end
--- a/app/views/activities/_busy.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/views/activities/_busy.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -1,7 +1,8 @@
 <% events = @events_by_day %>
 <% if (events.nil?) 
      activity = Redmine::Activity::Fetcher.new(User.anonymous)
-     events = activity.events(Date.today - 14, Date.today + 1)
+     days = Setting.activity_days_default.to_i
+     events = activity.events(Date.today - days, Date.today + 1)
    end
 %>
 
@@ -31,11 +32,11 @@
      <%
 	u = project.users_by_role
 	if ! u.empty? %>
-     (<%=
+        <%=
 	   mgmt_roles = u.keys.select{ |r| r.allowed_to?(:edit_project) }
 	   managers = mgmt_roles.map{ |r| u[r] }.flatten.sort.uniq
 	   managers.map{ |m| m.name }.join(', ')
-	 %>)<%
+	 %><%
 	end
 	%>
 	</span>
@@ -45,4 +46,5 @@
 
     <% end %>
   </ul>
+
 <% end %>
--- a/app/views/layouts/base.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/views/layouts/base.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -55,6 +55,9 @@
       <% unless page_header_title[1].empty? %>
         style="margin-top: 0px; "
       <% end %>  
+      <% if !@project.nil? and @project.name.length > 35 %>
+        class="long-title"
+      <% end %>
     ><% if display_main_menu?(@project) %>
        <%= link_to_project(@project) %>
      <% else %> 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/views/my/blocks/_myprojects.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -0,0 +1,16 @@
+<%  @user_projects = User.current.projects.all(:order => :name) %>
+
+<% if @user_projects.empty? %>
+<h3><%=l(:label_my_projects)%></h3>
+<div class="box">
+  <div class="tip"><%= l(:label_have_no_projects)%> <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}) if User.current.allowed_to?(:add_project, nil, :global => true) %></div>
+</div>
+<% else %>
+<h3><%=l(:label_my_projects)%> (<%= @user_projects.count %>)</h3>
+<div class="box">
+<%=
+   render :partial => 'projects/my', :locals => { :user => User.current }
+ %>
+</div>
+<% end %>
+
--- a/app/views/my/page.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/views/my/page.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -1,3 +1,7 @@
+<% content_for :header_tags do %>
+    <%= stylesheet_link_tag 'redmine_tags', :plugin => 'redmine_tags' %>
+<% end %>
+
 <div class="contextual">
     <%= link_to l(:label_personalize_page), :action => 'page_layout' %>
     <%= '| ' + link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') if User.current.allowed_to?(:add_project, nil, :global => true) %>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/views/projects/_mature.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -0,0 +1,38 @@
+
+   <ul>
+
+   <% 
+      for project in mature_projects(5)
+   %>
+
+   <li class="busy">
+     <span class="title">
+       <% if !project.root? %>
+         <% project.ancestors.each do |p| %>
+           <%= h(p) %>&nbsp;&#187;
+         <% end %>
+       <% end %>
+       <%= link_to_project project %>
+     </span>
+     <% if !project.is_public? %>
+       <span class="private"><%= l(:field_is_private) %></span>
+     <% end %>
+     <span class='managers'>
+     <%
+	u = project.users_by_role
+	if ! u.empty? %>
+        <%=
+	   mgmt_roles = u.keys.select{ |r| r.allowed_to?(:edit_project) }
+	   managers = mgmt_roles.map{ |r| u[r] }.flatten.sort.uniq
+	   managers.map{ |m| m.name }.join(', ')
+	 %><%
+	end
+	%>
+	</span>
+
+     <%= render_project_short_description project %>
+   </li>
+
+    <% end %>
+  </ul>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/views/projects/_my.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -0,0 +1,1 @@
+<%= render_my_project_hierarchy(@user_projects) %>
--- a/app/views/projects/explore.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/views/projects/explore.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -2,8 +2,13 @@
     <%= stylesheet_link_tag 'redmine_tags', :plugin => 'redmine_tags' %>
 <% end %>
 
+<div class="contextual">
+    <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') if User.current.allowed_to?(:add_project, nil, :global => true) %>
+</div>
+
+<h2><%= l(:label_explore_projects) %></h2>
+
 <% cache(:action => 'explore', :action_suffix => 'tags', :expires_in => 1.hour) do %>
-<h2><%= l(:label_explore_projects) %></h2>
   <div class="tags box">
   <h3><%=l(:label_project_tags_all)%></h3>
     <%= render :partial => 'projects/tagcloud' %>
@@ -15,11 +20,13 @@
   <div class="institutions box">
   <h3><%=l(:label_institutions_busy)%></h3>
     <%= render :partial => 'activities/busy_institution' %>
+    <%= link_to l(:label_overall_activity), { :controller => 'activities', :action => 'index' }, :class => 'more' %>
   </div>
   <% end %>
   <div class="projects box">
   <h3><%=l(:label_project_latest)%></h3>
     <%= render :partial => 'projects/latest' %>
+    <%= link_to l(:label_projects_more), { :controller => 'projects' }, :class => 'more' %>
   </div>
 </div>
 <div class="splitcontentright">
@@ -27,6 +34,13 @@
   <div class="projects box">
   <h3><%=l(:label_projects_busy)%></h3>
     <%= render :partial => 'activities/busy' %>
+    <%= link_to l(:label_overall_activity), { :controller => 'activities', :action => 'index' }, :class => 'more' %>
+  </div>
+  <% end %>
+  <% cache(:action => 'explore', :action_suffix => 'mature_projects', :expires_in => 1.hour) do %>
+  <div class="projects box">
+  <h3><%=l(:label_projects_mature)%></h3>
+    <%= render :partial => 'projects/mature' %>
   </div>
   <% end %>
 </div>
--- a/app/views/projects/index.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/views/projects/index.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -8,12 +8,6 @@
     <%= ('| ' + link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add')).html_safe if User.current.allowed_to?(:add_project, nil, :global => true) %>
 </div>
 
-<% if @user_projects %>
-  
-  <%= render_my_project_hierarchy(@user_projects) %>
-
-<% end %>
-
 <h2>
 <%= l("label_project_all") %>
 </h2>
--- a/app/views/welcome/index.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/app/views/welcome/index.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -23,7 +23,7 @@
   <div class="projects box">
   <h3><%=l(:label_project_latest)%></h3>
     <%= render :partial => 'projects/latest' %>
-    <%= link_to l(:label_projects_more), :controller => 'projects' %>
+    <%= link_to l(:label_projects_more), { :controller => 'projects' }, :class => 'more' %>
   </div>
     <%= call_hook(:view_welcome_index_right, :projects => @projects) %>
 </div>
--- a/config/locales/en.yml	Wed Jan 16 16:59:49 2013 +0000
+++ b/config/locales/en.yml	Wed Jan 23 13:15:33 2013 +0000
@@ -350,7 +350,7 @@
   setting_external_repository_url: "The URL of the existing external repository. Must be publicly accessible without a password"
   label_repository_external_url: "External repository URL"
   field_terms_and_conditions: 'Terms and Conditions:'
-  accept_terms_and_conditions: 'I have read and agree with the '
+  accept_terms_and_conditions: 'I have read, and agree to, the '
   setting_app_title: Application title
   setting_app_subtitle: Application subtitle
   setting_welcome_text: Welcome text
@@ -497,8 +497,6 @@
   project_module_embedded: Embedded documentation (Javadoc, Doxygen or MATLAB)
   label_tipoftheday: Tip of the day
   label_notifications: Important Message
-  field_terms_and_conditions: 'Terms and Conditions:'
-  accept_terms_and_conditions: 'I have read and agree with the '
   label_ssamr_description: Research description
   label_ssamr_details: Other Details
   label_ssamr_institution: Institution
@@ -512,6 +510,7 @@
   label_project_plural: Projects
   label_my_project_plural: My Projects
   label_other_project_plural: Other Projects
+  label_have_no_projects: You are not a member of any projects.
   label_x_projects:
     zero:  no projects
     one:   1 project
@@ -525,6 +524,7 @@
   label_projects_more: More projects
   label_project_tags_all: Popular tags
   label_projects_busy: Busy projects
+  label_projects_mature: Mature projects
   label_institutions_busy: Active institutions
   label_managers: Managed by
   label_issue: Issue
--- a/plugins/redmine_bibliography/app/models/publication.rb	Wed Jan 16 16:59:49 2013 +0000
+++ b/plugins/redmine_bibliography/app/models/publication.rb	Wed Jan 23 13:15:33 2013 +0000
@@ -19,6 +19,25 @@
 
   before_save :set_initial_author_order
 
+  named_scope :visible, lambda {|*args| { :include => :projects,
+                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_publication, *args) } }
+
+  acts_as_activity_provider :type => 'publication',
+                            :timestamp => "#{Publication.table_name}.created_at",
+                            :find_options => {
+                              :include => :projects,
+                              :conditions => "#{Project.table_name}.id = projects_publications.project_id"
+                            }
+
+  acts_as_event :title => Proc.new {|o| o.title },
+                :datetime => :created_at,
+                :type => 'publications',
+                :author => nil,
+                #todo - need too move the cache from the helper to the model
+                :description => Proc.new {|o| o.print_entry(:ieee)},
+                :url => Proc.new {|o| {:controller => 'publications', :action => 'show', :id => o.id }}
+
+
   # Ensure error message uses proper text instead of
   # bibtex_entry.entry_type (#268).  There has to be a better way to
   # do this!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/redmine_bibliography/app/views/activities/_recent.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -0,0 +1,92 @@
+<% events = @events_by_day %>
+<% max = 5 %>
+<% if (events.nil?)
+     activity = Redmine::Activity::Fetcher.new(User.current, :project => @project)
+
+     if @project
+        # Don't show news (duplicated with News box) or wiki edits (too
+	# tedious) in project front page
+        activity.scope = [ "changesets", "files", "issues", "documents" ]
+     end
+
+     events = activity.events(Date.today - 28, Date.today + 1)
+
+     if defined? user
+        events = events.select { |e|
+
+          if e.class != Publication
+            user.member_of? e.project
+          else
+            e.projects.map {|p| user.member_of? p }.any?
+          end
+        }
+
+     end
+
+     events = events.first(max)
+
+   end
+%>
+
+<div id="activity">
+
+<% if @project.nil? %>
+   <%= content_tag('h3', l(:label_activity_my_recent)) %>
+   <div class="activity box">
+<% end %>
+
+<% if events.empty? %>
+
+   <% if @project.nil? %>
+     <div class="tip"><%= l(:label_activity_my_recent_none) %></div>
+   <% end %>
+
+<% else %>
+
+   <% if !@project.nil? %>
+     <div class="activity box">
+     <%= content_tag('h3', l(:label_activity_recent)) %>
+   <% end %>
+
+   <dl>
+   <% events.sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
+    <%- if e.class != Publication -%>
+      <dt class="<%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
+     	<%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
+        <span class="time"><%= format_time(e.event_datetime) %></span>
+        <%= content_tag('span', link_to_project(e.project), :class => 'project') if @project.nil? || @project != e.project %>
+        <% if e.respond_to?(:event_author) %>
+          <span class="author"><%= e.event_author %></span>
+        <% end %>
+      </dt>
+      <dd><%= link_to format_activity_title(e.event_title), e.event_url %>
+        <span class="description"><%= format_activity_description(e.event_description) %></span>
+      </dd>
+     <% else -%>
+      <dt class="<%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
+         <span class="time"><%= format_time(e.event_datetime) %></span>
+          <%= link_to format_activity_title(e.event_title), e.event_url %>
+      was added to the following
+      <% if e.projects.count > 1 %>
+        projects:
+      <%- else -%>
+        project:
+      <%- end -%>
+      <%= content_tag('span', e.projects.join(', ')) -%>         <% if e.respond_to?(:event_author) %>
+             <span class="author"><%= e.event_author %></span>
+         <% end %>
+        </dt>
+           <dd><%= link_to format_activity_title(e.event_title), e.event_url %>
+           <span class="description"><%= format_activity_description(e.event_description) %></span>
+           </dd>
+     <% end -%>
+   <% end -%>
+   </dl>
+
+   </div>
+
+<% end %>
+
+<% if events.empty? and @project.nil? %></div><% end %>
+
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/redmine_bibliography/app/views/activities/index.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -0,0 +1,91 @@
+<h2><%=
+  if @author.nil?
+    if @institution_name.blank?
+      l(:label_activity)
+    else
+      l(:label_institution_activity, h(@institution_name))
+    end
+  else
+    l(:label_user_activity, link_to_user(@author))
+  end
+  %></h2>
+<p class="subtitle"><%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %></p>
+
+<div id="activity">
+<% @events_by_day.keys.sort.reverse.each do |day| %>
+<h3><%= format_activity_day(day) %></h3>
+<dl>
+<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
+  <%- if e.class != Publication -%>
+    <dt class="<%= e.event_type %>  <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
+      <%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
+      <span class="time"><%= format_time(e.event_datetime, false) %></span>
+      <%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %>
+      <%= link_to format_activity_title(e.event_title), e.event_url %>
+    </dt>
+    <dd>
+      <span class="description"><%= format_activity_description(e.event_description) %></span>
+      <span class="author"><%= link_to_user(e.event_author) if e.respond_to?(:event_author) %></span>
+    </dd>
+  <%- else -%>
+    <dt class="<%= e.event_type %>  <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
+      <%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
+      <span class="time"><%= format_time(e.event_datetime, false) %></span>
+      <%= link_to format_activity_title(e.event_title), e.event_url %>
+      was added to the following
+      <% if e.projects.count > 1 %>
+        projects:
+      <%- else -%>
+        project:
+      <%- end -%>
+      <%= content_tag('span', e.projects.join(', ')) -%>
+    </dt>
+    <dd>
+      <span class="description"><%= e.event_description -%></span>
+      <span class="author"><%= link_to_user(e.event_author) if e.respond_to?(:event_author) %></span>
+    </dd>
+  <% end -%>
+<%- end -%>
+</dl>
+<% end -%>
+</div>
+
+<%= content_tag('p', l(:label_no_data), :class => 'nodata') if @events_by_day.empty? %>
+
+<div style="float:left;">
+<%= link_to_content_update("\xc2\xab " + l(:label_previous),
+                   params.merge(:from => @date_to - @days - 1),
+                   :title => l(:label_date_from_to, :start => format_date(@date_to - 2*@days), :end => format_date(@date_to - @days - 1))) %>
+</div>
+<div style="float:right;">
+<%= link_to_content_update(l(:label_next) + " \xc2\xbb",
+                   params.merge(:from => @date_to + @days - 1),
+                   :title => l(:label_date_from_to, :start => format_date(@date_to), :end => format_date(@date_to + @days - 1))) unless @date_to >= Date.today %>
+</div>
+&nbsp;
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => params.merge(:from => nil, :key => User.current.rss_key) %>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(:atom, params.merge(:format => 'atom', :from => nil, :key => User.current.rss_key)) %>
+<% end %>
+
+<% content_for :sidebar do %>
+<% form_tag({}, :method => :get) do %>
+<h3><%= l(:label_activity) %></h3>
+<p><% @activity.event_types.each do |t| %>
+<%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %>
+<label for="show_<%=t%>"><%= link_to(l("label_#{t.singularize}_plural"), {"show_#{t}" => 1, :user_id => params[:user_id]})%></label>
+<br />
+<% end %></p>
+<% if @project && @project.descendants.active.any? %>
+    <%= hidden_field_tag 'with_subprojects', 0 %>
+    <p><label><%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%></label></p>
+<% end %>
+<%= hidden_field_tag('user_id', params[:user_id]) unless params[:user_id].blank? %>
+<p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p>
+<% end %>
+<% end %>
+
+<% html_title(l(:label_activity), @author) -%>
--- a/plugins/redmine_bibliography/init.rb	Wed Jan 16 16:59:49 2013 +0000
+++ b/plugins/redmine_bibliography/init.rb	Wed Jan 23 13:15:33 2013 +0000
@@ -39,15 +39,22 @@
   settings :default => { 'menu' => 'Publications' }, :partial => 'settings/bibliography'
 
   project_module :redmine_bibliography do
+    permission :view_publication, {:publications => :show}, :public => :true
     permission :publications, { :publications => :index }, :public => true
     permission :edit_publication, {:publications => [:edit, :update]}
     permission :add_publication, {:publications => [:new, :create]}
     permission :delete_publication, {:publications => :destroy}
 
+
   end
 
   # extending the Project Menu
   menu :project_menu, :publications, { :controller => 'publications', :action => 'index', :path => nil }, :after => :activity, :param => :project_id, :caption => Proc.new { Setting.plugin_redmine_bibliography['menu'] },
    :if => Proc.new { !Setting.plugin_redmine_bibliography['menu'].blank? }
 
+  activity_provider :publication, :class_name => 'Publication', :default => true
+
 end
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/redmine_tags/app/views/projects/_my.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -0,0 +1,1 @@
+<%= render_my_project_hierarchy_with_tags(@user_projects) %>
--- a/plugins/redmine_tags/app/views/projects/_tagcloud.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/plugins/redmine_tags/app/views/projects/_tagcloud.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -1,6 +1,6 @@
 
 <div id="tags">
-<%= render_tags_list(Project.available_tags, :style => :cloud) %>
+<%= render_tags_list(Project.available_tags.select { |t| Project.tagged_with(t).count > 1 }, :style => :cloud) %>
 </div>
 
 
--- a/plugins/redmine_tags/app/views/projects/index.html.erb	Wed Jan 16 16:59:49 2013 +0000
+++ b/plugins/redmine_tags/app/views/projects/index.html.erb	Wed Jan 23 13:15:33 2013 +0000
@@ -13,7 +13,9 @@
 
 <div style="clear:both;"></div>
 <% if User.current.logged? %>
-  <%= render :partial => 'my_projects' %>
+<div class="splitcontentleft">
+  <div class=box><b>Looking for a list of your own projects?</b><br>It's moved to <%= link_to l(:label_my_page), { :controller => 'my', :action => 'page' } %>.</div>
+</div>
 <% end %>
 
 <div style="clear:both;"></div>
--- a/plugins/redmine_tags/lib/redmine_tags/patches/projects_controller_patch.rb	Wed Jan 16 16:59:49 2013 +0000
+++ b/plugins/redmine_tags/lib/redmine_tags/patches/projects_controller_patch.rb	Wed Jan 23 13:15:33 2013 +0000
@@ -91,12 +91,6 @@
               # todo: check ordering ~luisf.14/Jan/2013
               @projects = @projects[@offset, @limit]
 
-              if User.current.logged?
-                # seems sort_by gives us case-sensitive ordering, which we don't want
-                #          @user_projects = User.current.projects.sort_by(&:name)
-                @user_projects = User.current.projects.all(:order => :name)
-              end
-
               render :template => 'projects/index.html.erb', :layout => !request.xhr?
             }
             format.api {
--- a/public/stylesheets/application.css	Wed Jan 16 16:59:49 2013 +0000
+++ b/public/stylesheets/application.css	Wed Jan 23 13:15:33 2013 +0000
@@ -374,7 +374,7 @@
 div#activity dd, div#news dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
 div#activity dt, div#news dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
 div#activity dt.me .time, div#news dt.me .time { border-bottom: 1px solid #999; }
-div#activity dt .time, div#news dt .time, .projects .latest .time { color: #777; font-size: 80%; }
+div#activity dt .time, div#news dt .time, .projects .latest .time, .projects .busy .managers { color: #777; font-size: 80%; }
 div#activity dd .description, #search-results dd .description { font-style: italic; }
 div#activity span.project:after, div#news span.project:after, #search-results span.project:after { content: " -"; }
 div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
@@ -405,7 +405,7 @@
   margin-left: 0;
 }
 
-.projects .latest .title { margin-right: 0.5em; }
+.projects .latest .title, .projects .busy .title { margin-right: 0.5em; }
 .tipoftheday .tip { margin-left: 2em; margin-top: 0.5em; }
 
 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
@@ -457,18 +457,18 @@
 
 ul.projects { margin: 0; padding-left: 1em; }
 ul.projects.root { margin: 0;  padding: 0; }
-ul.projects ul.projects { border-left: 3px solid #e0e0e0; }
+/*ul.projects ul.projects { border-left: 3px solid #e0e0e0; } */
 ul.projects li.root { list-style-type:none; margin-bottom: 1em; }
-ul.projects li.child { list-style-type:none; margin-top: 1em;}
-ul.projects div.root a.project { font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
+ul.projects li.child { list-style-type:none; }
+ul.projects div.root a.project { font-weight: bold; }
 
+li.latest, li.busy { margin-bottom: 0.5em; }
 #projects-index ul.projects ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;}
 #projects-index ul.projects li.root {margin-bottom: 1em;}
 #projects-index ul.projects li.child {margin-top: 1em;}
 #projects-index ul.projects div.root a.project { font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
 /* .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; } */
 
-li.latest { margin-bottom: 0.5em; }
 
 #notified-projects ul, #tracker_project_ids ul {max-height:250px; overflow-y:auto;}
 
--- a/public/themes/soundsoftware/stylesheets/application.css	Wed Jan 16 16:59:49 2013 +0000
+++ b/public/themes/soundsoftware/stylesheets/application.css	Wed Jan 23 13:15:33 2013 +0000
@@ -86,6 +86,8 @@
 .odd {background-color:#fdf7e4;}
 .even {background-color: #fdfaf0;}
 
+.box .more { margin-left: 40px; }
+
 #content .tabs { margin-bottom: 0; }
 
 table.list th {  background-color: #fdfaf0; border-bottom: 1px solid #a9b680; }
@@ -105,7 +107,7 @@
 table.projects .level2 .firstcol { padding-left: 2em; }
 table.projects .level3 .firstcol { padding-left: 3em; }
 
-ul.projects .public, ul.projects .private { padding-left: 0.5em; color: #3e442c; font-size: 0.95em }
+ul.projects .public, ul.projects .private { padding-left: 0.5em; color: #3e442c; font-size: 0.9em }
 
 table.files tr.active td { padding-top: 0.5em; padding-bottom: 0.5em; }
 table.files .file .active { font-weight: bold; }
@@ -117,6 +119,7 @@
 #header {  position: absolute; z-index: 0; top: 0; width: 100%; background: #fdfbf5; border-bottom: 2px solid #a9b680; /* height:80px; */ padding: 20px 0 0.5em 0; margin-bottom: 0; }
 #header a { color: #be5700; }
 #header h1 { color: #525a38; margin-top: 25px; font-size: 3em; font-weight: normal; margin-left: 10px; }
+#header h1#project-title.long-title { font-size: 2em; line-height: 0.95em }
 #header #project-title a, #header #project-title a:hover { color: #525a38; text-decoration: none; }
 .header-general h1 {
   background: url('soundsoftware-logo-code-title-only-transparent.png') no-repeat 0 0;