Revision 1298:4f746d8966dd app/helpers

View differences:

app/helpers/account_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/activities_helper.rb
1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1 19

  
2 20
module ActivitiesHelper
3 21

  
......
147 165
    threshold = insthash.values.sort.last(count).first
148 166
    insthash.keys.select { |k| insthash[k] >= threshold }.sample(count)
149 167
  end
168
  
169
  def sort_activity_events(events)
170
    events_by_group = events.group_by(&:event_group)
171
    sorted_events = []
172
    events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each do |event|
173
      if group_events = events_by_group.delete(event.event_group)
174
        group_events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each_with_index do |e, i|
175
          sorted_events << [e, i > 0]
176
        end
177
      end
178
    end
179
    sorted_events
180
  end
150 181

  
151 182
end
app/helpers/admin_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/application_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
24 24
  include Redmine::WikiFormatting::Macros::Definitions
25 25
  include Redmine::I18n
26 26
  include GravatarHelper::PublicMethods
27
  include Redmine::Pagination::Helper
27 28

  
28 29
  extend Forwardable
29 30
  def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
......
90 91
  # * :download - Force download (default: false)
91 92
  def link_to_attachment(attachment, options={})
92 93
    text = options.delete(:text) || attachment.filename
93
    action = options.delete(:download) ? 'download' : 'show'
94
    opt_only_path = {}
95
    opt_only_path[:only_path] = (options[:only_path] == false ? false : true)
96
    options.delete(:only_path)
97
    link_to(h(text),
98
           {:controller => 'attachments', :action => action,
99
            :id => attachment, :filename => attachment.filename}.merge(opt_only_path),
100
           options)
94
    route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path
95
    html_options = options.slice!(:only_path)
96
    url = send(route_method, attachment, attachment.filename, options)
97
    link_to text, url, html_options
101 98
  end
102 99

  
103 100
  # Generates a link to a SCM revision
......
119 116
  # Generates a link to a message
120 117
  def link_to_message(message, options={}, html_options = nil)
121 118
    link_to(
122
      h(truncate(message.subject, :length => 60)),
123
      { :controller => 'messages', :action => 'show',
124
        :board_id => message.board_id,
125
        :id => (message.parent_id || message.id),
119
      truncate(message.subject, :length => 60),
120
      board_message_path(message.board_id, message.parent_id || message.id, {
126 121
        :r => (message.parent_id && message.id),
127 122
        :anchor => (message.parent_id ? "message-#{message.id}" : nil)
128
      }.merge(options),
123
      }.merge(options)),
129 124
      html_options
130 125
    )
131 126
  end
......
134 129
  # Examples:
135 130
  #
136 131
  #   link_to_project(project)                          # => link to the specified project overview
137
  #   link_to_project(project, :action=>'settings')     # => link to project settings
138 132
  #   link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options
139 133
  #   link_to_project(project, {}, :class => "project") # => html options with default url (project overview)
140 134
  #
141 135
  def link_to_project(project, options={}, html_options = nil)
142 136
    if project.archived?
143
      h(project)
137
      h(project.name)
138
    elsif options.key?(:action)
139
      ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0."
140
      url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
141
      link_to project.name, url, html_options
144 142
    else
145
      url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
146
      link_to(h(project), url, html_options)
143
      link_to project.name, project_path(project, options), html_options
144
    end
145
  end
146

  
147
  # Generates a link to a project settings if active
148
  def link_to_project_settings(project, options={}, html_options=nil)
149
    if project.active?
150
      link_to project.name, settings_project_path(project, options), html_options
151
    elsif project.archived?
152
      h(project.name)
153
    else
154
      link_to project.name, project_path(project, options), html_options
147 155
    end
148 156
  end
149 157

  
......
152 160
  end
153 161

  
154 162
  def thumbnail_tag(attachment)
155
    link_to image_tag(url_for(:controller => 'attachments', :action => 'thumbnail', :id => attachment)),
156
      {:controller => 'attachments', :action => 'show', :id => attachment, :filename => attachment.filename},
163
    link_to image_tag(thumbnail_path(attachment)),
164
      named_attachment_path(attachment, attachment.filename),
157 165
      :title => attachment.filename
158 166
  end
