Revision 912:5e80956cc792 app/helpers
| app/helpers/account_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/admin_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 | 19 |
|
| 18 | 20 |
module AdminHelper |
| 19 | 21 |
def project_status_options_for_select(selected) |
| 20 |
options_for_select([[l(:label_all), ''],
|
|
| 22 |
options_for_select([[l(:label_all), ''], |
|
| 21 | 23 |
[l(:status_active), 1]], selected) |
| 22 | 24 |
end |
| 23 | 25 |
end |
| app/helpers/application_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 | 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
| 3 | 5 |
# |
| ... | ... | |
| 80 | 82 |
subject = truncate(subject, :length => options[:truncate]) |
| 81 | 83 |
end |
| 82 | 84 |
end |
| 83 |
s = link_to "#{issue.tracker} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue},
|
|
| 85 |
s = link_to "#{h(issue.tracker)} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue},
|
|
| 84 | 86 |
:class => issue.css_classes, |
| 85 | 87 |
:title => title |
| 86 | 88 |
s << ": #{h subject}" if subject
|
| ... | ... | |
| 95 | 97 |
def link_to_attachment(attachment, options={})
|
| 96 | 98 |
text = options.delete(:text) || attachment.filename |
| 97 | 99 |
action = options.delete(:download) ? 'download' : 'show' |
| 98 |
|
|
| 99 |
link_to(h(text), {:controller => 'attachments', :action => action, :id => attachment, :filename => attachment.filename }, options)
|
|
| 100 |
link_to(h(text), |
|
| 101 |
{:controller => 'attachments', :action => action,
|
|
| 102 |
:id => attachment, :filename => attachment.filename }, |
|
| 103 |
options) |
|
| 100 | 104 |
end |
| 101 | 105 |
|
| 102 | 106 |
# Generates a link to a SCM revision |
| ... | ... | |
| 106 | 110 |
text = options.delete(:text) || format_revision(revision) |
| 107 | 111 |
rev = revision.respond_to?(:identifier) ? revision.identifier : revision |
| 108 | 112 |
|
| 109 |
link_to(text, {:controller => 'repositories', :action => 'revision', :id => project, :rev => rev},
|
|
| 113 |
link_to(h(text), {:controller => 'repositories', :action => 'revision', :id => project, :rev => rev},
|
|
| 110 | 114 |
:title => l(:label_revision_id, format_revision(revision))) |
| 111 | 115 |
end |
| 112 | 116 |
|
| ... | ... | |
| 200 | 204 |
end |
| 201 | 205 |
content << "</ul>\n" |
| 202 | 206 |
end |
| 203 |
content |
|
| 207 |
content.html_safe
|
|
| 204 | 208 |
end |
| 205 | 209 |
|
| 206 | 210 |
# Renders flash messages |
| ... | ... | |
| 209 | 213 |
flash.each do |k,v| |
| 210 | 214 |
s << content_tag('div', v, :class => "flash #{k}")
|
| 211 | 215 |
end |
| 212 |
s |
|
| 216 |
s.html_safe
|
|
| 213 | 217 |
end |
| 214 | 218 |
|
| 215 | 219 |
# Renders tabs and their content |
| ... | ... | |
| 233 | 237 |
{ :value => url_for(:controller => 'projects', :action => 'show', :id => p, :jump => current_menu_item) }
|
| 234 | 238 |
end |
| 235 | 239 |
s << '</select>' |
| 236 |
s |
|
| 240 |
s.html_safe
|
|
| 237 | 241 |
end |
| 238 | 242 |
end |
| 239 | 243 |
|
| ... | ... | |
| 250 | 254 |
tag_options.merge!(yield(project)) if block_given? |
| 251 | 255 |
s << content_tag('option', name_prefix + h(project), tag_options)
|
| 252 | 256 |
end |
| 253 |
s |
|
| 257 |
s.html_safe
|
|
| 254 | 258 |
end |
| 255 | 259 |
|
| 256 | 260 |
# Yields the given block for each project with its level in the tree |
| ... | ... | |
| 281 | 285 |
end |
| 282 | 286 |
s << ("</li></ul>\n" * ancestors.size)
|
| 283 | 287 |
end |
| 284 |
s |
|
| 288 |
s.html_safe
|
|
| 285 | 289 |
end |
| 286 | 290 |
|
| 287 | 291 |
def principals_check_box_tags(name, principals) |
| ... | ... | |
| 289 | 293 |
principals.sort.each do |principal| |
| 290 | 294 |
s << "<label>#{ check_box_tag name, principal.id, false } #{link_to_user principal}</label>\n"
|
| 291 | 295 |
end |
| 296 |
s.html_safe |
|
| 297 |
end |
|
| 298 |
|
|
| 299 |
# Returns a string for users/groups option tags |
|
| 300 |
def principals_options_for_select(collection, selected=nil) |
|
| 301 |
s = '' |
|
| 302 |
groups = '' |
|
| 303 |
collection.sort.each do |element| |
|
| 304 |
selected_attribute = ' selected="selected"' if option_value_selected?(element, selected) |
|
| 305 |
(element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.name}</option>)
|
|
| 306 |
end |
|
| 307 |
unless groups.empty? |
|
| 308 |
s << %(<optgroup label="#{h(l(:label_group_plural))}">#{groups}</optgroup>)
|
|
| 309 |
end |
|
| 292 | 310 |
s |
| 293 | 311 |
end |
| 294 | 312 |
|
| ... | ... | |
| 308 | 326 |
end |
| 309 | 327 |
|
| 310 | 328 |
def html_hours(text) |
| 311 |
text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
|
|
| 329 |
text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>').html_safe
|
|
| 312 | 330 |
end |
| 313 | 331 |
|
| 314 | 332 |
def authoring(created, author, options={})
|
| 315 |
l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)) |
|
| 333 |
l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe
|
|
| 316 | 334 |
end |
| 317 | 335 |
|
| 318 | 336 |
def time_tag(time) |
| ... | ... | |
| 339 | 357 |
|
| 340 | 358 |
html = '' |
| 341 | 359 |
if paginator.current.previous |
| 342 |
html << link_to_content_update('« ' + l(:label_previous), url_param.merge(page_param => paginator.current.previous)) + ' '
|
|
| 360 |
# \xc2\xab(utf-8) = « |
|
| 361 |
html << link_to_content_update( |
|
| 362 |
"\xc2\xab " + l(:label_previous), |
|
| 363 |
url_param.merge(page_param => paginator.current.previous)) + ' ' |
|
| 343 | 364 |
end |
| 344 | 365 |
|
| 345 | 366 |
html << (pagination_links_each(paginator, options) do |n| |
| ... | ... | |
| 347 | 368 |
end || '') |
| 348 | 369 |
|
| 349 | 370 |
if paginator.current.next |
| 350 |
html << ' ' + link_to_content_update((l(:label_next) + ' »'), url_param.merge(page_param => paginator.current.next)) |
|
| 371 |
# \xc2\xbb(utf-8) = » |
|
| 372 |
html << ' ' + link_to_content_update( |
|
| 373 |
(l(:label_next) + " \xc2\xbb"), |
|
| 374 |
url_param.merge(page_param => paginator.current.next)) |
|
| 351 | 375 |
end |
| 352 | 376 |
|
| 353 | 377 |
unless count.nil? |
| ... | ... | |
| 357 | 381 |
end |
| 358 | 382 |
end |
| 359 | 383 |
|
| 360 |
html |
|
| 384 |
html.html_safe
|
|
| 361 | 385 |
end |
| 362 | 386 |
|
| 363 | 387 |
def per_page_links(selected=nil) |
| ... | ... | |
| 367 | 391 |
links.size > 1 ? l(:label_display_per_page, links.join(', ')) : nil
|
| 368 | 392 |
end |
| 369 | 393 |
|
| 370 |
def reorder_links(name, url) |
|
| 371 |
link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), url.merge({"#{name}[move_to]" => 'highest'}), :method => :post, :title => l(:label_sort_highest)) +
|
|
| 372 |
link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), url.merge({"#{name}[move_to]" => 'higher'}), :method => :post, :title => l(:label_sort_higher)) +
|
|
| 373 |
link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), url.merge({"#{name}[move_to]" => 'lower'}), :method => :post, :title => l(:label_sort_lower)) +
|
|
| 374 |
link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), url.merge({"#{name}[move_to]" => 'lowest'}), :method => :post, :title => l(:label_sort_lowest))
|
|
| 394 |
def reorder_links(name, url, method = :post) |
|
| 395 |
link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
|
|
| 396 |
url.merge({"#{name}[move_to]" => 'highest'}),
|
|
| 397 |
:method => method, :title => l(:label_sort_highest)) + |
|
| 398 |
link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)),
|
|
| 399 |
url.merge({"#{name}[move_to]" => 'higher'}),
|
|
| 400 |
:method => method, :title => l(:label_sort_higher)) + |
|
| 401 |
link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)),
|
|
| 402 |
url.merge({"#{name}[move_to]" => 'lower'}),
|
|
| 403 |
:method => method, :title => l(:label_sort_lower)) + |
|
| 404 |
link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)),
|
|
| 405 |
url.merge({"#{name}[move_to]" => 'lowest'}),
|
|
| 406 |
:method => method, :title => l(:label_sort_lowest)) |
|
| 375 | 407 |
end |
| 376 | 408 |
|
| 377 | 409 |
def breadcrumb(*args) |
| 378 | 410 |
elements = args.flatten |
| 379 |
elements.any? ? content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb') : nil
|
|
| 411 |
elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'breadcrumb') : nil
|
|
| 380 | 412 |
end |
| 381 | 413 |
|
| 382 | 414 |
def other_formats_links(&block) |
| 383 |
concat('<p class="other-formats">' + l(:label_export_to))
|
|
| 415 |
concat('<p class="other-formats">'.html_safe + l(:label_export_to))
|
|
| 384 | 416 |
yield Redmine::Views::OtherFormatsBuilder.new(self) |
| 385 |
concat('</p>')
|
|
| 417 |
concat('</p>'.html_safe)
|
|
| 386 | 418 |
end |
| 387 | 419 |
|
| 388 | 420 |
def page_header_title |
| ... | ... | |
| 414 | 446 |
|
| 415 | 447 |
def html_title(*args) |
| 416 | 448 |
if args.empty? |
| 417 |
title = [] |
|
| 449 |
title = @html_title || []
|
|
| 418 | 450 |
title << @project.name if @project |
| 419 |
title += @html_title if @html_title |
|
| 420 |
title << Setting.app_title |
|
| 451 |
title << Setting.app_title unless Setting.app_title == title.last |
|
| 421 | 452 |
title.select {|t| !t.blank? }.join(' - ')
|
| 422 | 453 |
else |
| 423 | 454 |
@html_title ||= [] |
| ... | ... | |
| 463 | 494 |
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) |
| 464 | 495 |
only_path = options.delete(:only_path) == false ? false : true |
| 465 | 496 |
|
| 466 |
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) { |macro, args| exec_macro(macro, obj, args) }
|
|
| 497 |
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) |
|
| 467 | 498 |
|
| 468 | 499 |
@parsed_headings = [] |
| 500 |
@current_section = 0 if options[:edit_section_links] |
|
| 469 | 501 |
text = parse_non_pre_blocks(text) do |text| |
| 470 |
[:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_headings].each do |method_name|
|
|
| 502 |
[:parse_sections, :parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_macros, :parse_headings].each do |method_name|
|
|
| 471 | 503 |
send method_name, text, project, obj, attr, only_path, options |
| 472 | 504 |
end |
| 473 | 505 |
end |
| ... | ... | |
| 505 | 537 |
while tag = tags.pop |
| 506 | 538 |
parsed << "</#{tag}>"
|
| 507 | 539 |
end |
| 508 |
parsed |
|
| 540 |
parsed.html_safe
|
|
| 509 | 541 |
end |
| 510 | 542 |
|
| 511 | 543 |
def parse_inline_attachments(text, project, obj, attr, only_path, options) |
| 512 | 544 |
# when using an image link, try to use an attachment, if possible |
| 513 | 545 |
if options[:attachments] || (obj && obj.respond_to?(:attachments)) |
| 514 |
attachments = nil
|
|
| 515 |
text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m| |
|
| 546 |
attachments = options[:attachments] || obj.attachments
|
|
| 547 |
text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m|
|
|
| 516 | 548 |
filename, ext, alt, alttext = $1.downcase, $2, $3, $4 |
| 517 |
attachments ||= (options[:attachments] || obj.attachments).sort_by(&:created_on).reverse |
|
| 518 | 549 |
# search for the picture in attachments |
| 519 |
if found = attachments.detect { |att| att.filename.downcase == filename }
|
|
| 520 |
image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found |
|
| 550 |
if found = Attachment.latest_attach(attachments, filename) |
|
| 551 |
image_url = url_for :only_path => only_path, :controller => 'attachments', |
|
| 552 |
:action => 'download', :id => found |
|
| 521 | 553 |
desc = found.description.to_s.gsub('"', '')
|
| 522 | 554 |
if !desc.blank? && alttext.blank? |
| 523 | 555 |
alt = " title=\"#{desc}\" alt=\"#{desc}\""
|
| 524 | 556 |
end |
| 525 |
"src=\"#{image_url}\"#{alt}"
|
|
| 557 |
"src=\"#{image_url}\"#{alt}".html_safe
|
|
| 526 | 558 |
else |
| 527 |
m |
|
| 559 |
m.html_safe
|
|
| 528 | 560 |
end |
| 529 | 561 |
end |
| 530 | 562 |
end |
| ... | ... | |
| 557 | 589 |
if page =~ /^(.+?)\#(.+)$/ |
| 558 | 590 |
page, anchor = $1, $2 |
| 559 | 591 |
end |
| 592 |
anchor = sanitize_anchor_name(anchor) if anchor.present? |
|
| 560 | 593 |
# check if page exists |
| 561 | 594 |
wiki_page = link_project.wiki.find_page(page) |
| 562 |
url = case options[:wiki_links] |
|
| 563 |
when :local; "#{title}.html"
|
|
| 564 |
when :anchor; "##{title}" # used for single-file wiki export
|
|
| 595 |
url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page |
|
| 596 |
"##{anchor}"
|
|
| 597 |
else |
|
| 598 |
case options[:wiki_links] |
|
| 599 |
when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '')
|
|
| 600 |
when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export
|
|
| 565 | 601 |
else |
| 566 | 602 |
wiki_page_id = page.present? ? Wiki.titleize(page) : nil |
| 567 | 603 |
url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project, :id => wiki_page_id, :anchor => anchor) |
| 568 | 604 |
end |
| 569 |
link_to((title || page), url, :class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
|
| 605 |
end |
|
| 606 |
link_to(title.present? ? title.html_safe : h(page), url, :class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
|
| 570 | 607 |
else |
| 571 | 608 |
# project or wiki doesn't exist |
| 572 |
all |
|
| 609 |
all.html_safe
|
|
| 573 | 610 |
end |
| 574 | 611 |
else |
| 575 |
all |
|
| 612 |
all.html_safe
|
|
| 576 | 613 |
end |
| 577 | 614 |
end |
| 578 | 615 |
end |
| ... | ... | |
| 610 | 647 |
# identifier:version:1.0.0 |
| 611 | 648 |
# identifier:source:some/file |
| 612 | 649 |
def parse_redmine_links(text, project, obj, attr, only_path, options) |
| 613 |
text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-]+):)?(attachment|document|version|commit|source|export|message|project)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|,|\s|\]|<|$)}) do |m|
|
|
| 650 |
text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-]+):)?(attachment|document|version|forum|news|commit|source|export|message|project)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|,|\s|\]|<|$)}) do |m|
|
|
| 614 | 651 |
leading, esc, project_prefix, project_identifier, prefix, sep, identifier = $1, $2, $3, $4, $5, $7 || $9, $8 || $10 |
| 615 | 652 |
link = nil |
| 616 | 653 |
if project_identifier |
| ... | ... | |
| 620 | 657 |
if prefix.nil? && sep == 'r' |
| 621 | 658 |
# project.changesets.visible raises an SQL error because of a double join on repositories |
| 622 | 659 |
if project && project.repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(project.repository.id, identifier)) |
| 623 |
link = link_to("#{project_prefix}r#{identifier}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
|
|
| 660 |
link = link_to(h("#{project_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
|
|
| 624 | 661 |
:class => 'changeset', |
| 625 | 662 |
:title => truncate_single_line(changeset.comments, :length => 100)) |
| 626 | 663 |
end |
| ... | ... | |
| 647 | 684 |
if message = Message.visible.find_by_id(oid, :include => :parent) |
| 648 | 685 |
link = link_to_message(message, {:only_path => only_path}, :class => 'message')
|
| 649 | 686 |
end |
| 687 |
when 'forum' |
|
| 688 |
if board = Board.visible.find_by_id(oid) |
|
| 689 |
link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
|
|
| 690 |
:class => 'board' |
|
| 691 |
end |
|
| 692 |
when 'news' |
|
| 693 |
if news = News.visible.find_by_id(oid) |
|
| 694 |
link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
|
|
| 695 |
:class => 'news' |
|
| 696 |
end |
|
| 650 | 697 |
when 'project' |
| 651 | 698 |
if p = Project.visible.find_by_id(oid) |
| 652 | 699 |
link = link_to_project(p, {:only_path => only_path}, :class => 'project')
|
| ... | ... | |
| 666 | 713 |
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
|
| 667 | 714 |
:class => 'version' |
| 668 | 715 |
end |
| 716 |
when 'forum' |
|
| 717 |
if project && board = project.boards.visible.find_by_name(name) |
|
| 718 |
link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
|
|
| 719 |
:class => 'board' |
|
| 720 |
end |
|
| 721 |
when 'news' |
|
| 722 |
if project && news = project.news.visible.find_by_title(name) |
|
| 723 |
link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
|
|
| 724 |
:class => 'news' |
|
| 725 |
end |
|
| 669 | 726 |
when 'commit' |
| 670 | 727 |
if project && project.repository && (changeset = Changeset.visible.find(:first, :conditions => ["repository_id = ? AND scmid LIKE ?", project.repository.id, "#{name}%"]))
|
| 671 | 728 |
link = link_to h("#{project_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.identifier},
|
| 672 | 729 |
:class => 'changeset', |
| 673 |
:title => truncate_single_line(changeset.comments, :length => 100)
|
|
| 730 |
:title => truncate_single_line(h(changeset.comments), :length => 100)
|
|
| 674 | 731 |
end |
| 675 | 732 |
when 'source', 'export' |
| 676 | 733 |
if project && project.repository && User.current.allowed_to?(:browse_repository, project) |
| ... | ... | |
| 696 | 753 |
end |
| 697 | 754 |
end |
| 698 | 755 |
end |
| 699 |
leading + (link || "#{project_prefix}#{prefix}#{sep}#{identifier}")
|
|
| 756 |
(leading + (link || "#{project_prefix}#{prefix}#{sep}#{identifier}")).html_safe
|
|
| 700 | 757 |
end |
| 701 | 758 |
end |
| 702 | 759 |
|
| 703 |
HEADING_RE = /<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>/i unless const_defined?(:HEADING_RE) |
|
| 760 |
HEADING_RE = /(<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>)/i unless const_defined?(:HEADING_RE) |
|
| 761 |
|
|
| 762 |
def parse_sections(text, project, obj, attr, only_path, options) |
|
| 763 |
return unless options[:edit_section_links] |
|
| 764 |
text.gsub!(HEADING_RE) do |
|
| 765 |
@current_section += 1 |
|
| 766 |
if @current_section > 1 |
|
| 767 |
content_tag('div',
|
|
| 768 |
link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)),
|
|
| 769 |
:class => 'contextual', |
|
| 770 |
:title => l(:button_edit_section)) + $1 |
|
| 771 |
else |
|
| 772 |
$1 |
|
| 773 |
end |
|
| 774 |
end |
|
| 775 |
end |
|
| 704 | 776 |
|
| 705 | 777 |
# Headings and TOC |
| 706 | 778 |
# Adds ids and links to headings unless options[:headings] is set to false |
| ... | ... | |
| 708 | 780 |
return if options[:headings] == false |
| 709 | 781 |
|
| 710 | 782 |
text.gsub!(HEADING_RE) do |
| 711 |
level, attrs, content = $1.to_i, $2, $3
|
|
| 783 |
level, attrs, content = $2.to_i, $3, $4
|
|
| 712 | 784 |
item = strip_tags(content).strip |
| 713 |
anchor = item.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
|
|
| 785 |
anchor = sanitize_anchor_name(item) |
|
| 786 |
# used for single-file wiki export |
|
| 787 |
anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version))
|
|
| 714 | 788 |
@parsed_headings << [level, anchor, item] |
| 715 | 789 |
"<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">¶</a></h#{level}>"
|
| 716 | 790 |
end |
| 717 | 791 |
end |
| 718 | 792 |
|
| 793 |
MACROS_RE = / |
|
| 794 |
(!)? # escaping |
|
| 795 |
( |
|
| 796 |
\{\{ # opening tag
|
|
| 797 |
([\w]+) # macro name |
|
| 798 |
(\(([^\}]*)\))? # optional arguments |
|
| 799 |
\}\} # closing tag |
|
| 800 |
) |
|
| 801 |
/x unless const_defined?(:MACROS_RE) |
|
| 802 |
|
|
| 803 |
# Macros substitution |
|
| 804 |
def parse_macros(text, project, obj, attr, only_path, options) |
|
| 805 |
text.gsub!(MACROS_RE) do |
|
| 806 |
esc, all, macro = $1, $2, $3.downcase |
|
| 807 |
args = ($5 || '').split(',').each(&:strip)
|
|
| 808 |
if esc.nil? |
|
| 809 |
begin |
|
| 810 |
exec_macro(macro, obj, args) |
|
| 811 |
rescue => e |
|
| 812 |
"<div class=\"flash error\">Error executing the <strong>#{macro}</strong> macro (#{e})</div>"
|
|
| 813 |
end || all |
|
| 814 |
else |
|
| 815 |
all |
|
| 816 |
end |
|
| 817 |
end |
|
| 818 |
end |
|
| 819 |
|
|
| 719 | 820 |
TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
|
| 720 | 821 |
|
| 721 | 822 |
# Renders the TOC with given headings |
| ... | ... | |
| 754 | 855 |
text.to_s. |
| 755 | 856 |
gsub(/\r\n?/, "\n"). # \r\n and \r -> \n |
| 756 | 857 |
gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br |
| 757 |
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br |
|
| 858 |
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 1 newline -> br |
|
| 859 |
html_safe |
|
| 758 | 860 |
end |
| 759 | 861 |
|
| 760 | 862 |
def lang_options_for_select(blank=true) |
| ... | ... | |
| 767 | 869 |
content_tag("label", label_text)
|
| 768 | 870 |
end |
| 769 | 871 |
|
| 770 |
def labelled_tabular_form_for(name, object, options, &proc) |
|
| 872 |
def labelled_tabular_form_for(*args, &proc) |
|
| 873 |
args << {} unless args.last.is_a?(Hash)
|
|
| 874 |
options = args.last |
|
| 771 | 875 |
options[:html] ||= {}
|
| 772 | 876 |
options[:html][:class] = 'tabular' unless options[:html].has_key?(:class) |
| 773 |
form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
|
|
| 877 |
options.merge!({:builder => TabularFormBuilder})
|
|
| 878 |
form_for(*args, &proc) |
|
| 879 |
end |
|
| 880 |
|
|
| 881 |
def labelled_form_for(*args, &proc) |
|
| 882 |
args << {} unless args.last.is_a?(Hash)
|
|
| 883 |
options = args.last |
|
| 884 |
options.merge!({:builder => TabularFormBuilder})
|
|
| 885 |
form_for(*args, &proc) |
|
| 774 | 886 |
end |
| 775 | 887 |
|
| 776 | 888 |
def back_url_hidden_field_tag |
| ... | ... | |
| 781 | 893 |
|
| 782 | 894 |
def check_all_links(form_name) |
| 783 | 895 |
link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
|
| 784 |
" | " + |
|
| 896 |
" | ".html_safe +
|
|
| 785 | 897 |
link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
|
| 786 | 898 |
end |
| 787 | 899 |
|
| ... | ... | |
| 794 | 906 |
legend = options[:legend] || '' |
| 795 | 907 |
content_tag('table',
|
| 796 | 908 |
content_tag('tr',
|
| 797 |
(pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed') : '') +
|
|
| 798 |
(pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : '') +
|
|
| 799 |
(pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : '')
|
|
| 800 |
), :class => 'progress', :style => "width: #{width};") +
|
|
| 801 |
content_tag('p', legend, :class => 'pourcent')
|
|
| 909 |
(pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed') : ''.html_safe) +
|
|
| 910 |
(pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) +
|
|
| 911 |
(pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe)
|
|
| 912 |
), :class => 'progress', :style => "width: #{width};").html_safe +
|
|
| 913 |
content_tag('p', legend, :class => 'pourcent').html_safe
|
|
| 802 | 914 |
end |
| 803 | 915 |
|
| 804 | 916 |
def checked_image(checked=true) |
| ... | ... | |
| 836 | 948 |
options[:class] << ' disabled' |
| 837 | 949 |
url = '#' |
| 838 | 950 |
end |
| 839 |
link_to name, url, options
|
|
| 951 |
link_to h(name), url, options
|
|
| 840 | 952 |
end |
| 841 | 953 |
|
| 842 | 954 |
def calendar_for(field_id) |
| ... | ... | |
| 879 | 991 |
(@has_content && @has_content[name]) || false |
| 880 | 992 |
end |
| 881 | 993 |
|
| 994 |
def email_delivery_enabled? |
|
| 995 |
!!ActionMailer::Base.perform_deliveries |
|
| 996 |
end |
|
| 997 |
|
|
| 882 | 998 |
# Returns the avatar image tag for the given +user+ if avatars are enabled |
| 883 | 999 |
# +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>') |
| 884 | 1000 |
def avatar(user, options = { })
|
| ... | ... | |
| 896 | 1012 |
end |
| 897 | 1013 |
end |
| 898 | 1014 |
|
| 1015 |
def sanitize_anchor_name(anchor) |
|
| 1016 |
anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
|
|
| 1017 |
end |
|
| 1018 |
|
|
| 899 | 1019 |
# Returns the javascript tags that are included in the html layout head |
| 900 | 1020 |
def javascript_heads |
| 901 | 1021 |
tags = javascript_include_tag(:defaults) |
| 902 | 1022 |
unless User.current.pref.warn_on_leaving_unsaved == '0' |
| 903 |
tags << "\n" + javascript_tag("Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('#{escape_javascript( l(:text_warn_on_leaving_unsaved) )}'); });")
|
|
| 1023 |
tags << "\n".html_safe + javascript_tag("Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('#{escape_javascript( l(:text_warn_on_leaving_unsaved) )}'); });")
|
|
| 904 | 1024 |
end |
| 905 | 1025 |
tags |
| 906 | 1026 |
end |
| 907 | 1027 |
|
| 908 | 1028 |
def favicon |
| 909 |
"<link rel='shortcut icon' href='#{image_path('/favicon.ico')}' />"
|
|
| 1029 |
"<link rel='shortcut icon' href='#{image_path('/favicon.ico')}' />".html_safe
|
|
| 910 | 1030 |
end |
| 911 | 1031 |
|
| 912 | 1032 |
def robot_exclusion_tag |
| 913 |
'<meta name="robots" content="noindex,follow,noarchive" />' |
|
| 1033 |
'<meta name="robots" content="noindex,follow,noarchive" />'.html_safe
|
|
| 914 | 1034 |
end |
| 915 | 1035 |
|
| 916 | 1036 |
def stylesheet_platform_font_tag |
| app/helpers/attachments_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 | 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
| 3 | 5 |
# |
| ... | ... | |
| 28 | 30 |
end |
| 29 | 31 |
end |
| 30 | 32 |
|
| 31 |
def to_utf8(str) |
|
| 32 |
if str.respond_to?(:force_encoding) |
|
| 33 |
str.force_encoding('UTF-8')
|
|
| 34 |
return str if str.valid_encoding? |
|
| 35 |
else |
|
| 36 |
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii |
|
| 37 |
end |
|
| 38 |
|
|
| 39 |
begin |
|
| 40 |
Iconv.conv('UTF-8//IGNORE', 'UTF-8', str + ' ')[0..-3]
|
|
| 41 |
rescue Iconv::InvalidEncoding |
|
| 42 |
# "UTF-8//IGNORE" is not supported on some OS |
|
| 43 |
str |
|
| 33 |
def render_api_attachment(attachment, api) |
|
| 34 |
api.attachment do |
|
| 35 |
api.id attachment.id |
|
| 36 |
api.filename attachment.filename |
|
| 37 |
api.filesize attachment.filesize |
|
| 38 |
api.content_type attachment.content_type |
|
| 39 |
api.description attachment.description |
|
| 40 |
api.content_url url_for(:controller => 'attachments', :action => 'download', :id => attachment, :filename => attachment.filename, :only_path => false) |
|
| 41 |
api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author |
|
| 42 |
api.created_on attachment.created_on |
|
| 44 | 43 |
end |
| 45 | 44 |
end |
| 46 | 45 |
end |
| app/helpers/auth_sources_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/boards_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006-2007 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/calendars_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 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 |
|
|
| 1 | 20 |
module CalendarsHelper |
| 2 | 21 |
def link_to_previous_month(year, month, options={})
|
| 3 | 22 |
target_year, target_month = if month == 1 |
| ... | ... | |
| 5 | 24 |
else |
| 6 | 25 |
[year, month - 1] |
| 7 | 26 |
end |
| 8 |
|
|
| 27 |
|
|
| 9 | 28 |
name = if target_month == 12 |
| 10 | 29 |
"#{month_name(target_month)} #{target_year}"
|
| 11 | 30 |
else |
| 12 | 31 |
"#{month_name(target_month)}"
|
| 13 | 32 |
end |
| 14 | 33 |
|
| 15 |
link_to_month(('« ' + name), target_year, target_month, options)
|
|
| 34 |
# \xc2\xab(utf-8) = « |
|
| 35 |
link_to_month(("\xc2\xab " + name), target_year, target_month, options)
|
|
| 16 | 36 |
end |
| 17 | 37 |
|
| 18 | 38 |
def link_to_next_month(year, month, options={})
|
| ... | ... | |
| 28 | 48 |
"#{month_name(target_month)}"
|
| 29 | 49 |
end |
| 30 | 50 |
|
| 31 |
link_to_month((name + ' »'), target_year, target_month, options) |
|
| 51 |
# \xc2\xbb(utf-8) = » |
|
| 52 |
link_to_month((name + " \xc2\xbb"), target_year, target_month, options) |
|
| 32 | 53 |
end |
| 33 | 54 |
|
| 34 | 55 |
def link_to_month(link_name, year, month, options={})
|
| 35 |
link_to_content_update(link_name, params.merge(:year => year, :month => month))
|
|
| 56 |
link_to_content_update(h(link_name), params.merge(:year => year, :month => month))
|
|
| 36 | 57 |
end |
| 37 | 58 |
end |
| app/helpers/custom_fields_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 | 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
| 3 | 5 |
# |
| ... | ... | |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| ... | ... | |
| 29 | 31 |
{:name => 'DocumentCategoryCustomField', :partial => 'custom_fields/index', :label => DocumentCategory::OptionName}
|
| 30 | 32 |
] |
| 31 | 33 |
end |
| 32 |
|
|
| 34 |
|
|
| 33 | 35 |
# Return custom field html tag corresponding to its format |
| 34 | 36 |
def custom_field_tag(name, custom_value) |
| 35 | 37 |
custom_field = custom_value.custom_field |
| ... | ... | |
| 39 | 41 |
field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format) |
| 40 | 42 |
case field_format.try(:edit_as) |
| 41 | 43 |
when "date" |
| 42 |
text_field_tag(field_name, custom_value.value, :id => field_id, :size => 10) +
|
|
| 44 |
text_field_tag(field_name, custom_value.value, :id => field_id, :size => 10) + |
|
| 43 | 45 |
calendar_for(field_id) |
| 44 | 46 |
when "text" |
| 45 | 47 |
text_area_tag(field_name, custom_value.value, :id => field_id, :rows => 3, :style => 'width:90%') |
| ... | ... | |
| 47 | 49 |
hidden_field_tag(field_name, '0') + check_box_tag(field_name, '1', custom_value.true?, :id => field_id) |
| 48 | 50 |
when "list" |
| 49 | 51 |
blank_option = custom_field.is_required? ? |
| 50 |
(custom_field.default_value.blank? ? "<option value=\"\">--- #{l(:actionview_instancetag_blank_option)} ---</option>" : '') :
|
|
| 52 |
(custom_field.default_value.blank? ? "<option value=\"\">--- #{l(:actionview_instancetag_blank_option)} ---</option>" : '') :
|
|
| 51 | 53 |
'<option></option>' |
| 52 | 54 |
select_tag(field_name, blank_option + options_for_select(custom_field.possible_values_options(custom_value.customized), custom_value.value), :id => field_id) |
| 53 | 55 |
else |
| 54 | 56 |
text_field_tag(field_name, custom_value.value, :id => field_id) |
| 55 | 57 |
end |
| 56 | 58 |
end |
| 57 |
|
|
| 59 |
|
|
| 58 | 60 |
# Return custom field label tag |
| 59 | 61 |
def custom_field_label_tag(name, custom_value) |
| 60 |
content_tag "label", custom_value.custom_field.name +
|
|
| 61 |
(custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>" : ""), |
|
| 62 |
content_tag "label", h(custom_value.custom_field.name) +
|
|
| 63 |
(custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>".html_safe : ""),
|
|
| 62 | 64 |
:for => "#{name}_custom_field_values_#{custom_value.custom_field.id}",
|
| 63 | 65 |
:class => (custom_value.errors.empty? ? nil : "error" ) |
| 64 | 66 |
end |
| 65 |
|
|
| 67 |
|
|
| 66 | 68 |
# Return custom field tag with its label tag |
| 67 | 69 |
def custom_field_tag_with_label(name, custom_value) |
| 68 | 70 |
custom_field_label_tag(name, custom_value) + custom_field_tag(name, custom_value) |
| 69 | 71 |
end |
| 70 |
|
|
| 72 |
|
|
| 71 | 73 |
def custom_field_tag_for_bulk_edit(name, custom_field, projects=nil) |
| 72 | 74 |
field_name = "#{name}[custom_field_values][#{custom_field.id}]"
|
| 73 | 75 |
field_id = "#{name}_custom_field_values_#{custom_field.id}"
|
| 74 | 76 |
field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format) |
| 75 | 77 |
case field_format.try(:edit_as) |
| 76 | 78 |
when "date" |
| 77 |
text_field_tag(field_name, '', :id => field_id, :size => 10) +
|
|
| 79 |
text_field_tag(field_name, '', :id => field_id, :size => 10) + |
|
| 78 | 80 |
calendar_for(field_id) |
| 79 | 81 |
when "text" |
| 80 | 82 |
text_area_tag(field_name, '', :id => field_id, :rows => 3, :style => 'width:90%') |
| ... | ... | |
| 94 | 96 |
return "" unless custom_value |
| 95 | 97 |
format_value(custom_value.value, custom_value.custom_field.field_format) |
| 96 | 98 |
end |
| 97 |
|
|
| 99 |
|
|
| 98 | 100 |
# Return a string used to display a custom value |
| 99 | 101 |
def format_value(value, field_format) |
| 100 | 102 |
Redmine::CustomFieldFormat.format_value(value, field_format) # Proxy |
| ... | ... | |
| 104 | 106 |
def custom_field_formats_for_select(custom_field) |
| 105 | 107 |
Redmine::CustomFieldFormat.as_select(custom_field.class.customized_class.name) |
| 106 | 108 |
end |
| 107 |
|
|
| 109 |
|
|
| 108 | 110 |
# Renders the custom_values in api views |
| 109 | 111 |
def render_api_custom_values(custom_values, api) |
| 110 | 112 |
api.array :custom_fields do |
| app/helpers/documents_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/enumerations_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/gantt_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 | 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
| 3 | 5 |
# |
| ... | ... | |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| ... | ... | |
| 25 | 27 |
params.merge(gantt.params.merge(:zoom => (gantt.zoom+1))), |
| 26 | 28 |
:class => 'icon icon-zoom-in' |
| 27 | 29 |
else |
| 28 |
content_tag('span', l(:text_zoom_in), :class => 'icon icon-zoom-in')
|
|
| 30 |
content_tag('span', l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
|
|
| 29 | 31 |
end |
| 30 |
|
|
| 32 |
|
|
| 31 | 33 |
when :out |
| 32 | 34 |
if gantt.zoom > 1 |
| 33 | 35 |
link_to_content_update l(:text_zoom_out), |
| 34 | 36 |
params.merge(gantt.params.merge(:zoom => (gantt.zoom-1))), |
| 35 | 37 |
:class => 'icon icon-zoom-out' |
| 36 | 38 |
else |
| 37 |
content_tag('span', l(:text_zoom_out), :class => 'icon icon-zoom-out')
|
|
| 39 |
content_tag('span', l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
|
|
| 38 | 40 |
end |
| 39 | 41 |
end |
| 40 | 42 |
end |
| app/helpers/groups_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 |
# Copyright (C) 2006-2009 Jean-Philippe Lang
|
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| ... | ... | |
| 24 | 26 |
end |
| 25 | 27 |
options |
| 26 | 28 |
end |
| 27 |
|
|
| 29 |
|
|
| 28 | 30 |
def group_settings_tabs |
| 29 | 31 |
tabs = [{:name => 'general', :partial => 'groups/general', :label => :label_general},
|
| 30 | 32 |
{:name => 'users', :partial => 'groups/users', :label => :label_user_plural},
|
| app/helpers/issue_categories_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/issue_moves_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
module IssueMovesHelper |
| 2 | 4 |
end |
| app/helpers/issue_relations_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006-2007 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/issue_statuses_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/issues_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 | 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
| 3 | 5 |
# |
| ... | ... | |
| 46 | 48 |
@cached_label_priority ||= l(:field_priority) |
| 47 | 49 |
@cached_label_project ||= l(:field_project) |
| 48 | 50 |
|
| 49 |
link_to_issue(issue) + "<br /><br />" + |
|
| 51 |
(link_to_issue(issue) + "<br /><br />" +
|
|
| 50 | 52 |
"<strong>#{@cached_label_project}</strong>: #{link_to_project(issue.project)}<br />" +
|
| 51 |
"<strong>#{@cached_label_status}</strong>: #{issue.status.name}<br />" +
|
|
| 53 |
"<strong>#{@cached_label_status}</strong>: #{h(issue.status.name)}<br />" +
|
|
| 52 | 54 |
"<strong>#{@cached_label_start_date}</strong>: #{format_date(issue.start_date)}<br />" +
|
| 53 | 55 |
"<strong>#{@cached_label_due_date}</strong>: #{format_date(issue.due_date)}<br />" +
|
| 54 |
"<strong>#{@cached_label_assigned_to}</strong>: #{issue.assigned_to}<br />" +
|
|
| 55 |
"<strong>#{@cached_label_priority}</strong>: #{issue.priority.name}"
|
|
| 56 |
"<strong>#{@cached_label_assigned_to}</strong>: #{h(issue.assigned_to)}<br />" +
|
|
| 57 |
"<strong>#{@cached_label_priority}</strong>: #{h(issue.priority.name)}").html_safe
|
|
| 56 | 58 |
end |
| 57 | 59 |
|
| 58 | 60 |
def issue_heading(issue) |
| ... | ... | |
| 72 | 74 |
end |
| 73 | 75 |
s << content_tag('h3', subject)
|
| 74 | 76 |
s << '</div>' * (ancestors.size + 1) |
| 75 |
s |
|
| 77 |
s.html_safe
|
|
| 76 | 78 |
end |
| 77 | 79 |
|
| 78 | 80 |
def render_descendants_tree(issue) |
| ... | ... | |
| 87 | 89 |
:class => "issue issue-#{child.id} hascontextmenu #{level > 0 ? "idnt idnt-#{level}" : nil}")
|
| 88 | 90 |
end |
| 89 | 91 |
s << '</form></table>' |
| 90 |
s |
|
| 92 |
s.html_safe
|
|
| 91 | 93 |
end |
| 92 | 94 |
|
| 93 | 95 |
def render_custom_fields_rows(issue) |
| ... | ... | |
| 106 | 108 |
n += 1 |
| 107 | 109 |
end |
| 108 | 110 |
s << "</tr>\n" |
| 109 |
s |
|
| 111 |
s.html_safe
|
|
| 110 | 112 |
end |
| 111 | 113 |
|
| 112 | 114 |
def issues_destroy_confirmation_message(issues) |
| ... | ... | |
| 145 | 147 |
# links to #index on issues/show |
| 146 | 148 |
url_params = controller_name == 'issues' ? {:controller => 'issues', :action => 'index', :project_id => @project} : params
|
| 147 | 149 |
|
| 148 |
content_tag('h3', title) +
|
|
| 150 |
content_tag('h3', h(title)) +
|
|
| 149 | 151 |
queries.collect {|query|
|
| 150 | 152 |
link_to(h(query.name), url_params.merge(:query_id => query)) |
| 151 | 153 |
}.join('<br />')
|
| ... | ... | |
| 206 | 208 |
unless no_html |
| 207 | 209 |
label = content_tag('strong', label)
|
| 208 | 210 |
old_value = content_tag("i", h(old_value)) if detail.old_value
|
| 209 |
old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
|
|
| 211 |
old_value = content_tag("strike", old_value) if detail.old_value and detail.value.blank?
|
|
| 210 | 212 |
if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key) |
| 211 | 213 |
# Link to the attachment if it has not been removed |
| 212 | 214 |
value = link_to_attachment(a) |
| ... | ... | |
| 263 | 265 |
end |
| 264 | 266 |
end |
| 265 | 267 |
|
| 266 |
def issues_to_csv(issues, project = nil) |
|
| 267 |
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8') |
|
| 268 |
def issues_to_csv(issues, project, query, options={})
|
|
| 268 | 269 |
decimal_separator = l(:general_csv_decimal_separator) |
| 270 |
encoding = l(:general_csv_encoding) |
|
| 271 |
columns = (options[:columns] == 'all' ? query.available_columns : query.columns) |
|
| 272 |
|
|
| 269 | 273 |
export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| |
| 270 | 274 |
# csv header fields |
| 271 |
headers = [ "#", |
|
| 272 |
l(:field_status), |
|
| 273 |
l(:field_project), |
|
| 274 |
l(:field_tracker), |
|
| 275 |
l(:field_priority), |
|
| 276 |
l(:field_subject), |
|
| 277 |
l(:field_assigned_to), |
|
| 278 |
l(:field_category), |
|
| 279 |
l(:field_fixed_version), |
|
| 280 |
l(:field_author), |
|
| 281 |
l(:field_start_date), |
|
| 282 |
l(:field_due_date), |
|
| 283 |
l(:field_done_ratio), |
|
| 284 |
l(:field_estimated_hours), |
|
| 285 |
l(:field_parent_issue), |
|
| 286 |
l(:field_created_on), |
|
| 287 |
l(:field_updated_on) |
|
| 288 |
] |
|
| 289 |
# Export project custom fields if project is given |
|
| 290 |
# otherwise export custom fields marked as "For all projects" |
|
| 291 |
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_issue_custom_fields |
|
| 292 |
custom_fields.each {|f| headers << f.name}
|
|
| 293 |
# Description in the last column |
|
| 294 |
headers << l(:field_description) |
|
| 295 |
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
|
| 275 |
csv << [ "#" ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) } +
|
|
| 276 |
(options[:description] ? [Redmine::CodesetUtil.from_utf8(l(:field_description), encoding)] : []) |
|
| 277 |
|
|
| 296 | 278 |
# csv lines |
| 297 | 279 |
issues.each do |issue| |
| 298 |
fields = [issue.id, |
|
| 299 |
issue.status.name, |
|
| 300 |
issue.project.name, |
|
| 301 |
issue.tracker.name, |
|
| 302 |
issue.priority.name, |
|
| 303 |
issue.subject, |
|
| 304 |
issue.assigned_to, |
|
| 305 |
issue.category, |
|
| 306 |
issue.fixed_version, |
|
| 307 |
issue.author.name, |
|
| 308 |
format_date(issue.start_date), |
|
| 309 |
format_date(issue.due_date), |
|
| 310 |
issue.done_ratio, |
|
| 311 |
issue.estimated_hours.to_s.gsub('.', decimal_separator),
|
|
| 312 |
issue.parent_id, |
|
| 313 |
format_time(issue.created_on), |
|
| 314 |
format_time(issue.updated_on) |
|
| 315 |
] |
|
| 316 |
custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) }
|
|
| 317 |
fields << issue.description |
|
| 318 |
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
|
| 280 |
col_values = columns.collect do |column| |
|
| 281 |
s = if column.is_a?(QueryCustomFieldColumn) |
|
| 282 |
cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
|
|
| 283 |
show_value(cv) |
|
| 284 |
else |
|
| 285 |
value = issue.send(column.name) |
|
| 286 |
if value.is_a?(Date) |
|
| 287 |
format_date(value) |
|
| 288 |
elsif value.is_a?(Time) |
|
| 289 |
format_time(value) |
|
| 290 |
elsif value.is_a?(Float) |
|
| 291 |
value.to_s.gsub('.', decimal_separator)
|
|
| 292 |
else |
|
| 293 |
value |
|
| 294 |
end |
|
| 295 |
end |
|
| 296 |
s.to_s |
|
| 297 |
end |
|
| 298 |
csv << [ issue.id.to_s ] + col_values.collect {|c| Redmine::CodesetUtil.from_utf8(c.to_s, encoding) } +
|
|
| 299 |
(options[:description] ? [Redmine::CodesetUtil.from_utf8(issue.description, encoding)] : []) |
|
| 319 | 300 |
end |
| 320 | 301 |
end |
| 321 | 302 |
export |
| app/helpers/journals_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006-2008 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| ... | ... | |
| 24 | 26 |
links << link_to_remote(image_tag('comment.png'),
|
| 25 | 27 |
{ :url => {:controller => 'journals', :action => 'new', :id => issue, :journal_id => journal} },
|
| 26 | 28 |
:title => l(:button_quote)) if options[:reply_links] |
| 27 |
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
|
|
| 29 |
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
|
|
| 28 | 30 |
{ :controller => 'journals', :action => 'edit', :id => journal },
|
| 29 | 31 |
:title => l(:button_edit)) if editable |
| 30 | 32 |
end |
| ... | ... | |
| 34 | 36 |
css_classes << " editable" if editable |
| 35 | 37 |
content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => css_classes)
|
| 36 | 38 |
end |
| 37 |
|
|
| 39 |
|
|
| 38 | 40 |
def link_to_in_place_notes_editor(text, field_id, url, options={})
|
| 39 | 41 |
onclick = "new Ajax.Request('#{url_for(url)}', {asynchronous:true, evalScripts:true, method:'get'}); return false;"
|
| 40 | 42 |
link_to text, '#', options.merge(:onclick => onclick) |
| app/helpers/mail_handler_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006-2008 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/members_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/messages_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006-2007 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/my_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/news_helper.rb | ||
|---|---|---|
| 1 |
# redMine - project management software |
|
| 2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 | 5 |
# |
| 4 | 6 |
# This program is free software; you can redistribute it and/or |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| app/helpers/projects_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 | 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
| 3 | 5 |
# |
| ... | ... | |
| 46 | 48 |
options = '' |
| 47 | 49 |
options << "<option value=''></option>" if project.allowed_parents.include?(nil) |
| 48 | 50 |
options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected) |
| 49 |
content_tag('select', options, :name => 'project[parent_id]', :id => 'project_parent_id')
|
|
| 51 |
content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id')
|
|
| 50 | 52 |
end |
| 51 | 53 |
|
| 52 | 54 |
def render_project_short_description(project) |
| ... | ... | |
| 90 | 92 |
s << ("</li></ul>\n" * ancestors.size)
|
| 91 | 93 |
@project = original_project |
| 92 | 94 |
end |
| 93 |
s |
|
| 95 |
s.html_safe
|
|
| 94 | 96 |
end |
| 95 | 97 |
|
| 96 | 98 |
|
| app/helpers/queries_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 1 | 3 |
# Redmine - project management software |
| 2 | 4 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
| 3 | 5 |
# |
| ... | ... | |
| 5 | 7 |
# modify it under the terms of the GNU General Public License |
| 6 | 8 |
# as published by the Free Software Foundation; either version 2 |
| 7 | 9 |
# of the License, or (at your option) any later version. |
| 8 |
#
|
|
| 10 |
# |
|
| 9 | 11 |
# This program is distributed in the hope that it will be useful, |
| 10 | 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | 14 |
# GNU General Public License for more details. |
| 13 |
#
|
|
| 15 |
# |
|
| 14 | 16 |
# You should have received a copy of the GNU General Public License |
| 15 | 17 |
# along with this program; if not, write to the Free Software |
| 16 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 | 19 |
|
| 18 | 20 |
module QueriesHelper |
| 19 |
|
|
| 21 |
|
|
| 20 | 22 |
def operators_for_select(filter_type) |
| 21 | 23 |
Query.operators_by_filter_type[filter_type].collect {|o| [l(Query.operators[o]), o]}
|
| 22 | 24 |
end |
| 23 |
|
|
| 25 |
|
|
| 24 | 26 |
def column_header(column) |
| 25 | 27 |
column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption, |
| 26 |
:default_order => column.default_order) :
|
|
| 27 |
content_tag('th', column.caption)
|
|
| 28 |
:default_order => column.default_order) : |
|
| 29 |
content_tag('th', h(column.caption))
|
|
| 28 | 30 |
end |
| 29 |
|
|
| 31 |
|
|
| 30 | 32 |
def column_content(column, issue) |
| 31 | 33 |
value = column.value(issue) |
| 32 |
|
|
| 34 |
|
|
| 33 | 35 |
case value.class.name |
| 34 | 36 |
when 'String' |
| 35 | 37 |
if column.name == :subject |
| ... | ... | |
| 45 | 47 |
if column.name == :done_ratio |
| 46 | 48 |
progress_bar(value, :width => '80px') |
| 47 | 49 |
else |
| 48 |
value.to_s
|
|
| 50 |
h(value.to_s)
|
|
| 49 | 51 |
end |
| 50 | 52 |
when 'User' |
| 51 | 53 |
link_to_user value |
| ... | ... | |
| 74 | 76 |
@query.project = @project |
| 75 | 77 |
session[:query] = {:id => @query.id, :project_id => @query.project_id}
|
| 76 | 78 |
sort_clear |
| 79 |
elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil) |
|
| 80 |
# Give it a name, required to be valid |
|
| 81 |
@query = Query.new(:name => "_") |
|
| 82 |
@query.project = @project |
|
| 83 |
build_query_from_params |
|
| 84 |
session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
|
|
| 77 | 85 |
else |
| 78 |
if api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil) |
|
| 79 |
# Give it a name, required to be valid |
|
| 80 |
@query = Query.new(:name => "_") |
|
| 81 |
@query.project = @project |
|
| 82 |
if params[:fields] || params[:f] |
|
| 83 |
@query.filters = {}
|
|
| 84 |
@query.add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v]) |
|
| 85 |
else |
|
| 86 |
@query.available_filters.keys.each do |field| |
|
| 87 |
@query.add_short_filter(field, params[field]) if params[field] |
|
| 88 |
end |
|
| 89 |
end |
|
| 90 |
@query.group_by = params[:group_by] |
|
| 91 |
@query.column_names = params[:c] || (params[:query] && params[:query][:column_names]) |
|
| 92 |
session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
|
|
Also available in: Unified diff