changeset 16:020926a36823 yuya

* Add redmine-checkout plugin (as of svn rev 179 of the plugin)
author Chris Cannam
date Wed, 25 Aug 2010 16:39:01 +0100
parents 9c6c72729d91
children cefbcad807b5
files vendor/plugins/redmine_checkout/README.rdoc vendor/plugins/redmine_checkout/Rakefile vendor/plugins/redmine_checkout/app/views/projects/settings/_repository_checkout.rhtml vendor/plugins/redmine_checkout/app/views/projects/settings/_repository_checkout_protocol.rhtml vendor/plugins/redmine_checkout/app/views/redmine_checkout_hooks/_view_repositories_show_contextual.rhtml vendor/plugins/redmine_checkout/app/views/settings/_checkout.rhtml vendor/plugins/redmine_checkout/app/views/settings/_checkout_protocol.rhtml vendor/plugins/redmine_checkout/app/views/settings/_checkout_scm.rhtml vendor/plugins/redmine_checkout/app/views/settings/_redmine_checkout.rhtml vendor/plugins/redmine_checkout/assets/images/ZeroClipboard.as vendor/plugins/redmine_checkout/assets/images/ZeroClipboard.swf vendor/plugins/redmine_checkout/assets/images/button.svg vendor/plugins/redmine_checkout/assets/images/button_focus.svg vendor/plugins/redmine_checkout/assets/images/button_selected.svg vendor/plugins/redmine_checkout/assets/images/paste.png vendor/plugins/redmine_checkout/assets/javascripts/ZeroClipboard.js vendor/plugins/redmine_checkout/assets/javascripts/checkout.js vendor/plugins/redmine_checkout/assets/javascripts/subform.js vendor/plugins/redmine_checkout/assets/stylesheets/checkout.css vendor/plugins/redmine_checkout/assets/stylesheets/checkout_alternate.css vendor/plugins/redmine_checkout/config/locales/de.yml vendor/plugins/redmine_checkout/config/locales/en.yml vendor/plugins/redmine_checkout/config/locales/es.yml vendor/plugins/redmine_checkout/config/locales/fr.yml vendor/plugins/redmine_checkout/config/locales/it.yml vendor/plugins/redmine_checkout/config/locales/ja.yml vendor/plugins/redmine_checkout/config/locales/ko.yml vendor/plugins/redmine_checkout/config/locales/nl.yml vendor/plugins/redmine_checkout/config/locales/pl.yml vendor/plugins/redmine_checkout/config/locales/ro.yml vendor/plugins/redmine_checkout/db/migrate/20091208210439_add_checkout_url_info.rb vendor/plugins/redmine_checkout/db/migrate/20091220173312_add_display_login.rb vendor/plugins/redmine_checkout/db/migrate/20100118174556_add_render_link.rb vendor/plugins/redmine_checkout/db/migrate/20100118235845_remove_defaults.rb vendor/plugins/redmine_checkout/db/migrate/20100118235909_add_overwrite_option.rb vendor/plugins/redmine_checkout/db/migrate/20100203202320_update_settings.rb vendor/plugins/redmine_checkout/db/migrate/20100426154202_rename_render_link_to_render_type.rb vendor/plugins/redmine_checkout/db/migrate/20100512135418_consolidate_repository_options.rb vendor/plugins/redmine_checkout/db/migrate/20100609153630_apply_setting_changes.rb vendor/plugins/redmine_checkout/db/migrate/20100808185600_change_protocol_storage_from_hash_to_array.rb vendor/plugins/redmine_checkout/doc/COPYING vendor/plugins/redmine_checkout/init.rb vendor/plugins/redmine_checkout/lib/checkout/protocol.rb vendor/plugins/redmine_checkout/lib/checkout/repositories_helper_patch.rb vendor/plugins/redmine_checkout/lib/checkout/repository_hooks.rb vendor/plugins/redmine_checkout/lib/checkout/repository_patch.rb vendor/plugins/redmine_checkout/lib/checkout/setting_patch.rb vendor/plugins/redmine_checkout/lib/checkout/settings_controller_patch.rb vendor/plugins/redmine_checkout/lib/checkout/settings_helper_patch.rb vendor/plugins/redmine_checkout/lib/checkout_helper.rb vendor/plugins/redmine_checkout/lib/tasks/set_default.rake vendor/plugins/redmine_checkout/lib/tasks/spec.rake vendor/plugins/redmine_checkout/spec/controllers/repositories_controller_spec.rb vendor/plugins/redmine_checkout/spec/fixtures/enabled_modules.yml vendor/plugins/redmine_checkout/spec/fixtures/projects.yml vendor/plugins/redmine_checkout/spec/fixtures/repositories.yml vendor/plugins/redmine_checkout/spec/fixtures/roles.yml vendor/plugins/redmine_checkout/spec/fixtures/settings.yml vendor/plugins/redmine_checkout/spec/macros/macro_spec.rb vendor/plugins/redmine_checkout/spec/models/protocol_spec.rb vendor/plugins/redmine_checkout/spec/models/repository_spec.rb vendor/plugins/redmine_checkout/spec/models/setting_spec.rb vendor/plugins/redmine_checkout/spec/sanity_spec.rb vendor/plugins/redmine_checkout/spec/spec.opts vendor/plugins/redmine_checkout/spec/spec_helper.rb
diffstat 65 files changed, 2915 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/README.rdoc	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,43 @@
+= Redmine Checkout plugin
+
+Author:: Holger Just
+URL:: http://dev.holgerjust.de/projects/redmine-checkout
+
+This plugin to Redmine adds a link to the actual repository to the GUI.
+
+This plugin includes ZeroClipboard[http://code.google.com/p/zeroclipboard/]
+by Joseph Huckaby. This software is licensed under the
+{GNU Lesser General Public License}[http://www.gnu.org/licenses/lgpl.html].
+
+Copyright (c) 2009, 2010 Holger Just
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+= Installation
+
+The installation follows the standard installation path from
+http://www.redmine.org/projects/redmine/wiki/Plugins
+
+1. Copy the software to the vendor/plugins directory. Make sure that the name
+   of the directory is redmine_checkout.
+2. Run rake db:migrate_plugins RAILS_ENV=production
+3. Restart Redmine
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/Rakefile	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,10 @@
+#!/usr/bin/env ruby
+require 'redmine_plugin_support'
+ 
+Dir[File.expand_path(File.dirname(__FILE__)) + "/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
+ 
+RedminePluginSupport::Base.setup do |plugin|
+  plugin.project_name = 'redmine_checkout'
+  plugin.default_task = [:spec]
+  plugin.tasks = [:doc, :release, :clean, :spec, :stats]
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/app/views/projects/settings/_repository_checkout.rhtml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,54 @@
+<p><%= form.select(:checkout_overwrite, [
+    [l(:general_text_Yes), "1"],
+    [l(:general_text_No), "0"]
+  ],
+  {},
+  :onchange => <<-EOF
+    Effect.toggle($('checkout_settings'), 'slide', {duration:0.2});
+  EOF
+  )%></p>
+
+<div id="checkout_settings" <%= 'style="display:none;"' unless form.object.checkout_overwrite? %>><fieldset>
+  <legend><%=l :label_checkout %></legend>
+  
+  <p><%= form.text_area :checkout_description, :cols => 60, :rows => 5, :class => 'wiki-edit', :label => :field_description %></p>
+  <%= wikitoolbar_for 'repository_checkout_description' %>
+  
+  <% if form.object.scm_name == 'Subversion' %>
+  <p><%= form.select :checkout_display_login,[
+            [l(:label_display_login_none), ''],
+            [l(:label_display_login_username), 'username'],
+            [l(:label_display_login_password), 'password']
+          ],
+          :label => :setting_checkout_display_login %></p>
+  <% end %>
+  
+  <p><%= form.check_box :checkout_display_command %></p>
+  
+  <% javascript_tag do %>
+    protocolForm = new Subform(
+      '<%= escape_javascript(render(:partial => "projects/settings/repository_checkout_protocol", :locals => {:protocol => Checkout::Protocol.new({:protocol => form.object.scm_name, :append_path => form.object.allow_subtree_checkout? ? 1: 0, :repository => form.object})})) %>',
+      <%= form.object.checkout_protocols.length %>,
+      'checkout_protocol_table'
+    );
+  <% end %>
+  <p><label><%=l :label_protocol_plural %></label><%=l :help_repository_checkout_protocols %></p>
+  <%= hidden_field_tag 'repository[checkout_protocols][-1][protocol]', 'empty' %>
+  <table class="list checkout_protocol_table">
+    <thead><tr>
+      <th class="protocol_protocol"   ><%= l(:setting_protocol)%></th>
+      <th class="protocol_command"    ><%= l(:setting_checkout_command)%></th>
+      <th class="protocol_fixed_url"  ><%= l(:setting_checkout_fixed_url) %></th>
+      <th class="protocol_access"     ><%= l(:label_permissions) %></th>
+      <th class="protocol_append_path"><%= l(:label_append_path) %></th>
+      <th class="protocol_is_default" ><%= l(:label_default) %></th>
+      <th class="protocol_delete"     ></th>
+    </tr></thead>
+    <tbody id="checkout_protocol_table">
+      <% form.object.checkout_protocols.each_with_index do |protocol, index| %>
+        <%= render :partial => 'projects/settings/repository_checkout_protocol', :locals => {:protocol => protocol, :index => index, :classes => cycle('odd', 'even')} %>
+      <% end %>
+    </tbody>
+  </table>
+  <div style="text-align: right"><%= link_to_function l(:button_add_protocol), "protocolForm.add()", {:class => "icon icon-add"} %></div>
+</fieldset></div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/app/views/projects/settings/_repository_checkout_protocol.rhtml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,18 @@
+<%
+  index ||= "--INDEX--"
+  classes ||= ""
+  
+  protocol = Checkout::Protocol.new(protocol) unless protocol.is_a? Checkout::Protocol
+%>
+<tr id="<%= "checkout_protocols_#{index}" %>" class="<%= classes %>" <%= 'style="display:none"' if index == '--INDEX--' %>>
+  <td class="protocol_protocol"><%= text_field_tag "repository[checkout_protocols][#{index}][protocol]", protocol.protocol, :size => 10 %></td>
+  <td class="protocol_command"><%= text_field_tag "repository[checkout_protocols][#{index}][command]", protocol.command, :size => 15 %></td>
+  <td class="protocol_fixed_url"><%= text_field_tag "repository[checkout_protocols][#{index}][fixed_url]", protocol.fixed_url, :size => 60 %></td>
+  <td class="protocol_access"><%= select_tag "repository[checkout_protocols][#{index}][access]", options_for_select([
+    [l(:label_access_read_write), 'read+write'],
+    [l(:label_access_read_only), 'read-only'],
+    [l(:label_access_permission), 'permission']], protocol.access) %></td>
+  <td class="protocol_append_path"><%= check_box_tag "repository[checkout_protocols][#{index}][append_path]", 1, protocol.append_path? %></td>
+  <td class="protocol_is_default"><%= check_box_tag "repository[checkout_protocols][#{index}][is_default]", 1, protocol.default? %></td>
+  <td class="protocol_delete"><%= image_to_function 'delete.png', "var e=$('checkout_protocols_#{index}');var parent=e.up(\"tbody\");e.remove();recalculate_even_odd(parent);return false" %></td>
+</tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/app/views/redmine_checkout_hooks/_view_repositories_show_contextual.rhtml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,36 @@
+<div class="repository-info">
+  <% if repository.checkout_description.present? %>
+  <div class="wiki<%= ' bottomline' if protocols.present? %>"><%= textilizable repository.checkout_description %></div>
+  <% end %>
+  <% if protocols.present? %>
+  <div id="checkout_box">
+    <ul id="checkout_protocols">
+    <% protocols.each do |p| -%>
+      <li>
+        <a <%= 'class="selected"' if p == default_protocol %> id="checkout_protocol_<%= p.protocol.to_s.underscore %>" data-permission="<%= p.access_rw(User.current) %>" href="<%= URI.escape p.url(checkout_path) %>"><%=h p.protocol %></a>
+      </li>
+    <% end -%>
+    </ul>
+    <%= text_field_tag :checkout_url, h(default_protocol.full_command(checkout_path)), :readonly => true %>
+    <%- if Setting.checkout_use_zero_clipboard? %>
+    <div id="clipboard_container" title="<%= l(:label_copy_to_clipboard) %>" style="display: none;">
+       <div id="clipboard_button"><%= image_tag 'paste.png', :plugin => 'redmine_checkout' %></div>
+    </div>
+    <% end -%>
+    <% if default_protocol %><p><%=l :label_access_type, :type => l(default_protocol.access_label(User.current)) %></p><% end %>
+  
+    <% javascript_tag do %>
+      var checkout_access   = $H({<%= protocols.inject([]){|r,p| r << "'checkout_protocol_#{p.protocol.to_s.underscore}': '#{l(p.access_label(User.current))}'"}.join(', ') %>});
+      var checkout_commands = $H({<%= protocols.inject([]){|r,p| r << "'checkout_protocol_#{p.protocol.to_s.underscore}': '#{escape_javascript(p.full_command(checkout_path))}'"}.join(', ') %>});
+      <%- if Setting.checkout_use_zero_clipboard? %>ZeroClipboard.setMoviePath( '<%= image_path('ZeroClipboard.swf', :plugin => 'redmine_checkout') %>' );<% end %>
+    <% end %>
+  </div>
+  <% end%>
+</div>
+<div style="clear: left"></div>
+
+<% content_for :header_tags do %>
+  <%= stylesheet_link_tag 'checkout', :plugin => 'redmine_checkout' %>
+  <%= javascript_include_tag 'checkout', :plugin => 'redmine_checkout' %>
+  <%= (javascript_include_tag 'ZeroClipboard', :plugin => 'redmine_checkout') if Setting.checkout_use_zero_clipboard? %>
+<% end %>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/app/views/settings/_checkout.rhtml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,43 @@
+<% form_tag({:action => 'edit', :tab => 'checkout'}) do %>
+
+<% javascript_tag do %>
+protocolForms = $H();
+
+document.observe("dom:loaded", function() {
+  $('tab-content-checkout').select('fieldset.collapsed').each(function(e){
+    e.down('div').hide();
+  });
+  <%
+    CheckoutHelper.supported_scm.select{|scm| Setting.enabled_scm.include?(scm)}.each do |scm| 
+      next if Setting.send("checkout_overwrite_description_#{scm}?")
+  -%>
+  $('settings_checkout_description_<%= scm %>').up('div').up('div').hide();
+  <%- end %>
+});
+<% end %>
+
+
+<div class="box tabular settings">
+<p><%= setting_check_box :checkout_display_checkout_info %></p>
+
+<p><%= setting_text_area :checkout_description_Abstract, :cols => 60, :rows => 5, :class => 'wiki-edit', :label => :field_description %></p>
+<%= wikitoolbar_for 'settings_checkout_description_Abstract' %>
+
+<p><%= setting_check_box :checkout_use_zero_clipboard %></p>
+
+<% CheckoutHelper.supported_scm.select{|scm| Setting.enabled_scm.include?(scm)}.each do |scm| -%>
+<fieldset class="collapsible collapsed">
+  <legend onclick="toggleFieldset(this);"><%= "Repository::#{scm}".constantize.scm_name %></legend>
+  <div><%= render :partial => 'checkout_scm', :locals => {:scm => scm} %></div>
+</fieldset>
+<%- end %>
+
+</div>
+
+<%= submit_tag l(:button_save) %>
+<%- end %>
+
+<% content_for :header_tags do %>
+  <%= javascript_include_tag 'subform', :plugin => 'redmine_checkout' %>
+  <%= stylesheet_link_tag 'checkout', :plugin => 'redmine_checkout' %>
+<% end %>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/app/views/settings/_checkout_protocol.rhtml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,19 @@
+<%
+  index ||= "--INDEX--"
+  classes ||= ""
+  
+  protocol = Checkout::Protocol.new(protocol) unless protocol.is_a? Checkout::Protocol
+%>
+<tr id="<%= "checkout_protocols_#{scm}_#{index}" %>" class="<%= classes %>" <%= 'style="display:none"' if index == '--INDEX--' %>>
+  <td class="protocol_protocol"         ><%= text_field_tag "settings[checkout_protocols_#{scm}][#{index}][protocol]", protocol.protocol, :size => 10 %></td>
+  <td class="protocol_command"          ><%= text_field_tag "settings[checkout_protocols_#{scm}][#{index}][command]", protocol.command, :size => 15 %></td>
+  <td class="protocol_regex"            ><%= text_field_tag "settings[checkout_protocols_#{scm}][#{index}][regex]", protocol.regex, :size => 30 %></td>
+  <td class="protocol_regex_replacement"><%= text_field_tag "settings[checkout_protocols_#{scm}][#{index}][regex_replacement]", protocol.regex_replacement, :size => 30 %></td>
+  <td class="protocol_access"           ><%= select_tag "settings[checkout_protocols_#{scm}][#{index}][access]", options_for_select([
+    [l(:label_access_read_write), 'read+write'],
+    [l(:label_access_read_only), 'read-only'],
+    [l(:label_access_permission), 'permission']], protocol.access) %></td>
+  <td class="protocol_append_path"><%= check_box_tag "settings[checkout_protocols_#{scm}][#{index}][append_path]", 1, protocol.append_path? %></td>
+  <td class="protocol_is_default"><%= check_box_tag "settings[checkout_protocols_#{scm}][#{index}][is_default]", 1, protocol.default? %></td>
+  <td class="protocol_delete"><%= image_to_function 'delete.png', "var e=$('checkout_protocols_#{scm}_#{index}');var parent=e.up(\"tbody\");e.remove();recalculate_even_odd(parent);return false" %></td>
+</tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/app/views/settings/_checkout_scm.rhtml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,46 @@
+<div>
+  <p><%= setting_check_box "checkout_overwrite_description_#{scm}", :label => :setting_checkout_overwrite_description, :onclick => <<-EOF
+    Effect.toggle($('settings_checkout_description_#{scm}').up("div").up("div"), 'slide', {duration:0.2});
+  EOF
+  %></p>
+  
+  <div>
+    <p><%= setting_text_area "checkout_description_#{scm}", :cols => 60, :rows => 5, :class => 'wiki-edit', :label => :field_description %></p>
+    <%= wikitoolbar_for "settings_checkout_description_#{scm}" %>
+  </div>
+  
+  <% if scm == 'Subversion' %>
+  <p><%= setting_select "checkout_display_login",[
+            [l(:label_display_login_username), 'username'],
+            [l(:label_display_login_password), 'password']
+          ],
+          :blank => :label_display_login_none %></p>
+  <% end %>
+  
+  <p><%= setting_check_box "checkout_display_command_#{scm}", :label => :field_checkout_display_command %></p>
+
+  <% javascript_tag do %>
+    <% repo = "Repository::#{scm}".constantize %>
+    var subform = new Subform('<%= escape_javascript(render(:partial => "checkout_protocol", :locals => {:protocol => Checkout::Protocol.new({:protocol => repo.scm_name, :append_path => (repo.allow_subtree_checkout? ? '1' : '0'), :command => repo.checkout_default_command}), :scm => scm})) %>',<%= Setting.send("checkout_protocols_#{scm}").length %>,'settings_checkout_protocols_<%= scm %>');
+    protocolForms.set('<%= scm %>', subform);
+  <% end %>
+  <p><label><%=l :label_protocol_plural %></label><%=l :help_checkout_protocols %></p>
+  <table class="list checkout_protocol_table">
+    <thead><tr>
+      <th class="protocol_protocol"         ><%= l(:setting_protocol)%></th>
+      <th class="protocol_command"          ><%= l(:setting_checkout_command)%></th>
+      <th class="protocol_regex"            ><%= l(:setting_checkout_url_regex) %></th>
+      <th class="protocol_regex_replacement"><%= l(:setting_checkout_url_regex_replacement) %></th>
+      <th class="protocol_access"           ><%= l(:label_permissions) %></th>
+      <th class="protocol_append_path"      ><%= l(:label_append_path) %></th>
+      <th class="protocol_is_default"       ><%= l(:label_default) %></th>
+      <th class="protocol_delete"           ></th>
+    </tr></thead>
+    <tbody id="settings_checkout_protocols_<%= scm %>">
+      <% Setting.send("checkout_protocols_#{scm}").each_with_index do |protocol, index| %>
+        <%= render :partial => 'checkout_protocol', :locals => {:protocol => Checkout::Protocol.new(protocol), :scm => scm, :index => index, :classes => cycle('odd', 'even')} %>
+      <% end %>
+    </tbody>
+  </table>
+  <div style="text-align: right"><%= link_to_function l(:button_add_protocol), "protocolForms.get('#{scm}').add()", {:class => "icon icon-add"} %></div>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/app/views/settings/_redmine_checkout.rhtml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,1 @@
+<%=l(:help_moved_settings, :link => link_to(l(:label_settings_location), {:controller => 'settings', :action => 'index', :tab => 'checkout'})) %>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/images/ZeroClipboard.as	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,81 @@
+package {
+	// Simple Set Clipboard System
+	// Author: Joseph Huckaby
+	
+	import flash.display.Stage;
+	import flash.display.Sprite;
+	import flash.display.LoaderInfo;
+	import flash.display.StageScaleMode;
+	import flash.events.*;
+	import flash.display.StageAlign;
+	import flash.display.StageScaleMode;
+	import flash.external.ExternalInterface;
+	import flash.system.Security;
+	import flash.utils.*;
+	import flash.system.System;
+ 
+	public class ZeroClipboard extends Sprite {
+		
+		private var id:String = '';
+		private var button:Sprite;
+		private var clipText:String = '';
+		
+		public function ZeroClipboard() {
+			// constructor, setup event listeners and external interfaces
+			stage.scaleMode = StageScaleMode.EXACT_FIT;
+			flash.system.Security.allowDomain("*");
+			
+			// import flashvars
+			var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;
+			id = flashvars.id;
+			
+			// invisible button covers entire stage
+			button = new Sprite();
+			button.buttonMode = true;
+			button.useHandCursor = true;
+			button.graphics.beginFill(0xCCFF00);
+			button.graphics.drawRect(0, 0, Math.floor(flashvars.width), Math.floor(flashvars.height));
+			button.alpha = 0.0;
+			addChild(button);
+			button.addEventListener(MouseEvent.CLICK, clickHandler);
+			
+			button.addEventListener(MouseEvent.MOUSE_OVER, function(event:Event) {
+				ExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseOver', null );
+			} );
+			button.addEventListener(MouseEvent.MOUSE_OUT, function(event:Event) {
+				ExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseOut', null );
+			} );
+			button.addEventListener(MouseEvent.MOUSE_DOWN, function(event:Event) {
+				ExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseDown', null );
+			} );
+			button.addEventListener(MouseEvent.MOUSE_UP, function(event:Event) {
+				ExternalInterface.call( 'ZeroClipboard.dispatch', id, 'mouseUp', null );
+			} );
+			
+			// external functions
+			ExternalInterface.addCallback("setHandCursor", setHandCursor);
+			ExternalInterface.addCallback("setText", setText);
+			
+			// signal to the browser that we are ready
+			ExternalInterface.call( 'ZeroClipboard.dispatch', id, 'load', null );
+		}
+		
+		public function setText(newText) {
+			// set the maximum number of files allowed
+			clipText = newText;
+		}
+		
+		public function setHandCursor(enabled:Boolean) {
+			// control whether the hand cursor is shown on rollover (true)
+			// or the default arrow cursor (false)
+			button.useHandCursor = enabled;
+		}
+		
+		private function clickHandler(event:Event):void {
+			// user click copies text to clipboard
+			// as of flash player 10, this MUST happen from an in-movie flash click event
+			System.setClipboard( clipText );
+			ExternalInterface.call( 'ZeroClipboard.dispatch', id, 'complete', clipText );
+		}
+	}
+}
Binary file vendor/plugins/redmine_checkout/assets/images/ZeroClipboard.swf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/images/button.svg	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <linearGradient id="gradient" x1="100%" y1="100%">
+      <stop offset="0%" style="stop-color:#ddd; stop-opacity:1" />
+      <stop offset="100%" style="stop-color:#f8f8f8; stop-opacity:1" />
+    </linearGradient>
+  </defs>
+  <rect width="100%" height="100%" style="fill:url(#gradient)"/>
+</svg>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/images/button_focus.svg	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <linearGradient id="gradient" x1="100%" y1="100%">
+      <stop offset="0%" style="stop-color:#507AAA; stop-opacity:1" />
+      <stop offset="100%" style="stop-color:#759fcf; stop-opacity:1" />
+    </linearGradient>
+  </defs>
+  <rect width="100%" height="100%" style="fill:url(#gradient)"/>
+</svg>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/images/button_selected.svg	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <linearGradient id="gradient" x1="100%" y1="100%">
+      <stop offset="0%" style="stop-color:#aaa; stop-opacity:1" />
+      <stop offset="100%" style="stop-color:#ccc; stop-opacity:1" />
+    </linearGradient>
+  </defs>
+  <rect width="100%" height="100%" style="fill:url(#gradient)"/>
+</svg>
\ No newline at end of file
Binary file vendor/plugins/redmine_checkout/assets/images/paste.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/javascripts/ZeroClipboard.js	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,311 @@
+// Simple Set Clipboard System
+// Author: Joseph Huckaby
+
+var ZeroClipboard = {
+	
+	version: "1.0.7",
+	clients: {}, // registered upload clients on page, indexed by id
+	moviePath: 'ZeroClipboard.swf', // URL to movie
+	nextId: 1, // ID of next movie
+	
+	$: function(thingy) {
+		// simple DOM lookup utility function
+		if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
+		if (!thingy.addClass) {
+			// extend element with a few useful methods
+			thingy.hide = function() { this.style.display = 'none'; };
+			thingy.show = function() { this.style.display = ''; };
+			thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
+			thingy.removeClass = function(name) {
+				var classes = this.className.split(/\s+/);
+				var idx = -1;
+				for (var k = 0; k < classes.length; k++) {
+					if (classes[k] == name) { idx = k; k = classes.length; }
+				}
+				if (idx > -1) {
+					classes.splice( idx, 1 );
+					this.className = classes.join(' ');
+				}
+				return this;
+			};
+			thingy.hasClass = function(name) {
+				return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
+			};
+		}
+		return thingy;
+	},
+	
+	setMoviePath: function(path) {
+		// set path to ZeroClipboard.swf
+		this.moviePath = path;
+	},
+	
+	dispatch: function(id, eventName, args) {
+		// receive event from flash movie, send to client		
+		var client = this.clients[id];
+		if (client) {
+			client.receiveEvent(eventName, args);
+		}
+	},
+	
+	register: function(id, client) {
+		// register new client to receive events
+		this.clients[id] = client;
+	},
+	
+	getDOMObjectPosition: function(obj, stopObj) {
+		// get absolute coordinates for dom element
+		var info = {
+			left: 0, 
+			top: 0, 
+			width: obj.width ? obj.width : obj.offsetWidth, 
+			height: obj.height ? obj.height : obj.offsetHeight
+		};
+
+		while (obj && (obj != stopObj)) {
+			info.left += obj.offsetLeft;
+			info.top += obj.offsetTop;
+			obj = obj.offsetParent;
+		}
+
+		return info;
+	},
+	
+	Client: function(elem) {
+		// constructor for new simple upload client
+		this.handlers = {};
+		
+		// unique ID
+		this.id = ZeroClipboard.nextId++;
+		this.movieId = 'ZeroClipboardMovie_' + this.id;
+		
+		// register client with singleton to receive flash events
+		ZeroClipboard.register(this.id, this);
+		
+		// create movie
+		if (elem) this.glue(elem);
+	}
+};
+
+ZeroClipboard.Client.prototype = {
+	
+	id: 0, // unique ID for us
+	ready: false, // whether movie is ready to receive events or not
+	movie: null, // reference to movie object
+	clipText: '', // text to copy to clipboard
+	handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
+	cssEffects: true, // enable CSS mouse effects on dom container
+	handlers: null, // user event handlers
+	
+	glue: function(elem, appendElem, stylesToAdd) {
+		// glue to DOM element
+		// elem can be ID or actual DOM element object
+		this.domElement = ZeroClipboard.$(elem);
+		
+		// float just above object, or zIndex 99 if dom element isn't set
+		var zIndex = 99;
+		if (this.domElement.style.zIndex) {
+			zIndex = parseInt(this.domElement.style.zIndex, 10) + 1;
+		}
+		
+		if (typeof(appendElem) == 'string') {
+			appendElem = ZeroClipboard.$(appendElem);
+		}
+		else if (typeof(appendElem) == 'undefined') {
+			appendElem = document.getElementsByTagName('body')[0];
+		}
+		
+		// find X/Y position of domElement
+		var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem);
+		
+		// create floating DIV above element
+		this.div = document.createElement('div');
+		var style = this.div.style;
+		style.position = 'absolute';
+		style.left = '' + box.left + 'px';
+		style.top = '' + box.top + 'px';
+		style.width = '' + box.width + 'px';
+		style.height = '' + box.height + 'px';
+		style.zIndex = zIndex;
+		
+		if (typeof(stylesToAdd) == 'object') {
+			for (addedStyle in stylesToAdd) {
+				style[addedStyle] = stylesToAdd[addedStyle];
+			}
+		}
+		
+		// style.backgroundColor = '#f00'; // debug
+		
+		appendElem.appendChild(this.div);
+		
+		this.div.innerHTML = this.getHTML( box.width, box.height );
+	},
+	
+	getHTML: function(width, height) {
+		// return HTML for movie
+		var html = '';
+		var flashvars = 'id=' + this.id + 
+			'&width=' + width + 
+			'&height=' + height;
+			
+		if (navigator.userAgent.match(/MSIE/)) {
+			// IE gets an OBJECT tag
+			var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
+			html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
+		}
+		else {
+			// all other browsers get an EMBED tag
+			html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
+		}
+		return html;
+	},
+	
+	hide: function() {
+		// temporarily hide floater offscreen
+		if (this.div) {
+			this.div.style.left = '-2000px';
+		}
+	},
+	
+	show: function() {
+		// show ourselves after a call to hide()
+		this.reposition();
+	},
+	
+	destroy: function() {
+		// destroy control and floater
+		if (this.domElement && this.div) {
+			this.hide();
+			this.div.innerHTML = '';
+			
+			var body = document.getElementsByTagName('body')[0];
+			try { body.removeChild( this.div ); } catch(e) {;}
+			
+			this.domElement = null;
+			this.div = null;
+		}
+	},
+	
+	reposition: function(elem) {
+		// reposition our floating div, optionally to new container
+		// warning: container CANNOT change size, only position
+		if (elem) {
+			this.domElement = ZeroClipboard.$(elem);
+			if (!this.domElement) this.hide();
+		}
+		
+		if (this.domElement && this.div) {
+			var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
+			var style = this.div.style;
+			style.left = '' + box.left + 'px';
+			style.top = '' + box.top + 'px';
+		}
+	},
+	
+	setText: function(newText) {
+		// set text to be copied to clipboard
+		this.clipText = newText;
+		if (this.ready) this.movie.setText(newText);
+	},
+	
+	addEventListener: function(eventName, func) {
+		// add user event listener for event
+		// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
+		eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+		if (!this.handlers[eventName]) this.handlers[eventName] = [];
+		this.handlers[eventName].push(func);
+	},
+	
+	setHandCursor: function(enabled) {
+		// enable hand cursor (true), or default arrow cursor (false)
+		this.handCursorEnabled = enabled;
+		if (this.ready) this.movie.setHandCursor(enabled);
+	},
+	
+	setCSSEffects: function(enabled) {
+		// enable or disable CSS effects on DOM container
+		this.cssEffects = !!enabled;
+	},
+	
+	receiveEvent: function(eventName, args) {
+		// receive event from flash
+		eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+				
+		// special behavior for certain events
+		switch (eventName) {
+			case 'load':
+				// movie claims it is ready, but in IE this isn't always the case...
+				// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
+				this.movie = document.getElementById(this.movieId);
+				if (!this.movie) {
+					var self = this;
+					setTimeout( function() { self.receiveEvent('load', null); }, 1 );
+					return;
+				}
+				
+				// firefox on pc needs a "kick" in order to set these in certain cases
+				if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
+					var self = this;
+					setTimeout( function() { self.receiveEvent('load', null); }, 100 );
+					this.ready = true;
+					return;
+				}
+				
+				this.ready = true;
+				this.movie.setText( this.clipText );
+				this.movie.setHandCursor( this.handCursorEnabled );
+				break;
+			
+			case 'mouseover':
+				if (this.domElement && this.cssEffects) {
+					this.domElement.addClass('hover');
+					if (this.recoverActive) this.domElement.addClass('active');
+				}
+				break;
+			
+			case 'mouseout':
+				if (this.domElement && this.cssEffects) {
+					this.recoverActive = false;
+					if (this.domElement.hasClass('active')) {
+						this.domElement.removeClass('active');
+						this.recoverActive = true;
+					}
+					this.domElement.removeClass('hover');
+				}
+				break;
+			
+			case 'mousedown':
+				if (this.domElement && this.cssEffects) {
+					this.domElement.addClass('active');
+				}
+				break;
+			
+			case 'mouseup':
+				if (this.domElement && this.cssEffects) {
+					this.domElement.removeClass('active');
+					this.recoverActive = false;
+				}
+				break;
+		} // switch eventName
+		
+		if (this.handlers[eventName]) {
+			for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
+				var func = this.handlers[eventName][idx];
+			
+				if (typeof(func) == 'function') {
+					// actual function reference
+					func(this, args);
+				}
+				else if ((typeof(func) == 'object') && (func.length == 2)) {
+					// PHP style object + method, i.e. [myObject, 'myMethod']
+					func[0][ func[1] ](this, args);
+				}
+				else if (typeof(func) == 'string') {
+					// name of function
+					window[func](this, args);
+				}
+			} // foreach event handler defined
+		} // user defined handler for event
+	}
+	
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/javascripts/checkout.js	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,33 @@
+document.observe("dom:loaded", function() {
+  /* update the checkout URL if clicked on a protocol */
+  $('checkout_protocols').select('a').each(function(e) {
+    e.observe('click', function(event) {
+      $('checkout_url').value = checkout_commands.get(this.id);
+      $('checkout_protocols').select('a').each(function(e) {
+        e.removeClassName("selected");
+      });
+      this.addClassName("selected")
+      
+      var value = checkout_access.get(this.id);
+      $('checkout_access').innerHTML = value;
+      
+      event.stop();
+    });
+  });
+  /* select the text field contents if activated */
+  Event.observe('checkout_url', 'click', function(event) {
+   this.activate();
+  });
+
+  if (typeof('ZeroClipboard') != 'undefined') {
+    $('clipboard_container').show();
+    clipboard = new ZeroClipboard.Client();
+    clipboard.setHandCursor( true );
+    clipboard.glue('clipboard_button', 'clipboard_container');
+
+    clipboard.addEventListener('mouseOver', function (client) {
+      clipboard.setText( $('checkout_url').value );
+    });
+  }
+});
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/javascripts/subform.js	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,45 @@
+var Subform = Class.create({
+  lineIndex: 1,
+  parentElement: "",
+  initialize: function(rawHTML, lineIndex, parentElement) {
+    this.rawHTML        = rawHTML;
+    this.lineIndex      = lineIndex;
+    this.parentElement  = parentElement;
+  },
+  
+  parsedHTML: function() {
+    return this.rawHTML.replace(/--INDEX--/g, this.lineIndex++);
+  },
+  
+  add: function() {
+    var e = $(this.parentElement);
+    Element.insert(e, { bottom: this.parsedHTML()});
+    Effect.toggle(e.childElements().last(), 'slide', {duration:0.2});
+    recalculate_even_odd(e);
+  },
+  
+  add_after: function(e) {
+    Element.insert(e, { after: this.parsedHTML()});
+    Effect.toggle(e.next(), 'slide', {duration:0.2});
+    recalculate_even_odd($(this.parentElement));
+  },
+  
+  add_on_top: function() {
+    var e = $(this.parentElement);
+    Element.insert(e, { top: this.parsedHTML()});
+    Effect.toggle(e.childElements().first(), 'slide', {duration:0.2});
+    recalculate_even_odd(e);
+  }
+});
+
+function recalculate_even_odd(element) {
+  $A(element.childElements()).inject(
+    0,
+    function(acc, e)
+    {
+      e.removeClassName("even");
+      e.removeClassName("odd");
+      e.addClassName( (acc%2==0) ? "odd" : "even"); return ++acc;
+    }
+  )
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/stylesheets/checkout.css	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,162 @@
+/* Uncomment the following line for nicer tables if you use the alternate theme (or derived). */
+/* @import url(checkout_alternate.css); */
+
+table.checkout_protocol_table td { padding-right: 6px; vertical-align: middle; /* Double the border with of text input boxes */ }
+table.checkout_protocol_table td.protocol_access { padding-right: 0; }
+table.checkout_protocol_table td input[type=text], .checkout_protocol_table td select { width: 100%; }
+table.checkout_protocol_table td.protocol_delete { width: 16px; }
+table.checkout_protocol_table td.protocol_append_path, table.checkout_protocol_table td.protocol_is_default { text-align: center; }
+
+.icon-changeset { background-image: url(../../../images/changeset.png);}
+
+.repository-info {
+  background-color: #eee;
+  border: 1px solid #E4E4E4;
+  padding: 0 10px;
+  margin: 4px 0 10px;
+}
+
+.bottomline {
+  border-bottom: 1px solid #ccc;
+}
+
+#checkout_box {
+  margin: 10px 0;
+}
+
+#checkout_protocols {
+  height: 23px;
+  float: left;
+  margin: 0;
+  padding: 0;
+}
+
+#checkout_protocols li {
+  float: left;
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+}
+
+#checkout_protocols li:first-child a {
+  border-left-width: 1px;
+  
+  /* Standard, Opera 10, IE 9 */
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
+  /* Konquerer */
+  -khtml-border-top-left-radius: 3px;
+  -khtml-border-bottom-left-radius: 3px;
+  /* Gecko (Firefox, ...) */
+  -moz-border-radius: 3px 0 0 3px;
+  /* Webkit (Chrome, Safari, ...) */
+  -webkit-border-top-left-radius: 3px;
+  -webkit-border-bottom-left-radius: 3px;
+  /* IE <= 9 not supported */
+}
+
+#checkout_protocols li a,
+#clipboard_button {
+  background-color: #eee;
+  background:  url(../images/button.svg) 0 0 no-repeat; /* Opera  needs an "image" :( - using svg for this so it will scale properly without looking too ugly */
+  background: -khtml-gradient(linear, left top, left bottom, from(#f8f8f8), to(#ddd)); /* Konquerer */
+  background: -moz-linear-gradient(top,  #f8f8f8,  #ddd); /* Gecko (Firefox, ...) */
+  background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#ddd));   /* Webkit (Chrome, Safari, ...) */
+  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#dddddd'); /* IE 5.5 - 7 */
+  -ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#dddddd'); /* IE 8 */
+  
+  border-color: #bbb;
+  border-style: solid;
+  border-width: 1px 1px 1px 0;
+  
+  color: #333;
+  display: block;
+  font-size: 11px;
+  font-weight: bold;
+  line-height: 21px;
+  margin: 0;
+  padding: 0 10px 0 11px;
+  text-decoration: none;
+  text-shadow: 1px 1px 0 #fff;
+  position: relative; /* to please IE */
+}
+
+#checkout_protocols li a:hover,
+#checkout_protocols li a:focus {
+  background-color: #507AAA;
+  background:  url(../images/button_focus.svg) 0 0 no-repeat; /* Opera  needs an "image" :( - using svg for this so it will scale properly without looking too ugly */
+  background: -khtml-gradient(linear, left top, left bottom, from(#759fcf), to(#507AAA)); /* Konquerer */
+  background: -moz-linear-gradient(top,  #759fcf,  #507AAA); /* Gecko (Firefox, ...) */
+  background: -webkit-gradient(linear, left top, left bottom, from(#759fcf), to(#507AAA)); /* Webkit (Chrome, Safari, ...) */
+  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#759fcf', endColorstr='#507AAA'); /* IE 5.5 - IE 7 */
+  -ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#759fcf', endColorstr='#507AAA'); /* IE 8 */
+  
+  color: #fff;
+  text-shadow: -1px -1px 0 rgba(0,0,0,0.4);
+  border-top-color: #759fcf;
+  border-bottom-color: #507AAA;
+}
+
+#checkout_protocols li a.selected,
+#clipboard_button.active {
+  background-color: #bbb;
+  background:  url(../images/button_selected.svg) 0 0 no-repeat; /* Opera  needs an "image" :( - using svg for this so it will scale properly without looking too ugly */
+  background: -webkit-gradient(linear, left top, left bottom, from(#ccc), to(#aaa));  /* Konquerer */
+  background: -moz-linear-gradient(top,  #ccc,  #aaa); /* Gecko (Firefox, ...) */
+  background: -webkit-gradient(linear, left top, left bottom, from(#ccc), to(#aaa));  /* Webkit (Chrome, Safari, ...) */
+  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#aaaaaa'); /* IE 5.5 - IE 7 */
+  -ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#aaaaaa'); /* IE 8 */
+  
+  color: #000;
+  text-shadow: 1px 1px 0 rgba(255,255,255,0.4);
+  border-color: #bbb;
+}
+
+#checkout_url {
+  border: 1px solid #bbb;
+  border-width: 1px 1px 1px 0;
+  background-color: #fff;
+  color: #000;
+  font-size: 11px;
+  height: 16px;
+  padding: 3px 5px 2px;
+  width: 400px;
+  font-family: Monaco,"DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;
+  margin: 0 5px 0 0;
+  float: left;
+}
+
+#checkout_box p {
+  color: #666;
+  line-height: 23px;
+  font-size: 11px;
+  margin: 0 0 0 5px;
+}
+
+span#checkout_access {
+  font-weight: bold;
+}
+
+#clipboard_container {
+  position: relative;
+  float: left;
+  margin-right: 5px;
+}
+
+#clipboard_button {
+  height: 21px;
+  width: 23px;
+  padding: 0;
+  border-width: 1px;
+  text-align: center;
+  
+  border-radius: 5px; /* Standard, Opera 10, IE 9 */
+  -khtml-border-radius: 3px; /* Konquerer */
+  -moz-border-radius: 3px ; /* Gecko (Firefox, ...) */
+  -webkit-border-radius: 3px; /* Webkit (Chrome, Safari, ...) */
+  /* IE <= 9 not supported */
+}
+
+#clipboard_button img {
+  padding-top: 2px;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/assets/stylesheets/checkout_alternate.css	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,2 @@
+table.checkout_protocol_table td { padding-right: 10px !important; /* Double the border with of text input boxes */ }
+table.checkout_protocol_table td.protocol_access { padding-right: 2px !important; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/de.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,39 @@
+de:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Checkout-Informationen anzeigen"
+  setting_checkout_fixed_url: "Checkout-URL"
+  setting_checkout_url_regex: "Regulärer Ausdruck"
+  setting_checkout_url_regex_replacement: "Ersatztext"
+  setting_checkout_display_login: "Mitgliedsnamen anzeigen"
+  setting_checkout_command: "Checkout-Befehl"
+  setting_checkout_use_zero_clipboard: "Zwischenablagen-Helfer anzeigen"
+
+  setting_checkout_overwrite_description: "Standard-Beschreibung überschreiben"
+  field_checkout_overwrite: "Überschreibe Standardeinstellung für Checkout-Protokolle"
+  field_checkout_display_command: "Checkout-Befehl anzeigen"
+
+  label_protocol_plural: "Protokolle"
+  button_add_protocol: "Protokoll hinzufügen"
+
+  label_access_type: 'Diese URL erlaubt Zugriff zum <span id="checkout_access">{{type}}</span>.'
+  label_access_read_only: 'Nur-Lesen'
+  label_access_read_write: "Lesen+Schreiben"
+  label_access_permission: "Abhängig von Benutzer-Rechten"
+
+  label_append_path: "Pfad anhängen"
+
+  label_display_login_none: "Mitgliedsnamen nicht anzeigen"
+  label_display_login_username: "Mitgliedsnamen anzeigen, aber kein Kennwort"
+  label_display_login_password: "Mitgliedsnamen und Kennwort anzeigen"
+
+  label_copy_to_clipboard: "In die Zwischenablage kopieren"
+
+  help_checkout_protocols: |
+    Die URLs in Protokollen werden aus der originalen URL erzeugt, auf die der
+    reguläre Ausdruck und der Ersatztext angewendet werden. Der Ersatztext
+    erlaubt Rückwärtsreferenzen zu geklammerten Audrücken mit der \1 Notation.
+  help_repository_checkout_protocols: |
+    Lassen Sie das Checkout-URL-Feld leer um die URL des Projektarchivs zu verwenden.
+  help_moved_settings: "Die Konfigurationsseite wurde nach {{link}} verschoben."
+  label_settings_location: "Administration -> Konfiguration -> Checkout"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/en.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,39 @@
+en:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Display checkout information"
+  setting_checkout_fixed_url: "Checkout URL"
+  setting_checkout_url_regex: "Regular expression"
+  setting_checkout_url_regex_replacement: "Replacement text"
+  setting_checkout_display_login: "Display Login"
+  setting_checkout_command: "Checkout command"
+  setting_checkout_use_zero_clipboard: "Display clipboard helper"
+
+  setting_checkout_overwrite_description: "Overwrite default description"
+  field_checkout_overwrite: "Overwrite default settings for checkout protocols"
+  field_checkout_display_command: "Display checkout command"
+
+  label_protocol_plural: "Protocols"
+  button_add_protocol: "Add Protocol"
+
+  label_access_type: 'This URL has <span id="checkout_access">{{type}}</span> access.'
+  label_access_read_only: 'Read-Only'
+  label_access_read_write: "Read+Write"
+  label_access_permission: "Depending on user's permissions"
+
+  label_append_path: "Append path"
+
+  label_display_login_none: "Do not show login or password"
+  label_display_login_username: "Show login but no password"
+  label_display_login_password: "Show login and password"
+
+  label_copy_to_clipboard: "Copy to clipboard"
+
+  help_checkout_protocols: |
+    The URLs in protocols are generated from applying the regular expression
+    and the replacement text to the original URL. The replacement text
+    supports back-references to braced expressions using the \1 notation.
+  help_repository_checkout_protocols: |
+    Leave the Checkout URL field empty to use the defined repository URL.
+  help_moved_settings: "The settings page has been moved to {{link}}."
+  label_settings_location: "Administration -> Settings -> Checkout"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/es.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,39 @@
+es:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Display checkout information"
+  setting_checkout_fixed_url: "URL de checkout"
+  setting_checkout_url_regex: "Expresion regular"
+  setting_checkout_url_regex_replacement: "Texto de remplazo"
+  setting_checkout_display_login: "Mostrar usuario"
+  setting_checkout_command: "Comando de checkout"
+  setting_checkout_use_zero_clipboard: "Display clipboard helper"
+
+  setting_checkout_overwrite_description: "Overwrite default description"
+  field_checkout_overwrite: "Overwrite default settings for checkout protocols"
+  field_checkout_display_command: "Display checkout command"
+
+  label_protocol_plural: "Protocolos"
+  button_add_protocol: "Crear Protocolo"
+
+  label_access_type: 'This URL has <span id="checkout_access">{{type}}</span> access.'
+  label_access_read_only: 'Read-Only'
+  label_access_read_write: "Read+Write"
+  label_access_permission: "Depending on user's permissions"
+
+  label_append_path: "Append path"
+
+  label_display_login_none: "No mostrar usuario o contraseña"
+  label_display_login_username: "Mostrar usuario pero no contraseña"
+  label_display_login_password: "Mostrar usuario y contraseña"
+
+  label_copy_to_clipboard: "Copy to clipboard"
+
+  help_checkout_protocols: |
+    The URLs in protocols are generated from applying the regular expression
+    and the replacement text to the original URL. The replacement text
+    supports back-references to braced expressions using the \1 notation.
+  help_repository_checkout_protocols: |
+    Leave the Checkout URL field empty to use the defined repository URL.
+  help_moved_settings: "The settings page has been moved to {{link}}."
+  label_settings_location: "Administration -> Settings -> Checkout"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/fr.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,39 @@
+fr:
+  label_checkout: "Dépôt"
+
+  setting_checkout_display_checkout_info: "Display checkout information"
+  setting_checkout_fixed_url: "URL du dépôt"
+  setting_checkout_url_regex: "Expression Régulière"
+  setting_checkout_url_regex_replacement: "Texte de substitution"
+  setting_checkout_display_login: "Affiche le login"
+  setting_checkout_command: "Checkout command"
+  setting_checkout_use_zero_clipboard: "Display clipboard helper"
+
+  setting_checkout_overwrite_description: "Overwrite default description"
+  field_checkout_overwrite: "Overwrite default settings for checkout protocols"
+  field_checkout_display_command: "Affiche l'URL du dépôt"
+
+  label_protocol_plural: "Protocoles"
+  button_add_protocol: "Créer un protocole"
+
+  label_access_type: 'This URL has <span id="checkout_access">{{type}}</span> access.'
+  label_access_read_only: 'Read-Only'
+  label_access_read_write: "Read+Write"
+  label_access_permission: "Depending on user's permissions"
+
+  label_append_path: "Append path"
+
+  label_display_login_none: "Ne pas afficher le login ni le mot de passe"
+  label_display_login_username: "Afficher le login, pas le mot de passe"
+  label_display_login_password: "Afficher le login et le mot de passe"
+
+  label_copy_to_clipboard: "Copy to clipboard"
+
+  help_checkout_protocols: |
+    The URLs in protocols are generated from applying the regular expression
+    and the replacement text to the original URL. The replacement text
+    supports back-references to braced expressions using the \1 notation.
+  help_repository_checkout_protocols: |
+    Leave the Checkout URL field empty to use the defined repository URL.
+  help_moved_settings: "The settings page has been moved to {{link}}."
+  label_settings_location: "Administration -> Settings -> Checkout"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/it.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,40 @@
+it:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Visualizza le informazioni sul checkout"
+  setting_checkout_fixed_url: "URL di checkout"
+  setting_checkout_url_regex: "Espressione regolare"
+  setting_checkout_url_regex_replacement: "Testo sostituito"
+  setting_checkout_display_login: "Login visualizzato"
+  setting_checkout_command: "Comando per il checkout"
+  setting_checkout_use_zero_clipboard: "Visualizza l'utility per la copia negli appunti"
+
+  setting_checkout_overwrite_description: "Sovrascrivi la descrizione predefinita"
+  field_checkout_overwrite: "Sovrascrivi le impostazioni di checkout predefinite"
+  field_checkout_display_command: "Visualizza il comando per il checkout"
+
+  label_protocol_plural: "Protocolli"
+  button_add_protocol: "Aggiungi Protocollo"
+
+  label_access_type: 'Questo URL ha accesso <span id="checkout_access">{{type}}</span>.'
+  label_access_read_only: 'Sola-Lettura'
+  label_access_read_write: "Lettura+Scrittura"
+  label_access_permission: "Dipende dai permessi dell'utente"
+
+  label_append_path: "Aggiungi percorso"
+
+  label_display_login_none: "Non mostrare il login e password"
+  label_display_login_username: "Mostra il login senza password"
+  label_display_login_password: "Mostra il login e la password"
+
+  label_copy_to_clipboard: "Copia negli appunti"
+
+  help_checkout_protocols: |
+    Gli URL dei protocolli sono generati applicando le espressioni regolari
+    ed effettuando la sostituzione dell'URL originale con il testo specificato.
+    Il testo per la sostituzione può contenere riferimenti a più match usando
+    la notazione \1 \2...
+  help_repository_checkout_protocols: |
+    Lascia il campo URL di checkout bianco per usare l'URL definito nel repository.
+  help_moved_settings: "La pagina delle impostazioni è stata spostata in {{link}}."
+  label_settings_location: "Amministrazione -> Impostazioni -> Checkout"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/ja.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,39 @@
+ja:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Display checkout information"
+  setting_checkout_fixed_url: "チェックアウト URL"
+  setting_checkout_url_regex: "Regular expression"
+  setting_checkout_url_regex_replacement: "Replacement text"
+  setting_checkout_display_login: "ログインの表示"
+  setting_checkout_command: "Checkout command"
+  setting_checkout_use_zero_clipboard: "Display clipboard helper"
+
+  setting_checkout_overwrite_description: "Overwrite default description"
+  field_checkout_overwrite: "Overwrite default settings for checkout protocols"
+  field_checkout_display_command: "Display checkout command"
+
+  label_protocol_plural: "Protocols"
+  button_add_protocol: "Add Protocol"
+  
+  label_access_type: 'This URL has <span id="checkout_access">{{type}}</span> access.'
+  label_access_read_only: 'Read-Only'
+  label_access_read_write: "Read+Write"
+  label_access_permission: "Depending on user's permissions"
+
+  label_append_path: "Append path"
+
+  label_display_login_none: "ログインとパスワードを非表示"
+  label_display_login_username: "ログインのみ表示"
+  label_display_login_password: "ログインとパスワードを表示"
+
+  label_copy_to_clipboard: "Copy to clipboard"
+
+  help_checkout_protocols: |
+    The URLs in protocols are generated from applying the regular expression
+    and the replacement text to the original URL. The replacement text
+    supports back-references to braced expressions using the \1 notation.
+  help_repository_checkout_protocols: |
+    Leave the Checkout URL field empty to use the defined repository URL.
+  help_moved_settings: "The settings page has been moved to {{link}}."
+  label_settings_location: "Administration -> Settings -> Checkout"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/ko.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,40 @@
+ko:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Display checkout information"
+  setting_checkout_fixed_url: "체크 아웃 URL"
+  setting_checkout_url_regex: "정규식"
+  setting_checkout_url_regex_replacement: "대체 문자열"
+  setting_checkout_display_login: "로그인 표시"
+  setting_checkout_command: "Checkout command"
+  setting_checkout_use_zero_clipboard: "Display clipboard helper"
+  
+  setting_checkout_overwrite_description: "Overwrite default description"
+  field_checkout_overwrite: "Overwrite default settings for checkout protocols"
+  field_checkout_display_command: "Display checkout command"
+
+  label_protocol_plural: "Protocols"
+  button_add_protocol: "Add Protocol"
+
+  label_access_type: 'This URL has <span id="checkout_access">{{type}}</span> access.'
+  label_access_read_only: 'Read-Only'
+  label_access_read_write: "Read+Write"
+  label_access_permission: "Depending on user's permissions"
+
+  label_append_path: "Append path"
+
+  label_display_login_none: "로그인과 비밀번호를 보여주지 않습니다."
+  label_display_login_username: "로그인은 보여주지만 비밀번호는 보여주지 않습니다."
+  label_display_login_password: "로그인과 비밀번호를 보여줍니다."
+
+  label_copy_to_clipboard: "Copy to clipboard"
+
+  help_checkout_protocols: |
+    The URLs in protocols are generated from applying the regular expression
+    and the replacement text to the original URL. The replacement text
+    supports back-references to braced expressions using the \1 notation.
+  help_repository_checkout_protocols: |
+    Leave the Checkout URL field empty to use the defined repository URL.
+  help_moved_settings: "The settings page has been moved to {{link}}."
+  label_settings_location: "Administration -> Settings -> Checkout"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/nl.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,40 @@
+nl:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Checkout-informatie tonen"
+  setting_checkout_fixed_url: "Checkout-URL"
+  setting_checkout_url_regex: "Reguliere expressie"
+  setting_checkout_url_regex_replacement: "Vervangingstekst"
+  setting_checkout_display_login: "Geef login weer"
+  setting_checkout_command: "Checkout-opdracht"
+  setting_checkout_use_zero_clipboard: "Klembord-hulp tonen"
+
+  setting_checkout_overwrite_description: "Standaard omschrijving overschrijven"
+  field_checkout_overwrite: "Overschrijf standaard instellingen voor checkout-protocollen"
+  field_checkout_display_command: "Checkout-opdracht tonen"
+
+  label_protocol_plural: "Protocollen"
+  button_add_protocol: "Protocol toevoegen"
+
+  label_access_type: 'Deze URL heeft <span id="checkout_access">{{type}}</span> toegang.'
+  label_access_read_only: 'Alleen lezen'
+  label_access_read_write: "Lezen en schrijven"
+  label_access_permission: "Afhankelijk van gebruikersrechten"
+
+  label_append_path: "Pad toevoegen"
+
+  label_display_login_none: "Geen logingegevens tonen"
+  label_display_login_username: "Toon login zonder wachtwoord"
+  label_display_login_password: "Toon login en wachtwoord"
+
+  label_copy_to_clipboard: "Naar klembord kopiëren"
+
+  help_checkout_protocols: |
+    De URLs in protocollen worden samengesteld vanuit de originele URL, na
+    toepassing van de reguliere expressie en vervangingstekst. De vervangingstekst
+    ondersteunt referenties vanuit tussen haakjes geplaatste expressies
+    door middel van de \1 notatie.
+  help_repository_checkout_protocols: |
+    Laat het veld Checkout-URL leeg om de projectrepository te gebruiken.
+  help_moved_settings: "De instellingspagina is verplaatst naar {{link}}."
+  label_settings_location: "Administratie -> Instellingen -> Checkout"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/pl.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,39 @@
+pl:
+  label_checkout: "Pobieranie repozytorium"
+
+  setting_checkout_display_checkout_info: "Pokaż informację o możliwości pobrania repozytorium"
+  setting_checkout_fixed_url: "Adres URL pobierania repozytorium"
+  setting_checkout_url_regex: "Wyrażenie regularne"
+  setting_checkout_url_regex_replacement: "Wynikowy adres URL"
+  setting_checkout_display_login: "Pokaż dane logowania"
+  setting_checkout_command: "Komenda pobrania repozytorium"
+  setting_checkout_use_zero_clipboard: "Pokaż pomocnika schowka"
+
+  setting_checkout_overwrite_description: "Nadpisz domyślny opis"
+  field_checkout_overwrite: "Nadpisz domyślne ustawienia dla protokołów"
+  field_checkout_display_command: "Pokaż komendę pobrania repozytorium"
+
+  label_protocol_plural: "Protokoły"
+  button_add_protocol: "Dodaj protokół"
+
+  label_access_type: 'Ten adres URL ma dostęp <span id="checkout_access">{{type}}</span>.'
+  label_access_read_only: 'Tylko do odczytu'
+  label_access_read_write: "Odczyt+Zapis"
+  label_access_permission: "Zależne od uprawnień użytkownika"
+
+  label_append_path: "Dołącz ścieżkę"
+
+  label_display_login_none: "Nie pokazuj loginu ani hasła"
+  label_display_login_username: "Pokaż tylko login"
+  label_display_login_password: "Pokaż login i hasło"
+
+  label_copy_to_clipboard: "Kopiuj do schowka"
+
+  help_checkout_protocols: |
+    Wynikowe adresy URL w protokołach są generowane przez zamianę oryginalnego
+    adresu URL repozytorium na podstawie wyrażenia regularnego. Wynikowy adres
+    URL wspiera referencje do grup (tzw. back-references) używając notacji \1.
+  help_repository_checkout_protocols: |
+    Pozostaw adres URL pobierania repozytorium pusty aby uzyć adresu zdefiniowanego w ustawieniach projektu.
+  help_moved_settings: "Ustawienia zostały przeniesione do {{link}}."
+  label_settings_location: "Administracja -> Ustawienia -> Pobieranie repozytorium"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/config/locales/ro.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,39 @@
+ro:
+  label_checkout: "Checkout"
+
+  setting_checkout_display_checkout_info: "Display checkout information"
+  setting_checkout_fixed_url: "URL-ul pentru checkout"
+  setting_checkout_url_regex: "Expresie regulata (regexp)"
+  setting_checkout_url_regex_replacement: "Text inlocuitor (regexp)"
+  setting_checkout_display_login: "Arata datele pentru autentificare"
+  setting_checkout_command: "Comanda de checkout"
+  setting_checkout_use_zero_clipboard: "Display clipboard helper"
+
+  setting_checkout_overwrite_description: "Overwrite default description"
+  field_checkout_overwrite: "Overwrite default settings for checkout protocols"
+  field_checkout_display_command: "Display checkout command"
+
+  label_protocol_plural: "Protocols"
+  button_add_protocol: "Add Protocol"
+
+  label_access_type: 'This URL has <span id="checkout_access">{{type}}</span> access.'
+  label_access_read_only: 'Read-Only'
+  label_access_read_write: "Read+Write"
+  label_access_permission: "Depending on user's permissions"
+
+  label_append_path: "Append path"
+
+  label_display_login_none: "Nu afisa username sau parola"
+  label_display_login_username: "Afiseaza username-ul, dar nu si parola"
+  label_display_login_password: "Afiseaza atat username-ul, cat si parola"
+
+  label_copy_to_clipboard: "Copy to clipboard"
+
+  help_checkout_protocols: |
+    The URLs in protocols are generated from applying the regular expression
+    and the replacement text to the original URL. The replacement text
+    supports back-references to braced expressions using the \1 notation.
+  help_repository_checkout_protocols: |
+    Leave the Checkout URL field empty to use the defined repository URL.
+  help_moved_settings: "The settings page has been moved to {{link}}."
+  label_settings_location: "Administration -> Settings -> Checkout"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20091208210439_add_checkout_url_info.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,11 @@
+class AddCheckoutUrlInfo < ActiveRecord::Migration
+  def self.up
+    add_column :repositories, :checkout_url_type, :string, :default => 'none', :null => false
+    add_column :repositories, :checkout_url, :string, :default => '', :null => false
+  end
+
+  def self.down
+    remove_column :repository, :checkout_url_type
+    remove_column :repository, :checkout_url
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20091220173312_add_display_login.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,9 @@
+class AddDisplayLogin < ActiveRecord::Migration
+  def self.up
+    add_column :repositories, :display_login, :string, :default => 'none', :null => false
+  end
+
+  def self.down
+    remove_column :repositories, :display_login
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100118174556_add_render_link.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,9 @@
+class AddRenderLink < ActiveRecord::Migration
+  def self.up
+    add_column :repositories, :render_link, :boolean, :null => true
+  end
+  
+  def self.down
+    remove_column :repositories, :render_link
+  end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100118235845_remove_defaults.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,14 @@
+class RemoveDefaults < ActiveRecord::Migration
+  def self.up
+    change_column :repositories, :checkout_url_type, :string, :default => nil, :null => true
+    change_column :repositories, :checkout_url, :string, :default => nil, :null => true
+    change_column :repositories, :display_login, :string, :default => nil, :null => true
+  end
+  
+  def self.down
+    change_column :repositories, :checkout_url_type, :string, :default => 'none', :null => false
+    change_column :repositories, :checkout_url, :string, :default => '', :null => false
+    change_column :repositories, :display_login, :string, :default => 'none', :null => false
+  end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100118235909_add_overwrite_option.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,15 @@
+class AddOverwriteOption < ActiveRecord::Migration
+  def self.up
+    add_column :repositories, :checkout_url_overwrite, :boolean, :default => false, :null => false
+    
+    # existing repositories are set to overwrite the default settings
+    # This is to keep continuity of settings.
+    Repository.reset_column_information
+    Repository.update_all({:checkout_url_overwrite, true})
+  end
+  
+  def self.down
+    remove_column :repositories, :checkout_url_overwrite
+  end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100203202320_update_settings.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,36 @@
+class UpdateSettings < ActiveRecord::Migration
+  def self.up
+    settings = Setting.plugin_redmine_checkout
+    if settings['checkout_url_type'] == "overwritten"
+      settings['checkout_url_type'] = "generated"
+    end
+    
+    if settings.has_key? "checkout_url_regex"
+      settings['checkout_url_regex_default'] = settings.delete("checkout_url_regex")
+    end
+
+    if settings.has_key? "checkout_url_regex_replacement"
+      settings['checkout_url_regex_replacement_default'] = settings.delete("checkout_url_regex_replacement")
+    end
+    
+    Setting.plugin_redmine_checkout = settings
+  end
+  
+  def self.down
+    settings = Setting.plugin_redmine_checkout
+    if settings['checkout_url_type'] == "generated"
+      settings['checkout_url_type'] = "overwritten"
+    end
+    
+    if settings.has_key? "checkout_url_regex_default"
+      settings['checkout_url_regex'] = settings.delete("checkout_url_regex_default")
+    end
+
+    if settings.has_key? "checkout_url_regex_replacement_default"
+      settings['checkout_url_regex_replacement'] = settings.delete("checkout_url_regex_replacement_default")
+    end
+    
+    Setting.plugin_redmine_checkout = settings
+  end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100426154202_rename_render_link_to_render_type.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,31 @@
+class RenameRenderLinkToRenderType < ActiveRecord::Migration
+  def self.up
+    render_link = Setting.plugin_redmine_checkout.delete 'render_link'
+    unless  render_link.nil?
+      Setting.plugin_redmine_checkout['render_type'] = (render_link == 'true' ? 'link' : 'url')
+      Setting.plugin_redmine_checkout = Setting.plugin_redmine_checkout
+    end
+    
+    add_column :repositories, :render_type, :string, :default => 'url', :null => false
+    
+    Repository.update_all({:render_type => 'link'}, :render_link => true)
+    Repository.update_all({:render_type => 'url'}, ["render_link != ?", true])
+    
+    remove_column :repositories, :render_link
+  end
+  
+  def self.down
+    render_type = Setting.plugin_redmine_checkout.delete 'render_type'
+    unless  render_type.nil?
+      Setting.plugin_redmine_checkout['render_link'] = (render_type == 'link' ? 'true' : 'false')
+      Setting.plugin_redmine_checkout = Setting.plugin_redmine_checkout
+    end
+    
+    add_column :repositories, :render_link, :boolean, :null => true
+    
+    Repository.update_all({:render_link => true}, :render_type => 'link')
+    Repository.update_all({:render_link => false}, ["render_type != ?", 'link'])
+    
+    remove_column :repositories, :render_type
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100512135418_consolidate_repository_options.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,49 @@
+class ConsolidateRepositoryOptions < ActiveRecord::Migration
+  class Repository < ActiveRecord::Base
+    def self.inheritance_column
+      # disable single table inheritance
+      nil
+    end
+    
+    serialize :checkout_settings, Hash
+  end
+
+  def self.up
+    add_column :repositories, :checkout_settings, :text
+    
+    Repository.all.each do |r|
+      r.checkout_settings = {
+        "checkout_url_type" => r.checkout_url_type,
+        "checkout_url" => r.checkout_url,
+        "display_login" => r.display_login,
+        "render_type" => r.render_type,
+        "checkout_url_overwrite" => r.checkout_url_overwrite
+      }
+      r.save!
+    end
+    remove_column :repositories, :checkout_url_type
+    remove_column :repositories, :checkout_url
+    remove_column :repositories, :display_login
+    remove_column :repositories, :render_type
+    remove_column :repositories, :checkout_url_overwrite
+  end
+  
+  def self.down
+    add_column :repositories, :checkout_url_type, :string, :default => nil, :null => true
+    add_column :repositories, :checkout_url, :string, :default => nil, :null => true
+    add_column :repositories, :display_login, :string, :default => nil, :null => true
+    add_column :repositories, :render_type, :string, :default => 'url', :null => false
+    add_column :repositories, :checkout_url_overwrite, :boolean, :default => false, :null => false
+    
+    Repository.all.each do |r|
+      r.checkout_url_type = r.checkout_settings["checkout_url_type"]
+      r.checkout_url = r.checkout_settings["checkout_url"]
+      r.display_login = r.checkout_settings["display_login"]
+      r.render_link = r.checkout_settings["render_link"]
+      r.checkout_url_overwrite = r.checkout_settings["checkout_url_overwrite"]
+      r.save!
+    end
+    
+    remove_column :repositories, :checkout_settings
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100609153630_apply_setting_changes.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,113 @@
+class ApplySettingChanges < ActiveRecord::Migration
+  class Repository < ActiveRecord::Base
+    def self.inheritance_column
+      # disable single table inheritance
+      nil
+    end
+    
+    def scm_name
+      self.type || 'Abstract'
+    end
+    
+    serialize :checkout_settings, Hash
+  end
+  
+  def self.up
+    default_commands = {
+      'Bazaar' => 'bzr checkout',
+      'Cvs' => 'cvs checkout',
+      'Darcs' => 'darcs get',
+      'Git' => 'git clone',
+      'Mercurial' => 'hg clone',
+      'Subversion' => 'svn checkout'
+    }
+    
+    ## First migrate the individual repositories
+    
+    Repository.all.each do |r|
+      allow_subtree_checkout = ['Cvs', 'Subversion'].include? r.scm_name
+      
+      protocol = case r.checkout_settings['checkout_url_type']
+      when 'none', 'generated'
+        nil
+      when 'original', 'overwritten'
+        HashWithIndifferentAccess.new({ "0" => HashWithIndifferentAccess.new({
+          :protocol => r.scm_name,
+          :command => Setting.plugin_redmine_checkout["checkout_cmd_#{r.scm_name}"] || default_commands[r.scm_name],
+          :regex => "",
+          :regex_replacement => "",
+          :fixed_url => (r.checkout_settings['checkout_url_type'] == 'original' ? (r.url || "") : r.checkout_settings["checkout_url"]),
+          :access => 'permission',
+          :append_path => (allow_subtree_checkout ? '1' : '0'),
+          :is_default => '1'})
+        })
+      end
+      
+      r.checkout_settings = Hash.new({
+        'checkout_protocols' => protocol,
+        'checkout_description' => "The data contained in this repository can be downloaded to your computer using one of several clients.
+Please see the documentation of your version control software client for more information.
+
+Please select the desired protocol below to get the URL.",
+        'checkout_display_login' => (r.checkout_settings['display_login'] == 'none' ? '' : r.checkout_settings['display_login']),
+        'checkout_overwrite' => (r.checkout_settings['checkout_url_overwrite'] == 'true') ? '1': '0',
+        'checkout_display_command' => (r.checkout_settings["render_type"].to_s == 'cmd') ? '1' : '0'
+      })
+      r.save!
+    end
+    
+    ## Then the global settings
+    
+    settings = HashWithIndifferentAccess.new({
+      'display_login' => Setting.plugin_redmine_checkout['display_login'],
+      'use_zero_clipboard' => '1',
+
+      'display_checkout_info' => (Setting.plugin_redmine_checkout['checkout_url_type'] == 'none' ? '0' : '1'),
+      'description_Abstract' => <<-EOF
+The data contained in this repository can be downloaded to your computer using one of several clients.
+Please see the documentation of your version control software client for more information.
+
+Please select the desired protocol below to get the URL.
+EOF
+    })
+
+    default_commands.keys.each do |scm|
+      settings["description_#{scm}"] = ''
+      settings["overwrite_description_#{scm}"] = '0'
+      
+      display_command = (Setting.plugin_redmine_checkout["render_type"].to_s == 'cmd') ? '1' : '0'
+      settings["display_command_#{scm}"] = display_command
+      
+      case Setting.plugin_redmine_checkout['checkout_url_type']
+      when 'generated', 'none':
+        regex = Setting.plugin_redmine_checkout["checkout_url_regex_#{scm}"]
+        replacement = Setting.plugin_redmine_checkout["checkout_url_regex_replacement_#{scm}"]
+      when 'original':
+        regex = ''
+        replacement = ''
+      end
+      
+      settings["protocols_#{scm}"] = HashWithIndifferentAccess.new({
+        # access can be one of
+        #   read+write => this protocol always allows read/write access
+        #   read-only => this protocol always allows read access only
+        #   permission => Access depends on redmine permissions
+        '0' => HashWithIndifferentAccess.new({
+                :protocol => scm,
+                :command => Setting.plugin_redmine_checkout["checkout_cmd_#{scm}"] || default_commands[scm],
+                :regex => regex,
+                :regex_replacement => replacement,
+                :fixed_url => '',
+                :access => 'permission',
+                :append_path => (['Cvs', 'Subversion'].include?(scm) ? '1' : '0'),
+                :is_default => '1'
+               })
+      })
+    end
+    Setting.plugin_redmine_checkout = settings
+  end
+  
+  def self.down
+    raise ActiveRecord::IrreversibleMigration.new "Sorry, there is no down migration yet. If you really need one, please create an issue on http://dev.holgerjust.de/projects/redmine-checkout"
+  end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/db/migrate/20100808185600_change_protocol_storage_from_hash_to_array.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,57 @@
+class ChangeProtocolStorageFromHashToArray < ActiveRecord::Migration
+  class Repository < ActiveRecord::Base
+    def self.inheritance_column
+      # disable single table inheritance
+      nil
+    end
+    
+    def scm_name
+      self.type || 'Abstract'
+    end
+    
+    serialize :checkout_settings, Hash
+  end
+  
+  def self.up
+    ## First migrate the individual repositories
+    Repository.all.each do |r|
+      next unless r.checkout_settings['checkout_protocols'].is_a? Hash
+      r.checkout_settings['checkout_protocols'] = r.checkout_settings['checkout_protocols'].sort{|(ak,av),(bk,bv)|ak<=>bk}.collect{|id,protocol| protocol}
+      r.save!
+    end
+    
+    ## Then the global settings
+    settings = Setting.plugin_redmine_checkout
+    settings.keys.grep(/^protocols_/).each do |protocols|
+      next unless settings[protocols].is_a? Hash
+      settings[protocols] = settings[protocols].sort{|(ak,av),(bk,bv)|ak<=>bk}.collect{|id,protocol| protocol}
+    end
+    Setting.plugin_redmine_checkout = settings
+  end
+  
+  def self.down
+    ## First migrate the individual repositories
+    Repository.all.each do |r|
+      next unless r.checkout_settings['checkout_protocols'].is_a? Hash
+      r.checkout_settings['checkout_protocols'] = r.checkout_settings['checkout_protocols'].inject(HashWithIndifferentAccess.new) do |result, p|
+        result[result.length.to_s] = p
+      end
+      r.save!
+    end
+
+    ## Then the global settings
+    settings = Setting.plugin_redmine_checkout
+    settings.keys.grep(/^protocols_/).each do |protocols|
+      next unless r.checkout_settings['checkout_protocols'].is_a? Hash
+      settings[protocols] = settings[protocols].inject(HashWithIndifferentAccess.new) do |result, p|
+        result[result.length.to_s] = p
+      end
+    end
+    Setting.plugin_redmine_checkout = settings
+    
+    
+    
+    
+    raise ActiveRecord::IrreversibleMigration.new "Sorry, there is no down migration yet. If you really need one, please create an issue on http://dev.holgerjust.de/projects/redmine-checkout"
+  end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/doc/COPYING	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,22 @@
+Copyright (c) 2009 Holger Just
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/init.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,102 @@
+require 'redmine'
+
+require 'dispatcher'
+Dispatcher.to_prepare do
+  # Patches
+  require_dependency 'checkout/settings_controller_patch'
+  
+  require_dependency 'checkout/repositories_helper_patch'
+  require_dependency 'checkout/repository_patch'
+  
+  require_dependency 'checkout/settings_helper_patch'
+  require_dependency 'checkout/setting_patch'
+end
+
+# Hooks
+require 'checkout/repository_hooks'
+
+Redmine::Plugin.register :redmine_checkout do
+  name 'Redmine Checkout plugin'
+  url 'http://dev.holgerjust.de/projects/redmine-checkout'
+  author 'Holger Just'
+  author_url 'http://meine-er.de'
+  description 'Add links to the actual repository to the repository view.'
+  version '0.5'
+  
+  requires_redmine :version_or_higher => '0.9'
+  
+  settings_defaults = HashWithIndifferentAccess.new({
+    'display_login' => nil,
+    'use_zero_clipboard' => '1',
+    
+    'display_checkout_info' =>  '1',
+    'description_Abstract' => <<-EOF
+The data contained in this repository can be downloaded to your computer using one of several clients.
+Please see the documentation of your version control software client for more information.
+
+Please select the desired protocol below to get the URL.
+EOF
+  })
+  
+  # this is needed for setting the defaults
+  require 'checkout/repository_patch'
+  
+  CheckoutHelper.supported_scm.each do |scm|
+    klazz = "Repository::#{scm}".constantize
+    
+    settings_defaults["description_#{scm}"] = ''
+    settings_defaults["overwrite_description_#{scm}"] = '0'
+    settings_defaults["display_command_#{scm}"] = '0'
+    
+    # access can be one of
+    #   read+write => this protocol always allows read/write access
+    #   read-only => this protocol always allows read access only
+    #   permission => Access depends on redmine permissions
+    settings_defaults["protocols_#{scm}"] = [HashWithIndifferentAccess.new({
+      :protocol => scm,
+      :command => klazz.checkout_default_command,
+      :regex => '',
+      :regex_replacement => '',
+      :fixed_url => '',
+      :access => 'permission',
+      :append_path => (klazz.allow_subtree_checkout? ? '1' : '0'),
+      :is_default => '1'
+    })]
+  end
+  
+  settings :default => settings_defaults, :partial => 'settings/redmine_checkout'
+  
+  Redmine::WikiFormatting::Macros.register do
+    desc <<-EOF
+Creates a checkout link to the actual repository. Example:
+
+  use the default checkout protocol !{{repository}}
+  or use a specific protocol !{{repository(SVN)}}
+  or use the checkout protocol of a specific specific project: !{{repository(projectname:SVN)}}"
+EOF
+
+    macro :repository do |obj, args|
+      proto = args.first
+      if proto.to_s =~ %r{^([^\:]+)\:(.*)$}
+        project_identifier, proto = $1, $2
+        project = Project.find_by_identifier(project_identifier) || Project.find_by_name(project_identifier)
+      else
+        project = @project
+      end
+      
+      if project && project.repository
+        protocols = project.repository.checkout_protocols.select{|p| p.access_rw(User.current)}
+        
+        if proto.present?
+          proto_obj = protocols.find{|p| p.protocol.downcase == proto.downcase}
+        else
+          proto_obj = protocols.find(&:default?) || protocols.first
+        end
+      end
+      raise "Checkout protocol #{proto} not found" unless proto_obj
+      
+      cmd = (project.repository.checkout_display_command? && proto_obj.command.present?) ? proto_obj.command.strip + " " : ""
+      cmd + link_to(proto_obj.url, proto_obj.url)
+    end
+  end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout/protocol.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,114 @@
+module Checkout
+  class <<self
+    def awesome?
+      # Yes, this plugin is awesome!
+      true
+    end
+  end
+  
+  class Protocol
+    attr_accessor :protocol, :regex, :regex_replacement, :access, :repository
+    attr_writer :default, :command, :fixed_url, :append_path
+    
+    
+    def initialize(args={})
+      args = args.dup
+      
+      @protocol = args.delete :protocol
+      @command = args.delete :command # optional, if not set the default from the repo is used
+      
+      # either a fixed url
+      @fixed_url = args.delete :fixed_url
+
+      # or a regex
+      @regex = args.delete :regex
+      @regex_replacement = args.delete :regex_replacement
+      
+      @access = args.delete :access
+      @append_path = args.delete :append_path
+      @default = args.delete :is_default
+      
+      @repository = args.delete :repository
+    end
+    
+    def full_command(path = "")
+      cmd = ""
+      if repository.checkout_display_command?
+        cmd = self.command.present? ? self.command.strip + " " : ""
+      end
+      cmd + URI.escape(self.url(path))
+    end
+    
+    def default?
+      @default.to_i > 0
+    end
+    
+    def command
+      @command || self.repository && self.repository.checkout_default_command || ""
+    end
+    
+    def append_path?
+      @append_path.to_i > 0
+    end
+    
+    def access_rw(user)
+      # reduces the three available access levels 'read+write', 'read-only' and 'permission'
+      # to 'read+write' and 'read-only' and nil (not allowed)
+
+      @access_rw ||= {}
+      return @access_rw[user] if @access_rw.key? user
+      @access_rw[user] = case access
+      when 'permission'
+        case
+        when user.allowed_to?(:commit_access, repository.project) && user.allowed_to?(:browse_repository, repository.project)
+          'read+write'
+        when user.allowed_to?(:browse_repository, repository.project)
+          'read-only'
+        else
+          nil
+        end
+      else
+        @access
+      end
+    end
+    
+    def access_label(user)
+      case access_rw(user)
+        when 'read+write': :label_access_read_write
+        when 'read-only': :label_access_read_only
+      end
+    end
+  
+    def fixed_url
+      @fixed_url.present? ? @fixed_url : begin
+        if (regex.blank? || regex_replacement.blank?)
+          repository.url
+        else
+          repository.url.gsub(Regexp.new(regex), regex_replacement)
+        end
+      end
+    rescue RegexpError
+      repository.url || ""
+    end
+
+    def url(path = "")
+      return "" unless repository
+      
+      url = fixed_url.sub(/\/+$/, "")
+      if repository.allow_subtree_checkout? && self.append_path? && path.present?
+        url = "#{url}/#{path}"
+      end
+      
+      if repository.checkout_display_login?
+        begin
+          uri = URI.parse url
+          (uri.user = repository.login) if repository.login
+          (uri.password = repository.password) if (repository.checkout_display_login == 'password' && repository.login && repository.password)
+          url = uri.to_s
+        rescue URI::InvalidURIError
+        end
+      end
+      url
+    end
+  end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout/repositories_helper_patch.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,34 @@
+require_dependency 'repositories_helper'
+
+module Checkout
+  module RepositoriesHelperPatch
+    def self.included(base) # :nodoc:
+      base.send(:include, InstanceMethods)
+
+      base.class_eval do
+        alias_method_chain :repository_field_tags, :checkout
+        alias_method_chain :scm_select_tag, :javascript
+      end
+    end
+  
+    module InstanceMethods
+      def repository_field_tags_with_checkout(form, repository)    
+        tags = repository_field_tags_without_checkout(form, repository) || ""
+        return tags if repository.class.name == "Repository"
+      
+        tags + @controller.send(:render_to_string, :partial => 'projects/settings/repository_checkout', :locals => {:form => form, :repository => repository, :scm => repository.scm_name})
+      end
+      
+      def scm_select_tag_with_javascript(*args)
+        content_for :header_tags do
+          javascript_include_tag('subform', :plugin => 'redmine_checkout') +
+          stylesheet_link_tag('checkout', :plugin => 'redmine_checkout')
+        end
+        scm_select_tag_without_javascript(*args)
+      end
+    end
+  end
+end
+
+RepositoriesHelper.send(:include, Checkout::RepositoriesHelperPatch)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout/repository_hooks.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,34 @@
+module Checkout
+  class RepositoryHooks < Redmine::Hook::ViewListener
+    # Renders the checkout URL
+    #
+    # Context:
+    # * :project => Current project
+    # * :repository => Current Repository
+    #
+    def view_repositories_show_contextual(context={})
+      if context[:repository].present? && Setting.checkout_display_checkout_info?
+        protocols = context[:repository].checkout_protocols.select do |p|
+          p.access_rw(User.current)
+        end
+        
+        path = context[:controller].instance_variable_get("@path")
+        if path && context[:controller].instance_variable_get("@entry")
+          # a single file is showing, so we return only the directory
+          path = File.dirname(path)
+        end
+        
+        default = protocols.find(&:default?) || protocols.first
+        
+        context.merge!({
+          :protocols => protocols,
+          :default_protocol => default,
+          :checkout_path => path
+        })
+      
+        options = {:partial => "redmine_checkout_hooks/view_repositories_show_contextual"}
+        context[:controller].send(:render_to_string, {:locals => context}.merge(options))
+      end
+    end
+  end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout/repository_patch.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,186 @@
+require_dependency 'repository'
+require_dependency 'checkout_helper'
+
+module Checkout
+  module RepositoryPatch
+    def self.included(base) # :nodoc:
+      base.extend(ClassMethods)
+      base.send(:include, InstanceMethods)
+      
+      base.class_eval do
+        unloadable
+        serialize :checkout_settings, Hash
+      end
+    end
+    
+    module ClassMethods
+      def allow_subtree_checkout?
+        # default implementation
+        false
+      end
+      
+      def checkout_default_command
+        # default implementation
+        ""
+      end
+    end
+    
+    module InstanceMethods
+      def after_initialize
+        self.checkout_settings ||= {}
+      end
+    
+      def checkout_overwrite=(value)
+        checkout_settings['checkout_overwrite'] = value
+      end
+    
+      def checkout_overwrite
+        (checkout_settings['checkout_overwrite'].to_i > 0) ? '1' : '0'
+      end
+
+      def checkout_overwrite?
+        self.scm_name != 'Abstract' && checkout_overwrite.to_i > 0
+      end
+    
+      def checkout_description=(value)
+        checkout_settings['checkout_description'] = value
+      end
+    
+      def checkout_description
+        if checkout_overwrite?
+          checkout_settings['checkout_description']
+        else
+          if CheckoutHelper.supported_scm.include?(scm_name) && Setting.send("checkout_overwrite_description_#{scm_name}?")
+            Setting.send("checkout_description_#{scm_name}")
+          else
+            Setting.send("checkout_description_Abstract")
+          end
+        end
+      end
+    
+      def checkout_protocols
+        @checkout_protocols ||= begin
+          if CheckoutHelper.supported_scm.include? scm_name
+            if checkout_overwrite?
+              protocols = checkout_settings['checkout_protocols'] || []
+            else
+              protocols = Setting.send("checkout_protocols_#{scm_name}") || []
+            end
+          else
+            protocols = []
+          end
+          
+          protocols.collect do |p|
+            Checkout::Protocol.new p.merge({:repository => self})
+          end
+        end
+      end
+    
+      def checkout_protocols=(value)
+        # value is an Array or a Hash
+        if value.is_a? Hash
+          value = value.dup.delete_if {|id, protocol| id.to_i < 0 }
+          value = value.sort{|(ak,av),(bk,bv)|ak<=>bk}.collect{|id,protocol| protocol}
+        end
+        
+        checkout_settings['checkout_protocols'] = value
+      end
+
+      def checkout_display_login
+        if checkout_overwrite? && self.scm_name == "Subversion"
+          result = checkout_settings['checkout_display_login']
+        else
+          result = Setting.checkout_display_login
+        end
+        (result.to_i > 0) ? '1' : '0'
+      end
+    
+      def checkout_display_login?
+        checkout_display_login.to_i > 0
+      end
+    
+      def checkout_display_login=(value)
+        value = nil unless self.scm_name == "Subversion"
+        checkout_settings['checkout_display_login'] = value
+      end
+      
+      def checkout_display_command?
+        checkout_display_command.to_i > 0
+      end
+      
+      def checkout_display_command=(value)
+        checkout_settings['checkout_display_command'] = value
+      end
+      
+      def checkout_display_command
+        if checkout_overwrite?
+          checkout_settings['checkout_display_command']
+        else
+          Setting.send("checkout_display_command_#{scm_name}")
+        end
+      end
+      
+      def allow_subtree_checkout?
+        self.class.allow_subtree_checkout?
+      end
+      
+      def checkout_default_command
+        self.class.checkout_default_command
+      end
+    end
+  end
+end
+
+Repository.send(:include, Checkout::RepositoryPatch)
+
+subtree_checkout_repos = ["Subversion", "Cvs"]
+commands = {
+  'Bazaar' => 'bzr checkout',
+  'Cvs' => 'cvs checkout',
+  'Darcs' => 'darcs get',
+  'Git' => 'git clone',
+  'Mercurial' => 'hg clone',
+  'Subversion' => 'svn checkout'
+}
+
+CheckoutHelper.supported_scm.each do |scm|
+  require_dependency "repository/#{scm.underscore}"
+  cls = Repository.const_get(scm)
+  
+  allow_subtree_checkout = ""
+  if subtree_checkout_repos.include? scm
+    allow_subtree_checkout = <<-EOS
+     def allow_subtree_checkout?
+        true
+      end
+    EOS
+  end
+  
+  checkout_command = ""
+  if commands[scm]
+    checkout_command = <<-EOS
+      def checkout_default_command
+        '#{commands[scm]}'
+      end
+    EOS
+  end
+  
+  class_mod = Module.new
+  class_mod.module_eval(<<-EOF
+    def self.included(base)
+      base.extend ChildClassMethods
+
+      base.class_eval do
+        unloadable
+        serialize :checkout_settings, Hash
+      end
+    end
+
+    module ChildClassMethods
+      #{allow_subtree_checkout}
+      #{checkout_command}
+    end
+  EOF
+  )
+  cls.send(:include, class_mod)
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout/setting_patch.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,75 @@
+require_dependency 'setting'
+
+module Checkout
+  module SettingPatch
+    def self.included(base) # :nodoc:
+      base.extend(ClassMethods)
+      
+      base.class_eval do
+        unloadable
+        
+        # Defines getter and setter for each setting
+        # Then setting values can be read using: Setting.some_setting_name
+        # or set using Setting.some_setting_name = "some value"
+        Redmine::Plugin.find(:redmine_checkout).settings[:default].keys.each do |name|
+          if name.start_with?('protocols_')
+            default = "[]"
+          else
+            default = <<-END_SRC
+              begin
+                default = Setting.available_settings['plugin_redmine_checkout']['default']['#{name}']
+                # perform a deep copy of the default
+                Marshal::load(Marshal::dump(default))
+              end
+            END_SRC
+          end
+          
+          src = <<-END_SRC
+            def self.checkout_#{name}
+              self.plugin_redmine_checkout[:#{name}] || #{default}
+            end
+
+            def self.checkout_#{name}?
+              self.checkout_#{name}.to_i > 0
+            end
+
+            def self.checkout_#{name}=(value)
+              setting = Setting.plugin_redmine_checkout
+              setting[:#{name}] = value
+              Setting.plugin_redmine_checkout = setting
+            end
+          END_SRC
+          class_eval src, __FILE__, __LINE__
+        end
+        
+        class <<self
+          alias_method :store_without_checkout, :[]=
+          alias_method :[]=, :store_with_checkout
+          
+          alias_method :retrieve_without_checkout, :[]
+          alias_method :[], :retrieve_with_checkout
+        end
+      end
+    end
+    
+    module ClassMethods
+      def store_with_checkout(name, value)
+        if name.to_s.starts_with? "checkout_"
+          self.send("#{name}=", value)
+        else
+          store_without_checkout(name, value)
+        end
+      end
+      
+      def retrieve_with_checkout(name)
+        if name.to_s.starts_with? "checkout_"
+          self.send("#{name}")
+        else
+          retrieve_without_checkout(name)
+        end
+      end
+    end
+  end
+end
+
+Setting.send(:include, Checkout::SettingPatch)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout/settings_controller_patch.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,44 @@
+require_dependency 'settings_controller'
+
+module Checkout
+  module SettingsControllerPatch
+    def self.included(base) # :nodoc:
+      base.send(:include, InstanceMethods)
+
+      base.class_eval do
+        unloadable
+      
+        alias_method_chain :edit, :checkout
+      end
+    end
+    
+    module InstanceMethods
+      def edit_with_checkout
+        if request.post? && params['tab'] == 'checkout'
+          if params[:settings] && params[:settings].is_a?(Hash)
+            settings = HashWithIndifferentAccess.new
+            (params[:settings] || {}).each do |name, value|
+              if name = name.to_s.slice(/checkout_(.+)/, 1)
+                case value
+                when Array
+                  # remove blank values in array settings
+                  value.delete_if {|v| v.blank? }
+                when Hash
+                  # change protocols hash to array.
+                  value = value.sort{|(ak,av),(bk,bv)|ak<=>bk}.collect{|id,protocol| protocol} if name.start_with? "protocols_"
+                end
+                settings[name.to_sym] = value
+              end
+            end
+                        
+            Setting.plugin_redmine_checkout = settings
+            params[:settings] = {}
+          end
+        end
+        edit_without_checkout
+      end
+    end
+  end
+end
+
+SettingsController.send(:include, Checkout::SettingsControllerPatch)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout/settings_helper_patch.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,23 @@
+require_dependency 'settings_helper'
+
+module Checkout
+  module SettingsHelperPatch
+    def self.included(base) # :nodoc:
+      base.send(:include, InstanceMethods)
+
+      base.class_eval do
+        alias_method_chain :administration_settings_tabs, :checkout
+      end
+    end
+  
+    module InstanceMethods
+      def administration_settings_tabs_with_checkout
+        tabs = administration_settings_tabs_without_checkout
+        tabs << {:name => 'checkout', :partial => 'settings/checkout', :label => :label_checkout}
+      end
+    end
+  end
+end
+
+SettingsHelper.send(:include, Checkout::SettingsHelperPatch)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/checkout_helper.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,7 @@
+module CheckoutHelper
+  class <<self
+    def supported_scm
+      Object.const_defined?("REDMINE_SUPPORTED_SCM") ? REDMINE_SUPPORTED_SCM : Redmine::Scm::Base.all
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/tasks/set_default.rake	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,10 @@
+namespace :redmine do
+  namespace :plugins do
+    namespace :redmine_checkout do
+      desc "Sets all repositories to inherit the default setting for the checkout URL."
+      task :set_default => :environment do
+        Repository.all.each{|r| r.update_attributes(:checkout_overwrite => "0")}
+      end
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/lib/tasks/spec.rake	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,14 @@
+begin
+  require "spec/rake/spectask"
+  namespace :spec do
+    namespace :plugins do
+      desc "Runs the examples for redmine_checkout"
+      Spec::Rake::SpecTask.new(:redmine_checkout) do |t|
+        t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
+        t.spec_files = FileList['vendor/plugins/redmine_checkout/spec/**/*_spec.rb']
+      end
+    end
+  end
+  task :spec => "spec:plugins:redmine_checkout"
+rescue LoadError
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/controllers/repositories_controller_spec.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,48 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe RepositoriesController do
+  fixtures :settings, :repositories, :projects, :roles, :users, :enabled_modules
+  integrate_views
+  
+  before(:each) do
+    Setting.default_language = 'en'
+    User.current = nil
+  end
+  
+  def get_repo
+    get :show, :id => 1
+  end
+  
+  it "should display the protocol selector" do
+    get_repo
+    response.should be_success
+    response.should render_template('show')
+    
+    response.should have_tag('ul#checkout_protocols') do
+      with_tag('a[id=?][href=?]', 'checkout_protocol_subversion', "file:///#{RAILS_ROOT.gsub(%r{config\/\.\.}, '')}/tmp/test/subversion_repository")
+      with_tag('a[id=?][href=?]', 'checkout_protocol_svn+ssh', 'svn+ssh://subversion_repository@svn.foo.bar/svn')
+    end
+  end
+  
+  it "should display the description" do
+    get_repo
+    response.should be_success
+    response.should render_template('show')
+    
+    response.should have_tag('div.repository-info', /Please select the desired protocol below to get the URL/)
+  end
+  
+  it 'should respect the use zero clipboard option' do
+    Setting.checkout_use_zero_clipboard = '1'
+    get_repo
+    response.should be_success
+    response.should render_template('show')
+    response.should have_tag('script[src*=?]', 'ZeroClipboard')
+
+    Setting.checkout_use_zero_clipboard = '0'
+    get_repo
+    response.should be_success
+    response.should render_template('show')
+    response.should_not have_tag('script[src*=]', 'ZeroClipboard')
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/fixtures/enabled_modules.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,5 @@
+---
+enabled_modules_001:
+  name: repository
+  project_id: 1
+  id: 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/fixtures/projects.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,13 @@
+--- 
+projects_001: 
+  created_on: 2006-07-19 19:13:59 +02:00
+  name: eCookbook
+  updated_on: 2006-07-19 22:53:01 +02:00
+  id: 1
+  description: Recipes management application
+  homepage: http://ecookbook.somenet.foo/
+  is_public: true
+  identifier: ecookbook
+  parent_id: 
+  lft: 1
+  rgt: 10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/fixtures/repositories.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,9 @@
+---
+svn: 
+  project_id: 1
+  url: file:///<%= RAILS_ROOT.gsub(%r{config\/\.\.}, '') %>/tmp/test/subversion_repository
+  id: 1
+  root_url: file:///<%= RAILS_ROOT.gsub(%r{config\/\.\.}, '') %>/tmp/test/subversion_repository
+  password: ""
+  login: ""
+  type: Subversion
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/fixtures/roles.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,187 @@
+--- 
+roles_001: 
+  name: Manager
+  id: 1
+  builtin: 0
+  permissions: |
+    --- 
+    - :add_project
+    - :edit_project
+    - :manage_members
+    - :manage_versions
+    - :manage_categories
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :manage_subtasks
+    - :add_issue_notes
+    - :move_issues
+    - :delete_issues
+    - :view_issue_watchers
+    - :add_issue_watchers
+    - :delete_issue_watchers
+    - :manage_public_queries
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :edit_time_entries
+    - :delete_time_entries
+    - :manage_news
+    - :comment_news
+    - :view_documents
+    - :manage_documents
+    - :view_wiki_pages
+    - :export_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :delete_wiki_pages_attachments
+    - :protect_wiki_pages
+    - :delete_wiki_pages
+    - :rename_wiki_pages
+    - :add_messages
+    - :edit_messages
+    - :delete_messages
+    - :manage_boards
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :manage_repository
+    - :view_changesets
+    - :manage_project_activities
+
+  position: 1
+roles_002: 
+  name: Developer
+  id: 2
+  builtin: 0
+  permissions: |
+    --- 
+    - :edit_project
+    - :manage_members
+    - :manage_versions
+    - :manage_categories
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :manage_subtasks
+    - :add_issue_notes
+    - :move_issues
+    - :delete_issues
+    - :view_issue_watchers
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :edit_own_time_entries
+    - :manage_news
+    - :comment_news
+    - :view_documents
+    - :manage_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :protect_wiki_pages
+    - :delete_wiki_pages
+    - :add_messages
+    - :edit_own_messages
+    - :delete_own_messages
+    - :manage_boards
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 2
+roles_003: 
+  name: Reporter
+  id: 3
+  builtin: 0
+  permissions: |
+    --- 
+    - :edit_project
+    - :manage_members
+    - :manage_versions
+    - :manage_categories
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :add_issue_notes
+    - :move_issues
+    - :view_issue_watchers
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :manage_news
+    - :comment_news
+    - :view_documents
+    - :manage_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :delete_wiki_pages
+    - :add_messages
+    - :manage_boards
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 3
+roles_004: 
+  name: Non member
+  id: 4
+  builtin: 1
+  permissions: |
+    --- 
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :add_issue_notes
+    - :move_issues
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :comment_news
+    - :view_documents
+    - :manage_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :add_messages
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 4
+roles_005: 
+  name: Anonymous
+  id: 5
+  builtin: 2
+  permissions: |
+    --- 
+    - :view_issues
+    - :add_issue_notes
+    - :view_gantt
+    - :view_calendar
+    - :view_time_entries
+    - :view_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :view_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 5
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/fixtures/settings.yml	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,115 @@
+---
+  settings:
+    name: plugin_redmine_checkout
+    value: |
+      --- !map:HashWithIndifferentAccess 
+      display_checkout_info: "1"
+      description_Abstract: |
+        The data contained in this repository can be downloaded to your computer using one of several clients.
+        Please see the documentation of your version control software client for more information.
+
+        Please select the desired protocol below to get the URL.
+      display_command_Bazaar: '1'
+      use_zero_clipboard: "1"
+
+      overwrite_description_Bazaar: "0"
+      description_Bazaar: ""
+      display_command_Bazaar: '1'
+      protocols_Bazaar: 
+        "0": !map:HashWithIndifferentAccess 
+          command: "bzr checkout"
+          regex: ""
+          regex_replacement: ""
+          read_write: readwrite
+          append_path: "0"
+          is_default: "1"
+          protocol: Bazaar
+      overwrite_description_Cvs: "0"
+      description_Cvs: ""
+      display_command_Cvs: '1'
+      protocols_Cvs: 
+        "0": !map:HashWithIndifferentAccess 
+          command: "cvs checkout"
+          regex: ""
+          regex_replacement: ""
+          read_write: readwrite
+          append_path: "0"
+          is_default: "1"
+          protocol: Cvs
+      overwrite_description_Darcs: "0"
+      description_Darcs: ""
+      display_command_Darcs: '1'
+      protocols_Darcs: 
+        "0": !map:HashWithIndifferentAccess 
+          command: "darcs get"
+          regex: ""
+          regex_replacement: ""
+          read_write: readwrite
+          append_path: "0"
+          is_default: "1"
+          protocol: Darcs
+      overwrite_description_Filesystem: "0"
+      description_Filesystem: ""
+      display_command_Filesystem: '1'
+      protocols_Filesystem: !map:HashWithIndifferentAccess 
+        "0": !map:HashWithIndifferentAccess 
+          command: ""
+          regex: ""
+          append_path: "0"
+          is_default: "1"
+          protocol: Filesystem
+          access: read+write
+          regex_replacement: ""
+      overwrite_description_Git: "0"
+      description_Git: ""
+      display_command_Git: '1'
+      protocols_Git: !map:HashWithIndifferentAccess 
+        "0": !map:HashWithIndifferentAccess 
+          command: "git clone"
+          regex: ""
+          append_path: "0"
+          is_default: "1"
+          protocol: Git
+          access: read+write
+          regex_replacement: ""
+      overwrite_description_Mercurial: "0"
+      description_Mercurial: ""
+      display_command_Mercurial: '1'
+      protocols_Mercurial: !map:HashWithIndifferentAccess 
+        "0": !map:HashWithIndifferentAccess 
+          command: "hg clone"
+          regex: ""
+          append_path: "0"
+          is_default: "1"
+          protocol: Mercurial
+          access: read+write
+          regex_replacement: ""
+      display_login: username
+      overwrite_description_Subversion: "0"
+      description_Subversion: ""
+      display_command_Subversion: '1'
+      protocols_Subversion: !map:HashWithIndifferentAccess 
+        "0": !map:HashWithIndifferentAccess 
+          command: "svn checkout"
+          regex: foo
+          append_path: "1"
+          is_default: "1"
+          protocol: Subversion
+          access: permission
+          regex_replacement: bar
+        "1": !map:HashWithIndifferentAccess 
+          command: "svn co"
+          regex: "^.*?([^/]+)/?$"
+          append_path: "1"
+          is_default: "0"
+          protocol: SVN+SSH
+          access: read-only
+          regex_replacement: svn+ssh://\1@svn.foo.bar/svn
+        "2": !map:HashWithIndifferentAccess 
+          command: "svn checkout"
+          append_path: "0"
+          is_default: "0"
+          regex: ""
+          protocol: Root
+          access: read+write
+          regex_replacement: ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/macros/macro_spec.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,55 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe "Macros" do
+  fixtures :settings, :repositories, :projects, :enabled_modules
+  
+  include ERB::Util
+  include ApplicationHelper
+  include ActionView::Helpers::TextHelper
+  include ActionView::Helpers::TagHelper
+  include ActionView::Helpers::UrlHelper
+
+  before(:each) do
+    Setting.checkout_display_command_Subversion = '0'
+    
+    @project = projects :projects_001
+  end
+  
+  
+  it "should display default checkout url" do
+    text = "{{repository}}"
+    
+    url = "file:///#{RAILS_ROOT.gsub(%r{config\/\.\.}, '')}/tmp/test/subversion_repository"
+    textilizable(text).should eql "<p><a href=\"#{url}\">#{url}</a></p>"
+  end
+
+  it "should display forced checkout url" do
+    text = "{{repository(svn+ssh)}}"
+    
+    url = 'svn+ssh://subversion_repository@svn.foo.bar/svn'
+    textilizable(text).should eql "<p><a href=\"#{url}\">#{url}</a></p>"
+  end
+
+  it "should fail without set project" do
+    @project = nil
+    
+    text = "{{repository(svn+ssh)}}"
+    textilizable(text).should eql "<p><div class=\"flash error\">Error executing the <strong>repository</strong> macro (Checkout protocol svn+ssh not found)</div></p>"
+  end
+
+  it "should display checkout url from stated project" do
+    @project = nil
+    text = "{{repository(ecookbook:svn+ssh)}}"
+    
+    url = 'svn+ssh://subversion_repository@svn.foo.bar/svn'
+    textilizable(text).should eql "<p><a href=\"#{url}\">#{url}</a></p>"
+  end
+  
+  it "should display command" do
+    Setting.checkout_display_command_Subversion = '1'
+    
+    text = "{{repository(svn+ssh)}}"
+    url = 'svn+ssh://subversion_repository@svn.foo.bar/svn'
+    textilizable(text).should eql "<p>svn co <a href=\"#{url}\">#{url}</a></p>"
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/models/protocol_spec.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,36 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe Checkout::Protocol do
+  fixtures :settings, :repositories, :projects, :enabled_modules
+  
+  before(:each) do
+    @admin = User.new
+    @admin.admin = true
+    @user = User.new
+    
+    @repo = repositories :svn
+    @repo.url = "http://example.com/svn/testrepo"
+  end
+  
+  it "should use regexes for generated URL" do
+    protocol = @repo.checkout_protocols.find{|r| r.protocol == "SVN+SSH"}
+    protocol.url.should eql "svn+ssh://testrepo@svn.foo.bar/svn"
+  end
+  
+  it "should resolve access properties" do
+    protocol = @repo.checkout_protocols.find{|r| r.protocol == "Subversion"}
+    protocol.access.should eql "permission"
+    protocol.access_rw(@admin).should eql "read+write"
+    
+    User.current = @user
+    protocol.access_rw(@user).should eql "read-only"
+  end
+  
+  it "should display the checkout command" do
+    subversion = @repo.checkout_protocols.find{|r| r.protocol == "Subversion"}
+    svn_ssh = @repo.checkout_protocols.find{|r| r.protocol == "SVN+SSH"}
+
+    subversion.command.should eql "svn checkout"
+    svn_ssh.command.should eql "svn co"
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/models/repository_spec.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,49 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe Repository do
+  fixtures :settings, :repositories
+  
+  describe "initialize" do
+    before(:each) do
+      @repo = Repository.new()
+    end
+
+    it "should properly set default values" do
+      @repo.checkout_overwrite?.should be_false
+      @repo.checkout_description.should match /Please select the desired protocol below to get the URL/
+      @repo.checkout_display_login?.should be_false # no subversion repo
+      @repo.allow_subtree_checkout?.should be_false
+      @repo.checkout_protocols.should eql []
+    end
+  end
+  
+  describe "subtree checkout" do
+    before(:each) do
+      @svn = Repository::Subversion.new
+      @git = Repository::Git.new
+    end
+    it "should be allowed on subversion" do
+      @svn.allow_subtree_checkout?.should eql true
+    end
+    it "should only be possible if checked" do
+      
+    end
+    
+    it "should be forbidden on git" do
+      @git.allow_subtree_checkout?.should eql false
+    end
+  end
+  
+  describe "extensions" do
+    before(:each) do
+      @repo = Repository::Subversion.new
+    end
+    
+    it "should provide protocols" do
+      protocols = @repo.checkout_protocols
+      protocols[0].protocol.should eql "Subversion"
+      protocols[1].protocol.should eql "SVN+SSH"
+      protocols[2].protocol.should eql "Root"
+    end
+  end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/models/setting_spec.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,14 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe Setting do
+  fixtures :settings
+  
+  before(:each) do
+    Setting.default_language = 'en'
+  end
+  
+  it "should recognize checkout methods" do
+    Setting.checkout_display_checkout_info.should eql Setting.plugin_redmine_checkout['display_checkout_info']
+    Setting.checkout_display_checkout_info.should eql Setting.plugin_redmine_checkout[:display_checkout_info]
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/sanity_spec.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/spec_helper'
+ 
+describe Class do
+  it "should be a class of Class" do
+    Class.class.should eql(Class)
+  end
+  
+  it "should be awesome" do
+    Checkout.awesome?.should be_true
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/spec.opts	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,7 @@
+--colour
+--format
+progress
+--loadby
+mtime
+--reverse
+--backtrace
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/redmine_checkout/spec/spec_helper.rb	Wed Aug 25 16:39:01 2010 +0100
@@ -0,0 +1,27 @@
+ENV['RAILS_ENV'] ||= 'test'
+
+# prevent case where we are using rubygems and test-unit 2.x is installed
+begin
+  require 'rubygems'
+  gem "test-unit", "~> 1.2.3"
+rescue LoadError
+end
+
+begin
+  require "config/environment" unless defined? RAILS_ROOT
+  require RAILS_ROOT + '/spec/spec_helper'
+rescue LoadError => error
+  puts <<-EOS
+
+    You need to install rspec in your Redmine project.
+    Please execute the following code:
+    
+      gem install rspec-rails
+      script/generate rspec
+
+  EOS
+  raise error
+end
+
+Fixtures.create_fixtures File.join(File.dirname(__FILE__), "fixtures"), ActiveRecord::Base.connection.tables
+require File.join(File.dirname(__FILE__), "..", "init.rb")
\ No newline at end of file