159 167

  
......
187 195

  
188 196
  def format_version_name(version)
189 197
    if version.project == @project
190
    	h(version)
198
      h(version)
191 199
    else
192 200
      h("#{version.project} - #{version}")
193 201
    end
......
341 349
  def options_for_membership_project_select(principal, projects)
342 350
    options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
343 351
    options << project_tree_options_for_select(projects) do |p|
344
      {:disabled => principal.projects.include?(p)}
352
      {:disabled => principal.projects.to_a.include?(p)}
345 353
    end
346 354
    options
347 355
  end
......
397 405
    str.blank? ? nil : str
398 406
  end
399 407

  
400
  def pagination_links_full(paginator, count=nil, options={})
401
    page_param = options.delete(:page_param) || :page
402
    per_page_links = options.delete(:per_page_links)
403
    url_param = params.dup
404

  
405
    html = ''
406
    if paginator.current.previous
407
      # \xc2\xab(utf-8) = &#171;
408
      html << link_to_content_update(
409
                   "\xc2\xab " + l(:label_previous),
410
                   url_param.merge(page_param => paginator.current.previous)) + ' '
411
    end
412

  
413
    html << (pagination_links_each(paginator, options) do |n|
414
      link_to_content_update(n.to_s, url_param.merge(page_param => n))
415
    end || '')
416

  
417
    if paginator.current.next
418
      # \xc2\xbb(utf-8) = &#187;
419
      html << ' ' + link_to_content_update(
420
                      (l(:label_next) + " \xc2\xbb"),
421
                      url_param.merge(page_param => paginator.current.next))
422
    end
423

  
424
    unless count.nil?
425
      html << " (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})"
426
      if per_page_links != false && links = per_page_links(paginator.items_per_page, count)
427
	      html << " | #{links}"
428
      end
429
    end
430

  
431
    html.html_safe
432
  end
433

  
434
  def per_page_links(selected=nil, item_count=nil)
435
    values = Setting.per_page_options_array
436
    if item_count && values.any?
437
      if item_count > values.first
438
        max = values.detect {|value| value >= item_count} || item_count
439
      else
440
        max = item_count
441
      end
442
      values = values.select {|value| value <= max || value == selected}
443
    end
444
    if values.empty? || (values.size == 1 && values.first == selected)
445
      return nil
446
    end
447
    links = values.collect do |n|
448
      n == selected ? n : link_to_content_update(n, params.merge(:per_page => n))
449
    end
450
    l(:label_display_per_page, links.join(', '))
451
  end
452

  
453 408
  def reorder_links(name, url, method = :post)
454 409
    link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
455 410
            url.merge({"#{name}[move_to]" => 'highest'}),
......
529 484
  end
530 485

  
531 486
  def accesskey(s)
532
    Redmine::AccessKeys.key_for s
487
    @used_accesskeys ||= []
488
    key = Redmine::AccessKeys.key_for(s)
489
    return nil if @used_accesskeys.include?(key)
490
    @used_accesskeys << key
491
    key
533 492
  end
534 493

  
535 494
  # Formats text according to system settings.
......
617 576
        filename, ext, alt, alttext = $1.downcase, $2, $3, $4
618 577
        # search for the picture in attachments
619 578
        if found = Attachment.latest_attach(attachments, filename)
620
          image_url = url_for :only_path => only_path, :controller => 'attachments',
621
                              :action => 'download', :id => found
579
          image_url = download_named_attachment_path(found, found.filename, :only_path => only_path)
622 580
          desc = found.description.to_s.gsub('"', '')
623 581
          if !desc.blank? && alttext.blank?
624 582
            alt = " title=\"#{desc}\" alt=\"#{desc}\""
......
647 605
      esc, all, page, title = $1, $2, $3, $5
648 606
      if esc.nil?
649 607
        if page =~ /^([^\:]+)\:(.*)$/
650
          link_project = Project.find_by_identifier($1) || Project.find_by_name($1)
651
          page = $2
652
          title ||= $1 if page.blank?
608
          identifier, page = $1, $2
609
          link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier)
610
          title ||= identifier if page.blank?
653 611
        end
654 612

  
655 613
        if link_project && link_project.wiki
......
814 772
                repository = project.repository
815 773
              end
