Compare commits

...

26 Commits

Author SHA1 Message Date
Jean-Philippe Lang
8cdd427a0e Changes for 2.1.6 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11152 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-01-09 14:03:28 +00:00
Jean-Philippe Lang
de2b7c2879 Upgrade to Rails 3.2.11.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11151 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-01-09 14:01:43 +00:00
Jean-Philippe Lang
f0aad8c2a8 Backported r10842 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11150 e93f8b46-1217-0410-a6f0-8f06a7374b81
2013-01-09 14:01:27 +00:00
Jean-Philippe Lang
68b923640e Set version to 2.1.5
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11046 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-18 12:56:45 +00:00
Jean-Philippe Lang
4e2fbf440b Changelog for 2.1.5 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11043 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-18 12:24:45 +00:00
Toshi MARUYAMA
5572b6c715 Merged r11035 from trunk to 2.1-stable (#12615)
Russian translation updated by Kirill Bezrukov.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11038 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-17 23:45:36 +00:00
Toshi MARUYAMA
d63f0fa5b0 Merged r11022 from trunk to 2.1-stable (#12614)
Dutch translation updated.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11024 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-17 12:44:13 +00:00
Toshi MARUYAMA
dff772b066 Merged r11014 from trunk to 2.1-stable (#12605)
Norwegian translation for 1.4-stable updated by Ketil Mehl.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11019 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-16 07:39:07 +00:00
Jean-Philippe Lang
fb2cbdc6cc Merged r10991 from trunk (#12568).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11008 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-15 07:55:41 +00:00
Jean-Philippe Lang
6062a0a89d Merged r10885 from trunk (#12451).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11007 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-15 07:54:21 +00:00
Jean-Philippe Lang
0ebf95d819 Merged r10992 from trunk (#12400).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11005 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-15 07:52:31 +00:00
Jean-Philippe Lang
14879e24c4 Merged r10956 from trunk (#12513).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11003 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-15 07:50:45 +00:00
Jean-Philippe Lang
ca0b289479 Merged r10975 from trunk (#12566).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@11001 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-12-15 07:48:42 +00:00
Jean-Philippe Lang
e36a611f81 Reverts r10895 (#12472).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10897 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-30 10:25:22 +00:00
Jean-Philippe Lang
6c2eec59d8 Merged r10893 into 2.1-stable (#12472).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10895 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-30 08:58:26 +00:00
Jean-Philippe Lang
905ed3aa75 Updates for 2.1.4 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10875 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-24 09:35:08 +00:00
Jean-Philippe Lang
bb4c530ba2 Merged r10865 and r10866 from trunk (#12431).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10873 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-23 22:31:02 +00:00
Jean-Philippe Lang
e3958ef577 Merged r10838 from trunk (#12274).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10872 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-23 22:29:45 +00:00
Jean-Philippe Lang
c5f2dadb2c Merged r10836 from trunk (#12298).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10871 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-23 22:28:37 +00:00
Jean-Philippe Lang
af8dcccb7b Merged r10837 from trunk (#12332).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10870 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-23 22:25:40 +00:00
Toshi MARUYAMA
c0742ed9e6 Merged r10862 from trunk to 2.1-stable (#12409)
scm: git: change extra_report_last_commit type at unit test to string.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10863 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-22 01:10:50 +00:00
Jean-Philippe Lang
8c7ae20402 Merged r10850 from trunk (#12396).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10861 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-21 20:44:19 +00:00
Toshi MARUYAMA
06b68f1948 Merged r10856 and r10857 from trunk to 2.1-stable (#12409)
scm: git: fix changesets aren't read after clear_changesets call.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10858 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-21 09:55:48 +00:00
Toshi MARUYAMA
b51203bc83 Merged r10853 from trunk (#12399)
svn propset svn:eol-style native to fixtures.


git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10855 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-21 07:19:57 +00:00
Toshi MARUYAMA
f578a5c4f6 Merged r10852 from trunk (#12399)
fix non ASCII attachment filename encoding broken (MOJIBAKE) in receiving mail on Ruby 1.8.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10854 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-21 07:14:30 +00:00
Jean-Philippe Lang
17d1907747 Merged r10840 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.1-stable@10848 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-11-18 20:37:28 +00:00
30 changed files with 472 additions and 130 deletions

View File

@@ -1,6 +1,6 @@
source 'http://rubygems.org'
gem 'rails', '3.2.8'
gem 'rails', '3.2.11'
gem "jquery-rails", "~> 2.0.2"
gem "i18n", "~> 0.6.0"
gem "coderay", "~> 1.0.6"
@@ -41,7 +41,7 @@ end
platforms :mri_18, :mingw_18 do
group :mysql do
gem "mysql"
gem "mysql", "~> 2.8.1"
end
end

View File

@@ -26,7 +26,8 @@ class PreviewsController < ApplicationController
if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n")
@description = nil
end
@notes = params[:notes]
# params[:notes] is useful for preview of notes in issue history
@notes = params[:notes] || (params[:issue] ? params[:issue][:notes] : nil)
else
@description = (params[:issue] ? params[:issue][:description] : nil)
end

View File

@@ -129,15 +129,6 @@ class WikiController < ApplicationController
# don't keep previous comment
@content.comments = nil
if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
attachments = Attachment.attach_files(@page, params[:attachments])
render_attachment_warning_if_needed(@page)
# don't save content if text wasn't changed
@page.save
redirect_to :action => 'show', :project_id => @project, :id => @page.title
return
end
@content.comments = params[:content][:comments]
@text = params[:content][:text]
if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
@@ -149,8 +140,8 @@ class WikiController < ApplicationController
@content.text = @text
end
@content.author = User.current
@page.content = @content
if @page.save
if @page.save_with_content
attachments = Attachment.attach_files(@page, params[:attachments])
render_attachment_warning_if_needed(@page)
call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
@@ -239,7 +230,7 @@ class WikiController < ApplicationController
# Export wiki to a single pdf or html file
def export
@pages = @wiki.pages.all(:order => 'title', :include => [:content, :attachments], :limit => 75)
@pages = @wiki.pages.all(:order => 'title', :include => [:content, :attachments])
respond_to do |format|
format.html {
export = render_to_string :action => 'export_multiple', :layout => false

View File

@@ -130,7 +130,13 @@ class CustomField < ActiveRecord::Base
possible_values_options = possible_values_options(customized)
if possible_values_options.present?
keyword = keyword.to_s.downcase
possible_values_options.detect {|text, id| text.downcase == keyword}.try(:last)
if v = possible_values_options.detect {|text, id| text.downcase == keyword}
if v.is_a?(Array)
v.last
else
v
end
end
else
keyword
end

View File

@@ -124,6 +124,7 @@ class MailHandler < ActionMailer::Base
def dispatch
headers = [email.in_reply_to, email.references].flatten.compact
subject = email.subject.to_s
if headers.detect {|h| h.to_s =~ MESSAGE_ID_RE}
klass, object_id = $1, $2.to_i
method_name = "receive_#{klass}_reply"
@@ -132,9 +133,9 @@ class MailHandler < ActionMailer::Base
else
# ignoring it
end
elsif m = email.subject.match(ISSUE_REPLY_SUBJECT_RE)
elsif m = subject.match(ISSUE_REPLY_SUBJECT_RE)
receive_issue_reply(m[1].to_i)
elsif m = email.subject.match(MESSAGE_REPLY_SUBJECT_RE)
elsif m = subject.match(MESSAGE_REPLY_SUBJECT_RE)
receive_message_reply(m[1].to_i)
else
dispatch_to_default
@@ -244,9 +245,26 @@ class MailHandler < ActionMailer::Base
def add_attachments(obj)
if email.attachments && email.attachments.any?
email.attachments.each do |attachment|
filename = attachment.filename
unless filename.respond_to?(:encoding)
# try to reencode to utf8 manually with ruby1.8
h = attachment.header['Content-Disposition']
unless h.nil?
begin
if m = h.value.match(/filename\*[0-9\*]*=([^=']+)'/)
filename = Redmine::CodesetUtil.to_utf8(filename, m[1])
elsif m = h.value.match(/filename=.*=\?([^\?]+)\?[BbQq]\?/)
# http://tools.ietf.org/html/rfc2047#section-4
filename = Redmine::CodesetUtil.to_utf8(filename, m[1])
end
rescue
# nop
end
end
end
obj.attachments << Attachment.create(:container => obj,
:file => attachment.decoded,
:filename => attachment.filename,
:filename => filename,
:author => user,
:content_type => attachment.mime_type)
end

View File

@@ -427,5 +427,9 @@ class Repository < ActiveRecord::Base
connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
clear_extra_info_of_changesets
end
def clear_extra_info_of_changesets
end
end

View File

@@ -255,4 +255,15 @@ class Repository::Git < Repository
:order => 'committed_on DESC'
)
end
def clear_extra_info_of_changesets
return if extra_info.nil?
v = extra_info["extra_report_last_commit"]
write_attribute(:extra_info, nil)
h = {}
h["extra_report_last_commit"] = v
merge_extra_info(h)
self.save
end
private :clear_extra_info_of_changesets
end

View File

@@ -172,6 +172,21 @@ class WikiPage < ActiveRecord::Base
self.parent = parent_page
end
# Saves the page and its content if text was changed
def save_with_content
ret = nil
transaction do
if new_record?
# Rails automatically saves associated content
ret = save
else
ret = save && (content.text_changed? ? content.save : true)
end
raise ActiveRecord::Rollback unless ret
end
ret
end
protected
def validate_parent_title

View File

@@ -1,2 +1,8 @@
$("#journal-<%= @journal.id %>-notes").hide();
$("#journal-<%= @journal.id %>-notes").after('<%= escape_javascript(render :partial => 'notes_form') %>');
if ($("form#journal-<%= @journal.id %>-form").length > 0) {
// journal edit form already loaded
$("#journal-<%= @journal.id %>-form").show();
} else {
$("#journal-<%= @journal.id %>-notes").after('<%= escape_javascript(render :partial => 'notes_form') %>');
}

View File

@@ -14,7 +14,7 @@
<tr class="<%= cycle 'odd', 'even' %>">
<td>
<%= link_to repository.identifier,
{:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier_param.present? %>
{:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier.present? %>
</td>
<td align="center"><%= checked_image repository.is_default? %></td>
<td><%=h repository.scm_name %></td>

View File

@@ -49,7 +49,7 @@ nl:
one: "ongeveer 1 uur"
other: "ongeveer %{count} uren"
x_hours:
one: "1 hour"
one: "1 uur"
other: "%{count} hours"
x_days:
one: "1 dag"
@@ -990,58 +990,58 @@ nl:
description_all_columns: Alle kolommen
button_export: Exporteren
label_export_options: "%{export_format} export opties"
error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
error_attachment_too_big: Dit bestand kan niet worden geupload omdat het de maximaal toegestane grootte overschrijd (%{max_size})
notice_failed_to_save_time_entries: "Opslaan gefaald voor %{count} tijdsnotatie(s) van %{total} geselecteerde: %{ids}."
label_x_issues:
zero: 0 issue
one: 1 issue
other: "%{count} issues"
label_repository_new: New repository
field_repository_is_default: Main repository
label_copy_attachments: Copy attachments
zero: 0 incidenten
one: 1 incidenten
other: "%{count} incidenten"
label_repository_new: Nieuw repository
field_repository_is_default: Hoofd repository
label_copy_attachments: Copieer bijlage(n)
label_item_position: "%{position}/%{count}"
label_completed_versions: Completed versions
field_multiple: Multiple values
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
permission_manage_related_issues: Manage related issues
label_completed_versions: Versies compleet
field_multiple: Meerdere waardes
setting_commit_cross_project_ref: Sta toe om incidenten van alle projecten te refereren en oplossen
text_issue_conflict_resolution_add_notes: Voeg mijn notities toe en annuleer andere wijzigingen
text_issue_conflict_resolution_overwrite: Voeg mijn wijzigingen alsnog toe (voorgaande notities worden bewaard, maar sommige kunnen overschreden worden)
notice_issue_update_conflict: Dit incident is reeds geupdate door een andere gebruiker terwijl jij bezig was
text_issue_conflict_resolution_cancel: Annuleer mijn wijzigingen en geef pagina opnieuw weer %{link}
permission_manage_related_issues: Beheer gerelateerde incidenten
field_auth_source_ldap_filter: LDAP filter
label_search_for_watchers: Search for watchers to add
notice_account_deleted: Your account has been permanently deleted.
setting_unsubscribe: Allow users to delete their own account
button_delete_my_account: Delete my account
label_search_for_watchers: Zoek om monitoorders toe te voegen
notice_account_deleted: Uw account is permanent verwijderd
setting_unsubscribe: Sta gebruikers toe hun eigen account te verwijderen
button_delete_my_account: Verwijder mijn account
text_account_destroy_confirmation: |-
Are you sure you want to proceed?
Your account will be permanently deleted, with no way to reactivate it.
error_session_expired: Your session has expired. Please login again.
text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
setting_session_lifetime: Session maximum lifetime
setting_session_timeout: Session inactivity timeout
label_session_expiration: Session expiration
permission_close_project: Close / reopen the project
label_show_closed_projects: View closed projects
button_close: Close
button_reopen: Reopen
project_status_active: active
project_status_closed: closed
project_status_archived: archived
text_project_closed: This project is closed and read-only.
notice_user_successful_create: User %{id} created.
field_core_fields: Standard fields
Weet u zeker dat u door wilt gaan?
Uw account wordt permanent verwijderd zonder mogelijkheid deze te heractiveren.
error_session_expired: Uw sessie is verlopen. U dient opnieuw in te loggen.
text_session_expiration_settings: "Waarschuwing: door deze instelling te wijzigen kan sessies laten verlopen inclusief de uwe"
setting_session_lifetime: Maximale sessieduur
setting_session_timeout: Sessie inactiviteit timeout
label_session_expiration: Sessie verlopen
permission_close_project: Sluit / heropen project
label_show_closed_projects: Gesloten projecten weergeven
button_close: Sluiten
button_reopen: Heropen
project_status_active: actief
project_status_closed: gesloten
project_status_archived: gearchiveerd
text_project_closed: Dit project is gesloten en op alleen-lezen
notice_user_successful_create: Gebruiker %{id} aangemaakt.
field_core_fields: Standaard verleden
field_timeout: Timeout (in seconds)
setting_thumbnails_enabled: Display attachment thumbnails
setting_thumbnails_size: Thumbnails size (in pixels)
label_status_transitions: Status transitions
label_fields_permissions: Fields permissions
label_readonly: Read-only
label_required: Required
setting_thumbnails_enabled: Geef bijlage miniaturen weer
setting_thumbnails_size: Grootte miniaturen (in pixels)
label_status_transitions: Status transitie
label_fields_permissions: Permissie velden
label_readonly: Alleen-lezen
label_required: Verplicht
text_repository_identifier_info: 'Alleen kleine letter (a-z), cijfers, streepjes en liggende streepjes zijn toegestaan.<br />Eenmaal opgeslagen kan de identifier niet worden gewijzigd.'
field_board_parent: Parent forum
label_attribute_of_project: Project's %{name}
label_attribute_of_author: Author's %{name}
label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: Copy subtasks
field_board_parent: Hoofd forum
label_attribute_of_project: Project %{name}
label_attribute_of_author: Auteur(s) %{name}
label_attribute_of_assigned_to: Toegewezen %{name}
label_attribute_of_fixed_version: Target versions %{name}
label_copy_subtasks: Kopieer subtaken

View File

@@ -971,64 +971,64 @@
setting_issue_group_assignment: Tillat tildeling av saker til grupper
label_diff: diff
description_query_sort_criteria_direction: Sort direction
description_query_sort_criteria_direction: Sorteringsretning
description_project_scope: Search scope
description_filter: Filter
description_user_mail_notification: Mail notification settings
description_date_from: Enter start date
description_message_content: Message content
description_available_columns: Available Columns
description_date_range_interval: Choose range by selecting start and end date
description_date_from: Oppgi startdato
description_message_content: Meldingsinnhold
description_available_columns: Tilgjengelige kolonner
description_date_range_interval: Velg datointervall ved å spesifisere start- og sluttdato
description_issue_category_reassign: Choose issue category
description_search: Searchfield
description_search: Søkefelt
description_notes: Notes
description_date_range_list: Choose range from list
description_choose_project: Projects
description_date_to: Enter end date
description_choose_project: Prosjekter
description_date_to: Oppgi sluttdato
description_query_sort_criteria_attribute: Sort attribute
description_wiki_subpages_reassign: Choose new parent page
description_selected_columns: Selected Columns
label_parent_revision: Parent
label_child_revision: Child
description_wiki_subpages_reassign: Velg ny overordnet side
description_selected_columns: Valgte kolonner
label_parent_revision: Overordnet
label_child_revision: Underordnet
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Edit this section
setting_default_issue_start_date_to_creation_date: Bruk dagens dato som startdato for nye saker
button_edit_section: Rediger denne seksjonen
setting_repositories_encodings: Attachments and repositories encodings
description_all_columns: All Columns
button_export: Export
label_export_options: "%{export_format} export options"
error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
description_all_columns: Alle kolonnene
button_export: Eksporter
label_export_options: "%{export_format} eksportvalg"
error_attachment_too_big: Filen overstiger maksimum filstørrelse (%{max_size}) og kan derfor ikke lastes opp
notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
label_x_issues:
zero: 0 sak
one: 1 sak
other: "%{count} saker"
label_repository_new: New repository
field_repository_is_default: Main repository
label_copy_attachments: Copy attachments
label_repository_new: Nytt depot
field_repository_is_default: Hoveddepot
label_copy_attachments: Kopier vedlegg
label_item_position: "%{position}/%{count}"
label_completed_versions: Completed versions
text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
field_multiple: Multiple values
text_project_identifier_info: Kun små bokstaver (a-z), tall, bindestrek (-) og "underscore" (_) er tillatt.<br />Etter lagring er det ikke mulig å gjøre endringer.
field_multiple: Flere verdier
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
notice_issue_update_conflict: Saken ble oppdatert av en annen bruker mens du redigerte den.
text_issue_conflict_resolution_cancel: Forkast alle endringen mine og vis %{link} på nytt
permission_manage_related_issues: Manage related issues
field_auth_source_ldap_filter: LDAP filter
label_search_for_watchers: Search for watchers to add
notice_account_deleted: Your account has been permanently deleted.
setting_unsubscribe: Allow users to delete their own account
button_delete_my_account: Delete my account
notice_account_deleted: Din konto er ugjenkallelig slettet.
setting_unsubscribe: Tillat brukere å slette sin egen konto
button_delete_my_account: Slett kontoen min
text_account_destroy_confirmation: |-
Are you sure you want to proceed?
Your account will be permanently deleted, with no way to reactivate it.
error_session_expired: Your session has expired. Please login again.
text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
setting_session_lifetime: Session maximum lifetime
setting_session_timeout: Session inactivity timeout
label_session_expiration: Session expiration
Er du sikker på at du ønsker å fortsette?
Kontoen din vil bli ugjenkallelig slettet uten mulighet for å reaktiveres igjen.
error_session_expired: Økten har gått ut på tid. Vennligst logg på igjen.
text_session_expiration_settings: "Advarsel: ved å endre disse innstillingene kan aktive økter gå ut på tid, inkludert din egen."
setting_session_lifetime: Øktenes makslengde
setting_session_timeout: Økten er avsluttet på grunn av inaktivitet
label_session_expiration: Økten er avsluttet
permission_close_project: Close / reopen the project
label_show_closed_projects: View closed projects
button_close: Close

View File

@@ -1121,7 +1121,7 @@ ru:
button_export: Экспорт
label_export_options: "%{export_format} параметры экспорта"
error_attachment_too_big: Этот файл нельзя загрузить из-за превышения максимального размера файла (%{max_size})
notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
notice_failed_to_save_time_entries: "Невозможно сохранить %{count} затраченное время для %{total} выбранных: %{ids}."
label_x_issues:
zero: 0 Задач
one: 1 Задача
@@ -1147,11 +1147,11 @@ ru:
setting_unsubscribe: "Разрешить пользователям удалять свои учетные записи"
button_delete_my_account: "Удалить мою учетную запись"
text_account_destroy_confirmation: "Ваша учетная запись будет полностью удалена без возможности восстановления.\nВы уверены, что хотите продолжить?"
error_session_expired: Your session has expired. Please login again.
error_session_expired: Срок вашей сессии истек. Пожалуйста войдите еще раз
text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
setting_session_lifetime: Session maximum lifetime
setting_session_timeout: Session inactivity timeout
label_session_expiration: Session expiration
setting_session_lifetime: Максимальная продолжительность сессии
setting_session_timeout: Таймут сессии
label_session_expiration: Срок истечения сессии
permission_close_project: Закрывать / открывать проекты
label_show_closed_projects: Просматривать закрытые проекты
button_close: Сделать закрытым
@@ -1162,17 +1162,17 @@ ru:
text_project_closed: Проект закрыт и находиться в режиме только для чтения.
notice_user_successful_create: Пользователь %{id} создан.
field_core_fields: Стандартные поля
field_timeout: Timeout (in seconds)
setting_thumbnails_enabled: Display attachment thumbnails
setting_thumbnails_size: Thumbnails size (in pixels)
field_timeout: Таймаут (в секундах)
setting_thumbnails_enabled: Отображать превью для приложений
setting_thumbnails_size: Размер первью (в пикселях)
label_status_transitions: Статус-переходы
label_fields_permissions: Права на изменения полей
label_readonly: Не изменяется
label_required: Обязательное
text_repository_identifier_info: Допускаются только строчные латинские буквы (a-z), цифры, тире и подчеркивания.<br />После сохранения идентификатор изменить нельзя.
field_board_parent: Родительский форум
label_attribute_of_project: Project's %{name}
label_attribute_of_project: Проект %{name}
label_attribute_of_author: Имя автора %{name}
label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: Target version's %{name}
label_attribute_of_assigned_to: Назначена %{name}
label_attribute_of_fixed_version: Версия %{name}
label_copy_subtasks: Копировать подзадачи

View File

@@ -4,6 +4,31 @@ Redmine - project management software
Copyright (C) 2006-2012 Jean-Philippe Lang
http://www.redmine.org/
== 2013-01-09 v2.1.6
* Upgrade to Rails 3.2.11
== 2012-12-18 v2.1.5
* Defect #12400: Validation fails when receiving an email with list custom fields
* Defect #12451: Macros.rb extract_macro_options should use lazy search
* Defect #12513: Grouping of issues by custom fields not correct in PDF export
* Defect #12566: Issue history notes previews are broken
* Defect #12568: Clicking "edit" on a journal multiple times shows multiple forms
* Patch #12605: Norwegian translation for 1.4-stable update
* Patch #12614: Dutch translation
* Patch #12615: Russian translation
== 2012-11-24 v2.1.4
* Defect #12274: Wiki export from Index by title is truncated
* Defect #12298: Right-click context menu unable to batch/bulk update (IE8)
* Defect #12332: Repository identifier does not display on Project/Settings/Repositories
* Defect #12396: Error when receiving an email without subject header
* Defect #12399: Non ASCII attachment filename encoding broken (MOJIBAKE) in receiving mail on Ruby 1.8
* Defect #12409: Git: changesets aren't read after clear_changesets call
* Defect #12431: Project.rebuild! sorts root projects by id instead of name
== 2012-11-17 v2.1.3
* Defect #12050: :export links to repository files lead to a 404 error

View File

@@ -186,7 +186,7 @@ module CollectiveIdea #:nodoc:
end
# Find root node(s)
root_nodes = where("#{quoted_parent_column_name} IS NULL").order("#{quoted_left_column_name}, #{quoted_right_column_name}, id").each do |root_node|
root_nodes = where("#{quoted_parent_column_name} IS NULL").order(acts_as_nested_set_options[:order]).each do |root_node|
# setup index for this scope
indices[scope.call(root_node)] ||= 0
set_left_and_rights.call(root_node)

View File

@@ -422,7 +422,7 @@ module Redmine
if query.grouped? &&
(group = query.group_by_column.value(issue)) != previous_group
pdf.SetFontStyle('B',10)
group_label = group.blank? ? 'None' : group.to_s
group_label = group.blank? ? 'None' : group.to_s.dup
group_label << " (#{query.issue_count_by_group[group]})"
pdf.Bookmark group_label, 0, -1
pdf.RDMCell(table_width + col_id_width, row_height * 2, group_label, 1, 1, 'L')

View File

@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc:
MAJOR = 2
MINOR = 1
TINY = 3
TINY = 6
# Branch values:
# * official release: nil

View File

@@ -48,7 +48,7 @@ module Redmine
def extract_macro_options(args, *keys)
options = {}
while args.last.to_s.strip =~ %r{^(.+)\=(.+)$} && keys.include?($1.downcase.to_sym)
while args.last.to_s.strip =~ %r{^(.+?)\=(.+)$} && keys.include?($1.downcase.to_sym)
options[$1.downcase.to_sym] = $2
args.pop
end

View File

@@ -25,7 +25,7 @@ function contextMenuClick(event) {
}
contextMenuHide();
if (target.is('a') || target.is('img')) { return; }
if (event.which == 1 /*TODO || (navigator.appVersion.match(/\bMSIE\b/))*/) {
if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) {
var tr = target.parents('tr').first();
if (tr.length && tr.hasClass('hascontextmenu')) {
// a row was clicked, check if the click was on checkbox

View File

@@ -0,0 +1,26 @@
Date: Tue, 20 Nov 2012 23:08:25 +0900
Message-ID: <CANBr5-UZM=Odz4U3Q6vHd_9cd2tCT-_P9xDd=hRJ0aoMNTWXbw@mail.gmail.com>
Subject: test
From: John Smith <JSmith@somenet.foo>
To: redmine@somenet.foo
Content-Type: multipart/mixed; boundary=14dae93a13bf76ca5d04ceedc458
--14dae93a13bf76ca5d04ceedc458
Content-Type: text/plain; charset=ISO-8859-1
test
--14dae93a13bf76ca5d04ceedc458
Content-Type: text/plain; charset=US-ASCII;
name="=?ISO-8859-1?B?xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tw=?=
=?ISO-8859-1?B?/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc?=
=?ISO-8859-1?B?/MTk1vbc/C50eHQ=?="
Content-Disposition: attachment;
filename="=?ISO-8859-1?B?xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tw=?=
=?ISO-8859-1?B?/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc?=
=?ISO-8859-1?B?/MTk1vbc/C50eHQ=?="
Content-Transfer-Encoding: base64
X-Attachment-Id: f_h9r3mcjz0
dGVzdAo=
--14dae93a13bf76ca5d04ceedc458--

View File

@@ -0,0 +1,20 @@
Date: Mon, 19 Nov 2012 10:17:45 +0900
Message-ID: <CANBr5-U6cXMfLek5QiB2ZrBPR3vTThn9_Upvdkf3Dkod664+Xw@mail.gmail.com>
Subject: test
From: John Smith <JSmith@somenet.foo>
To: redmine@somenet.foo
Content-Type: multipart/mixed; boundary=bcaec54ee4ea84f77904cecee22e
--bcaec54ee4ea84f77904cecee22e
Content-Type: text/plain; charset=ISO-8859-1
test
--bcaec54ee4ea84f77904cecee22e
Content-Type: text/plain; charset=US-ASCII; name="=?ISO-2022-JP?B?GyRCJUYlOSVIGyhCLnR4dA==?="
Content-Disposition: attachment; filename="=?ISO-2022-JP?B?GyRCJUYlOSVIGyhCLnR4dA==?="
Content-Transfer-Encoding: base64
X-Attachment-Id: f_h9owndpv0
dGVzdAo=
--bcaec54ee4ea84f77904cecee22e--

View File

@@ -0,0 +1,10 @@
Content-Type: application/ms-tnef; name="winmail.dat"
Content-Transfer-Encoding: binary
From: John Smith <JSmith@somenet.foo>
To: "redmine@somenet.foo" <redmine@somenet.foo>
Date: Fri, 1 Jun 2012 14:39:38 +0200
Message-ID: <87C31D42249DD0489D1A1444E3232DD7019D6183@foo.bar>
Accept-Language: de-CH, en-US
Content-Language: de-CH
Fixture

View File

@@ -0,0 +1,34 @@
Message-ID: <50AB9546.7020800@gmail.com>
Date: Tue, 20 Nov 2012 23:35:50 +0900
From: John Smith <JSmith@somenet.foo>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc13 Thunderbird/3.1.10
MIME-Version: 1.0
To: redmine@somenet.foo
Subject: test
Content-Type: multipart/mixed;
boundary="------------050902080306030406090208"
This is a multi-part message in MIME format.
--------------050902080306030406090208
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
test
--------------050902080306030406090208
Content-Type: image/png;
name="=?ISO-8859-1?Q?=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4?=
=?ISO-8859-1?Q?=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6?=
=?ISO-8859-1?Q?=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6?=
=?ISO-8859-1?Q?=DC=FC=C4=E4=D6=F6=DC=FC=2Epng?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename*0*=ISO-8859-1''%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6;
filename*1*=%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC;
filename*2*=%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4;
filename*3*=%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%2E%70%6E%67
iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlz
AAALEwAACxMBAJqcGAAAAAd0SU1FB9wLFA4fJhRKIUQAAAAUSURBVAjXY/z//z8DEmBiQAWk
8gHq9gMHP8uZWAAAAABJRU5ErkJggg==
--------------050902080306030406090208--

View File

@@ -0,0 +1,26 @@
Message-ID: <50AA00C6.4070108@gmail.com>
Date: Mon, 19 Nov 2012 18:49:58 +0900
From: John Smith <JSmith@somenet.foo>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Lightning/1.0b1 Thunderbird/3.0.10
MIME-Version: 1.0
To: redmine@somenet.foo
Subject: test
Content-Type: multipart/mixed;
boundary="------------030104060902010800050907"
This is a multi-part message in MIME format.
--------------030104060902010800050907
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit
test
--------------030104060902010800050907
Content-Type: text/plain;
name="=?ISO-2022-JP?B?GyRCJUYlOSVIGyhCLnR4dA==?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename*=ISO-2022-JP''%1B%24%42%25%46%25%39%25%48%1B%28%42%2E%74%78%74
dGVzdAo=
--------------030104060902010800050907--

View File

@@ -39,3 +39,4 @@ pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
category: Stock management
searchable field: Value for a custom field
Database: postgresql

View File

@@ -212,4 +212,9 @@ class CustomFieldTest < ActiveSupport::TestCase
assert_nil CustomField.new(:field_format => 'text').value_class
assert_nil CustomField.new.value_class
end
def test_value_from_keyword_for_list_custom_field
field = CustomField.find(1)
assert_equal 'PostgreSQL', field.value_from_keyword('postgresql', Issue.find(1))
end
end

View File

@@ -100,6 +100,25 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(text, :object => Issue.find(1))
end
def test_extract_macro_options_should_with_args
options = extract_macro_options(["arg1", "arg2"], :foo, :size)
assert_equal([["arg1", "arg2"], {}], options)
end
def test_extract_macro_options_should_with_options
options = extract_macro_options(["foo=bar", "size=2"], :foo, :size)
assert_equal([[], {:foo => "bar", :size => "2"}], options)
end
def test_extract_macro_options_should_with_args_and_options
options = extract_macro_options(["arg1", "arg2", "foo=bar", "size=2"], :foo, :size)
assert_equal([["arg1", "arg2"], {:foo => "bar", :size => "2"}], options)
end
def test_extract_macro_options_should_parse_options_lazily
options = extract_macro_options(["params=x=1&y=2"], :params)
assert_equal([[], {:params => "x=1&y=2"}], options)
end
def test_macro_exception_should_be_displayed
Redmine::WikiFormatting::Macros.macro :exception do |obj, args|

View File

@@ -177,8 +177,8 @@ class MailHandlerTest < ActiveSupport::TestCase
assert !issue.new_record?
issue.reload
assert_equal 'New ticket with custom field values', issue.subject
assert_equal 'Value for a custom field',
issue.custom_value_for(CustomField.find_by_name('Searchable field')).value
assert_equal 'PostgreSQL', issue.custom_field_value(1)
assert_equal 'Value for a custom field', issue.custom_field_value(2)
assert !issue.description.match(/^searchable field:/i)
end
@@ -373,6 +373,80 @@ class MailHandlerTest < ActiveSupport::TestCase
assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest
end
def test_thunderbird_with_attachment_ja
issue = submit_email(
'thunderbird_with_attachment_ja.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
attachment = issue.attachments.first
assert_equal ja, attachment.filename
assert_equal 5, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 5, File.size(attachment.diskfile)
assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
end
def test_gmail_with_attachment_ja
issue = submit_email(
'gmail_with_attachment_ja.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
attachment = issue.attachments.first
assert_equal ja, attachment.filename
assert_equal 5, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 5, File.size(attachment.diskfile)
assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
end
def test_thunderbird_with_attachment_latin1
issue = submit_email(
'thunderbird_with_attachment_iso-8859-1.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
u = ""
u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
11.times { u << u1 }
attachment = issue.attachments.first
assert_equal "#{u}.png", attachment.filename
assert_equal 130, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 130, File.size(attachment.diskfile)
assert_equal '4d80e667ac37dddfe05502530f152abb', attachment.digest
end
def test_gmail_with_attachment_latin1
issue = submit_email(
'gmail_with_attachment_iso-8859-1.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
u = ""
u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
11.times { u << u1 }
attachment = issue.attachments.first
assert_equal "#{u}.txt", attachment.filename
assert_equal 5, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 5, File.size(attachment.diskfile)
assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
end
def test_add_issue_with_iso_8859_1_subject
issue = submit_email(
'subject_as_iso-8859-1.eml',
@@ -393,6 +467,15 @@ class MailHandlerTest < ActiveSupport::TestCase
assert_equal ja, issue.subject
end
def test_add_issue_with_no_subject_header
issue = submit_email(
'no_subject_header.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal '(no subject)', issue.subject
end
def test_add_issue_with_mixed_japanese_subject
issue = submit_email(
'subject_japanese_2.eml',

View File

@@ -28,17 +28,17 @@ class ProjectNestedSetTest < ActiveSupport::TestCase
@a2 = Project.create!(:name => 'A2', :identifier => 'projecta2')
@a2.set_parent!(@a)
@c = Project.create!(:name => 'C', :identifier => 'projectc')
@c1 = Project.create!(:name => 'C1', :identifier => 'projectc1')
@c1.set_parent!(@c)
@b = Project.create!(:name => 'B', :identifier => 'projectb')
@b2 = Project.create!(:name => 'B2', :identifier => 'projectb2')
@b2.set_parent!(@b)
@b1 = Project.create!(:name => 'B1', :identifier => 'projectb1')
@b1.set_parent!(@b)
@b11 = Project.create!(:name => 'B11', :identifier => 'projectb11')
@b11.set_parent!(@b1)
@b2 = Project.create!(:name => 'B2', :identifier => 'projectb2')
@b2.set_parent!(@b)
@c = Project.create!(:name => 'C', :identifier => 'projectc')
@c1 = Project.create!(:name => 'C1', :identifier => 'projectc1')
@c1.set_parent!(@c)
@a, @a1, @a2, @b, @b1, @b11, @b2, @c, @c1 = *(Project.all.sort_by(&:name))
end
@@ -47,6 +47,13 @@ class ProjectNestedSetTest < ActiveSupport::TestCase
assert_valid_nested_set
end
def test_rebuild_should_build_valid_tree
Project.update_all "lft = NULL, rgt = NULL"
Project.rebuild!
assert_valid_nested_set
end
def test_moving_a_child_to_a_different_parent_should_keep_valid_tree
assert_no_difference 'Project.count' do
Project.find_by_name('B1').set_parent!(Project.find_by_name('A2'))

View File

@@ -217,6 +217,40 @@ class RepositoryGitTest < ActiveSupport::TestCase
assert_equal h1, h2
end
def test_keep_extra_report_last_commit_in_clear_changesets
assert_nil @repository.extra_info
h = {}
h["extra_report_last_commit"] = "1"
@repository.merge_extra_info(h)
@repository.save
@project.reload
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets
@project.reload
assert_equal NUM_REV, @repository.changesets.count
@repository.send(:clear_changesets)
assert_equal 1, @repository.extra_info.size
assert_equal "1", @repository.extra_info["extra_report_last_commit"]
end
def test_refetch_after_clear_changesets
assert_nil @repository.extra_info
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets
@project.reload
assert_equal NUM_REV, @repository.changesets.count
@repository.send(:clear_changesets)
@project.reload
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets
@project.reload
assert_equal NUM_REV, @repository.changesets.count
end
def test_parents
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets