Index: app/controllers/issues_controller.rb
===================================================================
--- app/controllers/issues_controller.rb	(revision 3084)
+++ app/controllers/issues_controller.rb	(working copy)
@@ -24,7 +24,7 @@
   before_filter :find_project, :only => [:new, :update_form, :preview]
   before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu]
   before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
-  accept_key_auth :index, :show, :changes
+  accept_key_auth :index, :show, :changes, :calendar
 
   helper :journals
   helper :projects
@@ -401,6 +401,9 @@
     retrieve_query
     if @query.valid?
       events = []
+      if (request.format == Mime::ICS)
+        @calendar.startdt = @project.created_on.to_s(:db)
+      end
       events += Issue.find(:all, 
                            :include => [:tracker, :status, :assigned_to, :priority, :project], 
                            :conditions => ["(#{@query.statement}) AND ((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
@@ -410,8 +413,11 @@
                                      
       @calendar.events = events
     end
-    
-    render :layout => false if request.xhr?
+    respond_to do |format|
+        format.html { render :layout => false if request.xhr? }
+        format.ics  { render_ics(events) }
+    end
+#    render :layout => false if request.xhr?
   end
   
   def context_menu
Index: app/controllers/application_controller.rb
===================================================================
--- app/controllers/application_controller.rb	(revision 3084)
+++ app/controllers/application_controller.rb	(working copy)
@@ -17,6 +17,7 @@
 
 require 'uri'
 require 'cgi'
+require 'icalendar'
 
 class ApplicationController < ActionController::Base
   include Redmine::I18n
@@ -53,7 +54,7 @@
       user = User.try_to_autologin(cookies[:autologin])
       session[:user_id] = user.id if user
       user
-    elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action])
+    elsif ['atom', 'ics'].include?(params[:format]) && params[:key] && accept_key_auth_actions.include?(params[:action])
       # RSS key authentication does not start a session
       User.find_by_rss_key(params[:key])
     end
@@ -186,6 +187,26 @@
     render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
   end
   
+  def render_ics(items, options={})
+    cal = Icalendar::Calendar.new
+    items.each { |i| 
+      event = Icalendar::Event.new
+      event.dtstart     =  i.start_date
+      event.dtend       =  i.due_date
+      if i.is_a? Issue
+        event.summary     =  i.subject
+      else
+        event.summary     =  "V. " + i.name
+      end
+      if !i.description.nil?
+        event.description = i.description
+      end
+      cal.add_event(event)
+    }
+    @cal_string = cal.to_ical 
+    render :template => "common/calendar.ics.erb", :layout => false , :content_type => Mime::ICS
+  end
+  
   def self.accept_key_auth(*actions)
     actions = actions.flatten.map(&:to_s)
     write_inheritable_attribute('accept_key_auth_actions', actions)
Index: app/views/common/calendar.ics.erb
===================================================================
--- app/views/common/calendar.ics.erb	(revision 0)
+++ app/views/common/calendar.ics.erb	(revision 0)
@@ -0,0 +1 @@
+<%= @cal_string %>
Index: app/views/issues/_sidebar.rhtml
===================================================================
--- app/views/issues/_sidebar.rhtml	(revision 3084)
+++ app/views/issues/_sidebar.rhtml	(working copy)
@@ -3,6 +3,8 @@
 <% if @project %>
 <%= link_to l(:field_summary), :controller => 'reports', :action => 'issue_report', :id => @project %><br />
 <%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %><br />
+<%= link_to 'ICS with open issues', :controller => 'issues', :action => 'calendar', :format => 'ics', :key => User.current.rss_key, :project_id => @project %><br />
+<%= link_to 'ICS with all issues', :controller => 'issues', :action => 'calendar', :format => 'ics', :status_id => '*', :key => User.current.rss_key, :project_id => @project %>
 <% end %>
 <%= call_hook(:view_issues_sidebar_issues_bottom) %>
 
Index: lib/redmine/helpers/calendar.rb
===================================================================
--- lib/redmine/helpers/calendar.rb	(revision 3084)
+++ lib/redmine/helpers/calendar.rb	(working copy)
@@ -44,6 +44,10 @@
           raise 'Invalid period'
         end
       end
+
+      def startdt=(dt)
+        @startdt = dt
+      end
       
       # Sets calendar events
       def events=(events)