816 774
              if prefix == 'commit'
817
                if repository && (changeset = Changeset.visible.find(:first, :conditions => ["repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%"]))
775
                if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first)
818 776
                  link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier},
819 777
                                               :class => 'changeset',
820
                                               :title => truncate_single_line(h(changeset.comments), :length => 100)
778
                                               :title => truncate_single_line(changeset.comments, :length => 100)
821 779
                end
822 780
              else
823 781
                if repository && User.current.allowed_to?(:browse_repository, project)
824
                  name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
782
                  name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$}
825 783
                  path, rev, anchor = $1, $3, $5
826 784
                  link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param,
827 785
                                                          :path => to_path_param(path),
......
835 793
          when 'attachment'
836 794
            attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
837 795
            if attachments && attachment = Attachment.latest_attach(attachments, name)
838
              link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
839
                                                     :class => 'attachment'
796
              link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment')
840 797
            end
841 798
          when 'project'
842
            if p = Project.visible.find(:first, :conditions => ["identifier = :s OR LOWER(name) = :s", {:s => name.downcase}])
799
            if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first
843 800
              link = link_to_project(p, {:only_path => only_path}, :class => 'project')
844 801
            end
845 802
          end
......
1092 1049
        (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) +
1093 1050
        (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe)
1094 1051
      ), :class => 'progress', :style => "width: #{width};").html_safe +
1095
      content_tag('p', legend, :class => 'pourcent').html_safe
1052
      content_tag('p', legend, :class => 'percent').html_safe
1096 1053
  end
1097 1054

  
1098 1055
  def checked_image(checked=true)
......
1136 1093
                   "var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " +
1137 1094
                     "showOn: 'button', buttonImageOnly: true, buttonImage: '" +
1138 1095
                     path_to_image('/images/calendar.png') +
1139
                     "', showButtonPanel: true};")
1096
                     "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};")
1140 1097
        jquery_locale = l('jquery.locale', :default => current_language.to_s)
1141 1098
        unless jquery_locale == 'en'
1142 1099
          tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js")
......
1240 1197

  
1241 1198
  def sanitize_anchor_name(anchor)
1242 1199
    if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java'
1243
      anchor.gsub(%r{[^\p{Word}\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
1200
      anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
1244 1201
    else
1245 1202
      # TODO: remove when ruby1.8 is no longer supported
1246 1203
      anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
......
1249 1206

  
1250 1207
  # Returns the javascript tags that are included in the html layout head
1251 1208
  def javascript_heads
1252
    tags = javascript_include_tag('jquery-1.7.2-ui-1.8.21-ujs-2.0.3', 'application')
1209
    tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application')
1253 1210
    unless User.current.pref.warn_on_leaving_unsaved == '0'
1254 1211
      tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
1255 1212
    end
app/helpers/attachments_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/auth_sources_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/boards_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/calendars_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/context_menus_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
36 36

  
37 37
  def bulk_update_custom_field_context_menu_link(field, text, value)
38 38
    context_menu_link h(text),
39
      {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back},
39
      bulk_update_issues_path(:ids => @issue_ids, :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back),
40 40
      :method => :post,
41 41
      :selected => (@issue && @issue.custom_field_value(field) == value)
42 42
  end
app/helpers/custom_fields_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
24 24
  end
25 25

  
26 26
  # Return custom field html tag corresponding to its format
27
  def custom_field_tag(name, custom_value)	
27
  def custom_field_tag(name, custom_value)
28 28
    custom_field = custom_value.custom_field
29 29
    field_name = "#{name}[custom_field_values][#{custom_field.id}]"
30 30
    field_name << "[]" if custom_field.multiple?
app/helpers/documents_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/enumerations_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/gantt_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
24 24
    when :in
25 25
      if gantt.zoom < 4
26 26
        link_to_content_update l(:text_zoom_in),
27
          params.merge(gantt.params.merge(:zoom => (gantt.zoom+1))),
27
          params.merge(gantt.params.merge(:zoom => (gantt.zoom + 1))),
28 28
          :class => 'icon icon-zoom-in'
29 29
      else
30
        content_tag('span', l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
30
        content_tag(:span, l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
31 31
      end
32 32

  
33 33
    when :out
34 34
      if gantt.zoom > 1
35 35
        link_to_content_update l(:text_zoom_out),
36
          params.merge(gantt.params.merge(:zoom => (gantt.zoom-1))),
36
          params.merge(gantt.params.merge(:zoom => (gantt.zoom - 1))),
37 37
          :class => 'icon icon-zoom-out'
38 38
      else
39
        content_tag('span', l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
39
        content_tag(:span, l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
40 40
      end
41 41
    end
42 42
  end
app/helpers/groups_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
24 24
            {:name => 'memberships', :partial => 'groups/memberships', :label => :label_project_plural}
25 25
            ]
26 26
  end
27

  
28
  def render_principals_for_new_group_users(group)
29
    scope = User.active.sorted.not_in_group(group).like(params[:q])
30
    principal_count = scope.count
31
    principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
32
    principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
33

  
34
    s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals')
35

  
36
    links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
37
      link_to text, autocomplete_for_user_group_path(group, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
38
    }
39

  
40
    s + content_tag('p', links, :class => 'pagination')
41
  end
27 42
end
app/helpers/issue_categories_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/issue_relations_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/issue_statuses_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/issues_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
184 184

  
185 185
  def sidebar_queries
186 186
    unless @sidebar_queries
187
      @sidebar_queries = Query.visible.all(
187
      @sidebar_queries = IssueQuery.visible.all(
188 188
        :order => "#{Query.table_name}.name ASC",
189 189
        # Project specific queries and global queries
190 190
        :conditions => (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id])
......
347 347

  
348 348
  # Find the name of an associated record stored in the field attribute
349 349
  def find_name_by_reflection(field, id)
350
    unless id.present?
351
      return nil
352
    end
350 353
    association = Issue.reflect_on_association(field.to_sym)
351 354
    if association
352 355
      record = association.class_name.constantize.find_by_id(id)
......
370 373
      end
371 374
    end
372 375
  end
373

  
374
  def issues_to_csv(issues, project, query, options={})
375
    decimal_separator = l(:general_csv_decimal_separator)
376
    encoding = l(:general_csv_encoding)
377
    columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns)
378
    if options[:description]
379
      if description = query.available_columns.detect {|q| q.name == :description}
380
        columns << description
381
      end
382
    end
383

  
384
    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
385
      # csv header fields
386
      csv << [ "#" ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
387

  
388
      # csv lines
389
      issues.each do |issue|
390
        col_values = columns.collect do |column|
391
          s = if column.is_a?(QueryCustomFieldColumn)
392
            cv = issue.custom_field_values.detect {|v| v.custom_field_id == column.custom_field.id}
393
            show_value(cv)
394
          else
395
            value = column.value(issue)
396
            if value.is_a?(Date)
397
              format_date(value)
398
            elsif value.is_a?(Time)
399
              format_time(value)
400
            elsif value.is_a?(Float)
401
              ("%.2f" % value).gsub('.', decimal_separator)
402
            else
403
              value
404
            end
405
          end
406
          s.to_s
407
        end
408
        csv << [ issue.id.to_s ] + col_values.collect {|c| Redmine::CodesetUtil.from_utf8(c.to_s, encoding) }
409
      end
410
    end
411
    export
412
  end
413 376
end
app/helpers/journals_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/mail_handler_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/members_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
18 18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 19

  
20 20
module MembersHelper
21
  def render_principals_for_new_members(project)
22
    scope = Principal.active.sorted.not_member_of(project).like(params[:q])
23
    principal_count = scope.count
24
    principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
25
    principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
26

  
27
    s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals')
28

  
29
    links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
30
      link_to text, autocomplete_project_memberships_path(project, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
31
    }
32

  
33
    s + content_tag('p', links, :class => 'pagination')
34
  end
21 35
end
app/helpers/messages_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/my_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
25 25
    user.projects.select { |p| p.visible? }.map { |p| p.members.map { |m| m.user_id } }.flatten.sort.uniq.reject { |i| user.id == i }
26 26
  end
27 27

  
28
  def calendar_items(startdt, enddt)
29
    Issue.visible.
30
      where(:project_id => User.current.projects.map(&:id)).
31
      where("(start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)", startdt, enddt, startdt, enddt).
32
      includes(:project, :tracker, :priority, :assigned_to).
33
      all
34
  end
35

  
36
  def documents_items
37
    Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).all
38
  end
39

  
40
  def issuesassignedtome_items
41
    Issue.visible.open.
42
      where(:assigned_to_id => ([User.current.id] + User.current.group_ids)).
43
      limit(10).
44
      includes(:status, :project, :tracker, :priority).
45
      order("#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC").
46
      all
47
  end
48

  
49
  def issuesreportedbyme_items
50
    Issue.visible.
51
      where(:author_id => User.current.id).
52
      limit(10).
53
      includes(:status, :project, :tracker).
54
      order("#{Issue.table_name}.updated_on DESC").
55
      all
56
  end
57

  
58
  def issueswatched_items
59
    Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).all
60
  end
61

  
62
  def news_items
63
    News.visible.
64
      where(:project_id => User.current.projects.map(&:id)).
65
      limit(10).
66
      includes(:project, :author).
67
      order("#{News.table_name}.created_on DESC").
68
      all
69
  end
70

  
71
  def timelog_items
72
    TimeEntry.
73
      where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, Date.today - 6, Date.today).
74
      includes(:activity, :project, {:issue => [:tracker, :status]}).
75
      order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC").
76
      all
77
  end
28 78
end
app/helpers/news_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/projects_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/queries_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
24 24

  
25 25
  def filters_options(query)
26 26
    options = [[]]
27
    sorted_options = query.available_filters.sort do |a, b|
28
      ord = 0
29
      if !(a[1][:order] == 20 && b[1][:order] == 20) 
30
        ord = a[1][:order] <=> b[1][:order]
31
      else
32
        cn = (CustomField::CUSTOM_FIELDS_NAMES.index(a[1][:field].class.name) <=>
33
                CustomField::CUSTOM_FIELDS_NAMES.index(b[1][:field].class.name))
34
        if cn != 0
35
          ord = cn
36
        else
37
          f = (a[1][:field] <=> b[1][:field])
38
          if f != 0
39
            ord = f
40
          else
41
            # assigned_to or author 
42
            ord = (a[0] <=> b[0])
43
          end
44
        end
45
      end
46
      ord
47
    end
48
    options += sorted_options.map do |field, field_options|
27
    options += query.available_filters.map do |field, field_options|
49 28
      [field_options[:name], field]
50 29
    end
51 30
  end
52 31

  
32
  def query_filters_hidden_tags(query)
33
    tags = ''.html_safe
34
    query.filters.each do |field, options|
35
      tags << hidden_field_tag("f[]", field, :id => nil)
36
      tags << hidden_field_tag("op[#{field}]", options[:operator], :id => nil)
37
      options[:values].each do |value|
38
        tags << hidden_field_tag("v[#{field}][]", value, :id => nil)
39
      end
40
    end
41
    tags
42
  end
43

  
44
  def query_columns_hidden_tags(query)
45
    tags = ''.html_safe
46
    query.columns.each do |column|
47
      tags << hidden_field_tag("c[]", column.name, :id => nil)
48
    end
49
    tags
50
  end
51

  
52
  def query_hidden_tags(query)
53
    query_filters_hidden_tags(query) + query_columns_hidden_tags(query)
54
  end
55

  
53 56
  def available_block_columns_tags(query)
54 57
    tags = ''.html_safe
55 58
    query.available_block_columns.each do |column|
......
58 61
    tags
59 62
  end
60 63

  
64
  def query_available_inline_columns_options(query)
65
    (query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
66
  end
67

  
68
  def query_selected_inline_columns_options(query)
69
    (query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
70
  end
71

  
72
  def render_query_columns_selection(query, options={})
73
    tag_name = (options[:name] || 'c') + '[]'
74
    render :partial => 'queries/columns', :locals => {:query => query, :tag_name => tag_name}
75
  end
76

  
61 77
  def column_header(column)
62 78
    column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
63 79
                                                        :default_order => column.default_order) :
......
88 104
    when 'Date'
89 105
      format_date(value)
90 106
    when 'Fixnum'
91
      if column.name == :done_ratio
107
      if column.name == :id
108
        link_to value, issue_path(issue)
109
      elsif column.name == :done_ratio
92 110
        progress_bar(value, :width => '80px')
93 111
      else
94 112
        value.to_s
......
106 124
    when 'FalseClass'
107 125
      l(:general_text_No)
108 126
    when 'Issue'
109
      link_to_issue(value, :subject => false)
127
      value.visible? ? link_to_issue(value) : "##{value.id}"
110 128
    when 'IssueRelation'
111 129
      other = value.other_issue(issue)
112 130
      content_tag('span',
......
117 135
    end
118 136
  end
119 137

  
138
  def csv_content(column, issue)
139
    value = column.value(issue)
140
    if value.is_a?(Array)
141
      value.collect {|v| csv_value(column, issue, v)}.compact.join(', ')
142
    else
143
      csv_value(column, issue, value)
144
    end
145
  end
146

  
147
  def csv_value(column, issue, value)
148
    case value.class.name
149
    when 'Time'
150
      format_time(value)
151
    when 'Date'
152
      format_date(value)
153
    when 'Float'
154
      sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
155
    when 'IssueRelation'
156
      other = value.other_issue(issue)
157
      l(value.label_for(issue)) + " ##{other.id}"
158
    else
159
      value.to_s
160
    end
161
  end
162

  
163
  def query_to_csv(items, query, options={})
164
    encoding = l(:general_csv_encoding)
165
    columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns)
166
    query.available_block_columns.each do |column|
167
      if options[column.name].present?
168
        columns << column
169
      end
170
    end
171

  
172
    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
173
      # csv header fields
174
      csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
175
      # csv lines
176
      items.each do |item|
177
        csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, item), encoding) }
178
      end
179
    end
180
    export
181
  end
182

  
120 183
  # Retrieve query from session or build a new query
121 184
  def retrieve_query
122 185
    if !params[:query_id].blank?
123 186
      cond = "project_id IS NULL"
124 187
      cond << " OR project_id = #{@project.id}" if @project
125
      @query = Query.find(params[:query_id], :conditions => cond)
188
      @query = IssueQuery.find(params[:query_id], :conditions => cond)
126 189
      raise ::Unauthorized unless @query.visible?
127 190
      @query.project = @project
128 191
      session[:query] = {:id => @query.id, :project_id => @query.project_id}
129 192
      sort_clear
130 193
    elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
131 194
      # Give it a name, required to be valid
132
      @query = Query.new(:name => "_")
195
      @query = IssueQuery.new(:name => "_")
133 196
      @query.project = @project
134
      build_query_from_params
197
      @query.build_from_params(params)
135 198
      session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
136 199
    else
137 200
      # retrieve from session
138
      @query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
139
      @query ||= Query.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
201
      @query = IssueQuery.find_by_id(session[:query][:id]) if session[:query][:id]
202
      @query ||= IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
140 203
      @query.project = @project
141 204
    end
142 205
  end
......
144 207
  def retrieve_query_from_session
145 208
    if session[:query]
146 209
      if session[:query][:id]
147
        @query = Query.find_by_id(session[:query][:id])
210
        @query = IssueQuery.find_by_id(session[:query][:id])
148 211
        return unless @query
149 212
      else
150
        @query = Query.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
213
        @query = IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
151 214
      end
152 215
      if session[:query].has_key?(:project_id)
153 216
        @query.project_id = session[:query][:project_id]
......
157 220
      @query
158 221
    end
159 222
  end
160

  
161
  def build_query_from_params
162
    if params[:fields] || params[:f]
163
      @query.filters = {}
164
      @query.add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
165
    else
166
      @query.available_filters.keys.each do |field|
167
        @query.add_short_filter(field, params[field]) if params[field]
168
      end
169
    end
170
    @query.group_by = params[:group_by] || (params[:query] && params[:query][:group_by])
171
    @query.column_names = params[:c] || (params[:query] && params[:query][:column_names])
172
  end
173 223
end
app/helpers/reports_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
35 35
    a = aggregate data, criteria
36 36
    a > 0 ? link_to(h(a), *args) : '-'
37 37
  end
38

  
39
  def aggregate_path(project, field, row, options={})
40
    parameters = {:set_filter => 1, :subproject_id => '!*', field => row.id}.merge(options)
41
    project_issues_path(row.is_a?(Project) ? row : project, parameters)
42
  end
38 43
end
app/helpers/repositories_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
43 43
  end
44 44

  
45 45
  def render_changeset_changes
46
    changes = @changeset.filechanges.find(:all, :limit => 1000, :order => 'path').collect do |change|
46
    changes = @changeset.filechanges.limit(1000).reorder('path').all.collect do |change|
47 47
      case change.action
48 48
      when 'A'
49 49
        # Detects moved/copied files
app/helpers/roles_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/routes_helper.rb
1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
module RoutesHelper
21

  
22
  # Returns the path to project issues or to the cross-project
23
  # issue list if project is nil
24
  def _project_issues_path(project, *args)
25
    if project
26
      project_issues_path(project, *args)
27
    else
28
      issues_path(*args)
29
    end
30
  end
31

  
32
  def _project_calendar_path(project, *args)
33
    project ? project_calendar_path(project, *args) : issues_calendar_path(*args)
34
  end
35

  
36
  def _project_gantt_path(project, *args)
37
    project ? project_gantt_path(project, *args) : issues_gantt_path(*args)
38
  end
39
end
app/helpers/search_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/settings_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
53 53
          check_box_tag(
54 54
             "settings[#{setting}][]",
55 55
             value,
56
             Setting.send(setting).include?(value),
56
             setting_values.include?(value),
57 57
             :id => nil
58 58
           ) + text.to_s,
59 59
          :class => (options[:inline] ? 'inline' : 'block')
app/helpers/sort_helper.rb
80 80
      @criteria.collect {|k,o| k + (o ? '' : ':desc')}.join(',')
81 81
    end
82 82

  
83
    # Returns an array of SQL fragments used to sort the list
83 84
    def to_sql
84 85
      sql = @criteria.collect do |k,o|
85 86
        if s = @available_criteria[k]
86
          (o ? s.to_a : s.to_a.collect {|c| append_desc(c)}).join(', ')
87
          (o ? s.to_a : s.to_a.collect {|c| append_desc(c)})
87 88
        end
88
      end.compact.join(', ')
89
      end.flatten.compact
89 90
      sql.blank? ? nil : sql
90 91
    end
91 92

  
app/helpers/timelog_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
56 56
  end
57 57

  
58 58
  def select_hours(data, criteria, value)
59
  	if value.to_s.empty?
60
  		data.select {|row| row[criteria].blank? }
59
    if value.to_s.empty?
60
      data.select {|row| row[criteria].blank? }
61 61
    else
62
    	data.select {|row| row[criteria].to_s == value.to_s}
62
      data.select {|row| row[criteria].to_s == value.to_s}
63 63
    end
64 64
  end
65 65

  
......
86 86
                        value)
87 87
  end
88 88

  
89
  def entries_to_csv(entries)
90
    decimal_separator = l(:general_csv_decimal_separator)
91
    custom_fields = TimeEntryCustomField.find(:all)
92
    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
93
      # csv header fields
94
      headers = [l(:field_spent_on),
95
                 l(:field_user),
96
                 l(:field_activity),
97
                 l(:field_project),
98
                 l(:field_issue),
99
                 l(:field_tracker),
100
                 l(:field_subject),
101
                 l(:field_hours),
102
                 l(:field_comments)
103
                 ]
104
      # Export custom fields
105
      headers += custom_fields.collect(&:name)
106

  
107
      csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
108
                                     c.to_s,
109
                                     l(:general_csv_encoding) )  }
