Index: app/controllers/issues_controller.rb
===================================================================
--- app/controllers/issues_controller.rb	(revision 3208)
+++ app/controllers/issues_controller.rb	(working copy)
@@ -111,6 +111,8 @@
     @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
     @priorities = IssuePriority.all
     @time_entry = TimeEntry.new
+    @custom_copies = CustomCopy.find(:all,
+      :conditions => "source_project_id=#{@issue.project.id} and source_tracker_id=#{@issue.tracker.id} and source_status_id=#{@issue.status.id}")
     respond_to do |format|
       format.html { render :template => 'issues/show.rhtml' }
       format.atom { render :action => 'changes', :layout => false, :content_type => 'application/atom+xml' }
@@ -276,6 +278,18 @@
   end
 
   def move
+    if (params[:custom_copy])
+       custom_copy = CustomCopy.find(params[:custom_copy])
+       redirect_to :controller => 'issues', :action => 'move', :id => params[:id],
+       :copy_options => {:copy => 't'},
+       :new_project_id => custom_copy.target_project_id,
+       :new_tracker_id => custom_copy.target_tracker_id,
+       :status_id => custom_copy.target_status_id,
+       :copied_status_id => custom_copy.source_post_status_id,
+       :follow => '1'
+    end
+    is_custom_copy = params[:new_project_id]
+
     @copy = params[:copy_options] && params[:copy_options][:copy]
     @allowed_projects = []
     # find projects to which the user is allowed to move the issue
@@ -289,7 +303,7 @@
     @target_project ||= @project    
     @trackers = @target_project.trackers
     @available_statuses = Workflow.available_statuses(@project)
-    if request.post?
+    if request.post? || is_custom_copy
       new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
       unsaved_issue_ids = []
       moved_issues = []
@@ -303,6 +317,18 @@
         issue.init_journal(User.current)
         if r = issue.move_to(@target_project, new_tracker, {:copy => @copy, :attributes => changed_attributes})
           moved_issues << r
+          if is_custom_copy && params[:copied_status_id]
+            copied_status = IssueStatus.find(params[:copied_status_id])
+            if copied_status && @available_statuses.include?(copied_status)
+              issue.status = copied_status
+              issue.save
+              relation = IssueRelation.new(params[:relation])
+              relation.issue_from    = issue
+              relation.issue_to      = r
+              relation.relation_type = IssueRelation::TYPE_RELATES
+              relation.save
+            end
+          end
         else
           unsaved_issue_ids << issue.id
         end
Index: app/models/custom_copy.rb
===================================================================
--- app/models/custom_copy.rb	(revision 0)
+++ app/models/custom_copy.rb	(revision 3208)
@@ -0,0 +1,27 @@
+# Redmine - project management software
+# Copyright (C) 2006-2009  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CustomCopy < ActiveRecord::Base
+   belongs_to :project, :foreign_key => 'source_project_id'
+   belongs_to :tracker, :foreign_key => 'source_tracker_id'
+   belongs_to :issue_status, :foreign_key => 'source_status_id'
+   belongs_to :issue_status, :foreign_key => 'source_post_status_id'
+   belongs_to :project, :foreign_key => 'target_project_id'
+   belongs_to :tracker, :foreign_key => 'target_tracker_id'
+   belongs_to :issue_status, :foreign_key => 'target_status_id'
+
+end
Index: app/views/issues/_action_menu.rhtml
===================================================================
--- app/views/issues/_action_menu.rhtml	(revision 3208)
+++ app/views/issues/_action_menu.rhtml	(working copy)
@@ -7,4 +7,9 @@
 <%= link_to_if_authorized l(:button_copy), {:controller => 'issues', :action => 'move', :id => @issue, :copy_options => {:copy => 't'} }, :class => 'icon icon-copy' %>
 <%= link_to_if_authorized l(:button_move), {:controller => 'issues', :action => 'move', :id => @issue }, :class => 'icon icon-move' %>
 <%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
+
+<% @custom_copies.each do |custom_copy| %>
+	<%= link_to_if_authorized h(custom_copy.label), {:controller => 'issues', :action => 'move', :id => @issue, :custom_copy => custom_copy.id }, :class => 'icon icon-copy' %>
+<% end %>
+
 </div>
Index: db/migrate/20091217215900_create_custom_copies.rb
===================================================================
--- db/migrate/20091217215900_create_custom_copies.rb	(revision 0)
+++ db/migrate/20091217215900_create_custom_copies.rb	(revision 3208)
@@ -0,0 +1,18 @@
+class CreateCustomCopies < ActiveRecord::Migration
+  def self.up
+    create_table :custom_copies do |t|
+      t.column :label, :string, :limit => 40, :default => "", :null => false
+      t.column :source_project_id, :integer, :null => false
+      t.column :source_tracker_id, :integer, :null => false
+      t.column :source_status_id,  :integer, :null => false
+      t.column :source_post_status_id,  :integer, :null => false
+      t.column :target_project_id, :integer, :null => false
+      t.column :target_tracker_id, :integer, :null => false
+      t.column :target_status_id,  :integer, :null => false
+    end
+  end
+
+  def self.down
+    drop_table :custom_copies
+  end
+end