110
      # csv lines
111
      entries.each do |entry|
112
        fields = [format_date(entry.spent_on),
113
                  entry.user,
114
                  entry.activity,
115
                  entry.project,
116
                  (entry.issue ? entry.issue.id : nil),
117
                  (entry.issue ? entry.issue.tracker : nil),
118
                  (entry.issue ? entry.issue.subject : nil),
119
                  entry.hours.to_s.gsub('.', decimal_separator),
120
                  entry.comments
121
                  ]
122
        fields += custom_fields.collect {|f| show_value(entry.custom_field_values.detect {|v| v.custom_field_id == f.id}) }
123

  
124
        csv << fields.collect {|c| Redmine::CodesetUtil.from_utf8(
125
                                     c.to_s,
126
                                     l(:general_csv_encoding) )  }
127
      end
128
    end
129
    export
130
  end
131

  
132 89
  def format_criteria_value(criteria_options, value)
133 90
    if value.blank?
134 91
      "[#{l(:label_none)}]"
......
150 107
      # Column headers
151 108
      headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
152 109
      headers += report.periods
153
      headers << l(:label_total)
110
      headers << l(:label_total_time)
154 111
      csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
155 112
                                    c.to_s,
156 113
                                    l(:general_csv_encoding) ) }
157 114
      # Content
158 115
      report_criteria_to_csv(csv, report.available_criteria, report.columns, report.criteria, report.periods, report.hours)
159 116
      # Total row
160
      str_total = Redmine::CodesetUtil.from_utf8(l(:label_total), l(:general_csv_encoding))
117
      str_total = Redmine::CodesetUtil.from_utf8(l(:label_total_time), l(:general_csv_encoding))
161 118
      row = [ str_total ] + [''] * (report.criteria.size - 1)
162 119
      total = 0
163 120
      report.periods.each do |period|
app/helpers/trackers_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/users_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/versions_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/watchers_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
......
20 20
module WatchersHelper
21 21

  
22 22
  def watcher_tag(object, user, options={})
23
    content_tag("span", watcher_link(object, user), :class => watcher_css(object))
23
    ActiveSupport::Deprecation.warn "#watcher_tag is deprecated and will be removed in Redmine 3.0. Use #watcher_link instead."
24
    watcher_link(object, user)
24 25
  end
25 26

  
26
  def watcher_link(object, user)
27
    return '' unless user && user.logged? && object.respond_to?('watched_by?')
28
    watched = object.watched_by?(user)
29
    url = {:controller => 'watchers',
30
           :action => (watched ? 'unwatch' : 'watch'),
31
           :object_type => object.class.to_s.underscore,
32
           :object_id => object.id}
33
    link_to((watched ? l(:button_unwatch) : l(:button_watch)), url,
34
            :remote => true, :method => 'post', :class => (watched ? 'icon icon-fav' : 'icon icon-fav-off'))
27
  def watcher_link(objects, user)
28
    return '' unless user && user.logged?
29
    objects = Array.wrap(objects)
35 30

  
31
    watched = objects.any? {|object| object.watched_by?(user)}
32
    css = [watcher_css(objects), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ')
33
    text = watched ? l(:button_unwatch) : l(:button_watch)
34
    url = watch_path(
35
      :object_type => objects.first.class.to_s.underscore,
36
      :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort)
37
    )
38
    method = watched ? 'delete' : 'post'
39

  
40
    link_to text, url, :remote => true, :method => method, :class => css
36 41
  end
37 42

  
38 43
  # Returns the css class used to identify watch links for a given +object+
39
  def watcher_css(object)
40
    "#{object.class.to_s.underscore}-#{object.id}-watcher"
44
  def watcher_css(objects)
45
    objects = Array.wrap(objects)
46
    id = (objects.size == 1 ? objects.first.id : 'bulk')
47
    "#{objects.first.class.to_s.underscore}-#{id}-watcher"
41 48
  end
42 49

  
43 50
  # Returns a comma separated list of users watching the given object
......
56 63
               :user_id => user}
57 64
        s << ' '
58 65
        s << link_to(image_tag('delete.png'), url,
59
                     :remote => true, :method => 'post', :style => "vertical-align: middle", :class => "delete")
66
                     :remote => true, :method => 'delete', :class => "delete")
60 67
      end
61
      content << content_tag('li', s)
68
      content << content_tag('li', s, :class => "user-#{user.id}")
62 69
    end
63
    content.present? ? content_tag('ul', content) : content
70
    content.present? ? content_tag('ul', content, :class => 'watchers') : content
64 71
  end
65 72

  
66 73
  def watchers_checkboxes(object, users, checked=nil)
app/helpers/welcome_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/wiki_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License
app/helpers/workflows_helper.rb
1 1
# encoding: utf-8
2 2
#
3 3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5 5
#
6 6
# This program is free software; you can redistribute it and/or
7 7
# modify it under the terms of the GNU General Public License

Also available in: Unified diff