Index: app/controllers/issues_controller.rb
===================================================================
--- app/controllers/issues_controller.rb	(revision 2924)
+++ app/controllers/issues_controller.rb	(working copy)
@@ -18,10 +18,10 @@
 class IssuesController < ApplicationController
   menu_item :new_issue, :only => :new
   
-  before_filter :find_issue, :only => [:show, :edit, :reply]
+  before_filter :find_issue, :only => [:show, :edit, :reply, :edit_gantt]
   before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
   before_filter :find_project, :only => [:new, :update_form, :preview]
-  before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu]
+  before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu, :edit_gantt]
   before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
   accept_key_auth :index, :show, :changes
 
@@ -170,6 +170,64 @@
   # Attributes that can be updated on workflow transition (without :edit permission)
   # TODO: make it configurable (at least per role)
   UPDATABLE_ATTRS_ON_TRANSITION = %w(status_id assigned_to_id fixed_version_id done_ratio) unless const_defined?(:UPDATABLE_ATTRS_ON_TRANSITION)
+
+  def edit_gantt
+    if !@issue.start_date || !@issue.due_before
+      render :text=>l(:notice_locking_conflict), :status=>400
+      return
+    end
+    @issue.init_journal(User.current)
+    date_from = Date.parse(params[:date_from])
+    old_start_date = @issue.start_date
+    o = get_position(@issue, date_from, Date.parse(params[:date_to]), params[:zoom])
+    text_for_revert = "#{@issue.id}=#{format_date(@issue.start_date)},#{@issue.start_date},#{format_date(@issue.due_before)},#{@issue.due_before},#{o[0]},#{o[1]},#{o[2]},#{o[3]}"
+    
+    if params[:day]
+      #bar moved
+      day = params[:day].to_i
+      duration = @issue.due_before - @issue.start_date
+      @issue.start_date = date_from + day
+      @issue.due_date = @issue.start_date + duration.to_i if @issue.due_date
+    elsif params[:start_date]
+      #start date changed
+      start_date = Date.parse(params[:start_date])
+      if @issue.start_date == start_date
+        render :text=>""
+        return #nothing has changed
+      end
+      @issue.start_date = start_date
+      @issue.due_date = start_date if @issue.due_date && start_date > @issue.due_date
+    elsif params[:due_date]
+      #due date changed
+      due_date = Date.parse(params[:due_date])
+      if @issue.due_date == due_date
+        render :text=>""
+        return #nothing has changed
+      end
+      @issue.due_date = due_date
+      @issue.start_date = due_date if due_date < @issue.start_date
+    end
+    fv = @issue.fixed_version
+    if fv && fv.effective_date && !@issue.due_date && fv.effective_date < @issue.start_date
+      @issue.start_date = old_start_date
+    end  
+    
+    begin
+      @issue.save!
+      o = get_position(@issue, date_from, Date.parse(params[:date_to]), params[:zoom])
+      text = "#{@issue.id}=#{format_date(@issue.start_date)},#{@issue.start_date},#{format_date(@issue.due_before)},#{@issue.due_before},#{o[0]},#{o[1]},#{o[2]},#{o[3]}"
+
+      #check dependencies
+      issues = @issue.all_precedes_issues
+      issues.each do |i|
+        o = get_position(i, date_from, Date.parse(params[:date_to]), params[:zoom])
+        text += "|#{i.id}=#{format_date(i.start_date)},#{i.start_date},#{format_date(i.due_before)},#{i.due_before},#{o[0]},#{o[1]},#{o[2]},#{o[3]}"
+      end
+      render :text=>text
+    rescue 
+      render :text=>@issue.errors.full_messages.join("\n") + "|" + text_for_revert  , :status=>400
+    end
+  end
   
   def edit
     @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
Index: app/helpers/issues_helper.rb
===================================================================
--- app/helpers/issues_helper.rb	(revision 2924)
+++ app/helpers/issues_helper.rb	(working copy)
@@ -27,8 +27,8 @@
     @cached_label_priority ||= l(:field_priority)
     
     link_to_issue(issue) + ": #{h(issue.subject)}
" +
-      "#{@cached_label_start_date}: #{format_date(issue.start_date)}
" +
-      "#{@cached_label_due_date}: #{format_date(issue.due_date)}
" +
+      "#{@cached_label_start_date}: #{format_date(issue.start_date)}
" +
+      "#{@cached_label_due_date}: #{format_date(issue.due_date)}
" +
       "#{@cached_label_assigned_to}: #{issue.assigned_to}
" +
       "#{@cached_label_priority}: #{issue.priority.name}"
   end
@@ -200,4 +200,26 @@
     export.rewind
     export
   end
+
+  def get_position(event, date_from, date_to, zoom_str)
+    zoom = zoom_str.to_i
+    i_start_date = (event.start_date >= date_from ? event.start_date : date_from )
+    i_end_date = (event.due_before <= date_to ? event.due_before : date_to )
+
+    i_done_date = event.start_date + ((event.due_before - event.start_date+1)*event.done_ratio/100).floor
+    i_done_date = (i_done_date <= date_from ? date_from : i_done_date )
+    i_done_date = (i_done_date >= date_to ? date_to : i_done_date )
+
+    i_late_date = [i_end_date, Date.today].min if i_start_date <= Date.today
+
+    i_left = ((i_start_date - date_from)*zoom).floor 	
+    i_left = 0 if i_left < 0
+    i_width = ((i_end_date - i_start_date + 1)*zoom).floor - 2                  # total width of the issue (- 2 for left and right borders)
+    i_width = 0 if i_width < 0
+    d_width = ((i_done_date - i_start_date)*zoom).floor - 2                     # done width
+    d_width = 0 if d_width < 0
+    l_width = i_late_date ? ((i_late_date - i_start_date+1)*zoom).floor - 2 : 0 # delay width
+    l_width = 0 if l_width < 0
+    return i_left, i_width, l_width, d_width
+  end
 end
Index: app/models/issue.rb
===================================================================
--- app/models/issue.rb	(revision 2924)
+++ app/models/issue.rb	(working copy)
@@ -246,6 +246,16 @@
     end
     dependencies
   end
+
+  def all_precedes_issues
+    dependencies = []
+    relations_from.each do |relation|
+      next unless relation.relation_type == IssueRelation::TYPE_PRECEDES
+      dependencies << relation.issue_to
+      dependencies += relation.issue_to.all_dependent_issues
+    end
+    dependencies
+  end
   
   # Returns an array of issues that duplicate this one
   def duplicates
Index: app/views/issues/gantt.rhtml
===================================================================
--- app/views/issues/gantt.rhtml	(revision 2924)
+++ app/views/issues/gantt.rhtml	(working copy)
@@ -46,7 +46,7 @@
 <% zoom = 1
 @gantt.zoom.times { zoom = zoom * 2 }
 
-subject_width = 330
+subject_width = 280
 header_heigth = 18
 
 headers_height = header_heigth
@@ -66,7 +66,106 @@
 g_height = [(20 * @gantt.events.length + 6)+150, 206].max
 t_height = g_height + headers_height
 %>
+
+
+
+
+
 
| @@ -80,7 +179,7 @@ # top = headers_height + 8 @gantt.events.each do |i| %> - | +
+ 
+
+
+<%
+top = headers_height + 8
+@gantt.events.each do |i| %>
+   
+
+  <% if i.is_a? Issue %>
+    <%= format_date(i.start_date) %>
+    
+    <%= calendar_for("#{i.id}_start_date") if i.is_a? Issue %>
+
+    ">
+      <%= format_date(i.due_before) %>
+    
+    
+    <%= calendar_for("#{i.id}_due_date") if i.due_date%>
+
+  <% else %>
+    <%= format_date(i.start_date) %>
+  <% end %>
+   
+<% top = top + 20
+end %>
+ | 
 
 
- 
+ 
 	<%= link_to "#{month_f.year}-#{month_f.month}", @gantt.params.merge(:year => month_f.year, :month => month_f.month), :title => "#{month_name(month_f.month)} #{month_f.year}"%>
 	 
-	<% 
+	<%
 	left = left + width + 1
 	month_f = month_f >> 1
 end %>
 
-<% 
+<%
 #
 # Weeks headers
 #
@@ -133,7 +279,7 @@
 		width = (7 - @gantt.date_from.cwday + 1) * zoom-1
 		%>
 		
 		<%= week_f.cweek if width >= 16 %>
 		 
-		<% 
+		<%
 		left = left + width+1
 		week_f = week_f+7
 	end
 end %>
 
-<% 
+<%
 #
 # Days headers
 #
@@ -157,15 +303,17 @@
 	left = 0
 	height = g_height + header_heigth - 1
 	wday = @gantt.date_from.cwday
-	(@gantt.date_to - @gantt.date_from + 1).to_i.times do 
+  dt = @gantt.date_from
+	(@gantt.date_to - @gantt.date_from + 1).to_i.times do
 	width =  zoom - 1
 	%>
 	 5 %>" class="gantt_hdr">
-	<%= day_name(wday).first %>
+	<%=  "#{dt.day} 
-	<% 
+	<%
 	left = left + width+1
 	wday = wday + 1
+  dt = dt + 1
 	wday = 1 if wday > 7
 	end
 end %>
@@ -175,41 +323,36 @@
 # Tasks
 #
 top = headers_height + 10
-@gantt.events.each do |i| 
-  if i.is_a? Issue 
-	i_start_date = (i.start_date >= @gantt.date_from ? i.start_date : @gantt.date_from )
-	i_end_date = (i.due_before <= @gantt.date_to ? i.due_before : @gantt.date_to )
-	
-	i_done_date = i.start_date + ((i.due_before - i.start_date+1)*i.done_ratio/100).floor
-	i_done_date = (i_done_date <= @gantt.date_from ? @gantt.date_from : i_done_date )
-	i_done_date = (i_done_date >= @gantt.date_to ? @gantt.date_to : i_done_date )
-	
-	i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
-	
-	i_left = ((i_start_date - @gantt.date_from)*zoom).floor 	
-	i_width = ((i_end_date - i_start_date + 1)*zoom).floor - 2                  # total width of the issue (- 2 for left and right borders)
-	d_width = ((i_done_date - i_start_date)*zoom).floor - 2                     # done width
-	l_width = i_late_date ? ((i_late_date - i_start_date+1)*zoom).floor - 2 : 0 # delay width
+@gantt.events.each do |i|
+  if i.is_a? Issue
+    i_left, i_width, l_width, d_width = get_position(i, @gantt.date_from, @gantt.date_to, zoom)
 	%>
-	"if @gantt.zoom == 4 %><%= day_name(wday).first %> 
-	<%= i.status.name %>
-	<%= (i.done_ratio).to_i %>%
-	 
-	
-	
+   
+     
+	<%# === tooltip === %>
+	
+    <%= h(i.status.name) %>
+    <%= (i.done_ratio).to_i %>%
+    <% if !i.due_date && i.fixed_version %>
+      - <%= h(i.fixed_version.name)  %>
+    <% end %>
+     
+  
+	
     <%= render_issue_tooltip i %>
 	 
-<% else 
+  <%= draggable_element("ev_#{i.id}",
+    :revert =>false, :scroll=>"'gantt-container'", :constraint => "'horizontal'", :snap=>zoom,
+       :onEnd=>"function( draggable, event )  {issue_moved(draggable.element);}"
+    ) %>
+
+<% else
     i_left = ((i.start_date - @gantt.date_from)*zoom).floor
     %>
-    
 		<%= h("#{i.project} -") unless @project && @project == i.project %>
 		<%=h i %>
Index: public/stylesheets/application.css
===================================================================
--- public/stylesheets/application.css	(revision 2924)
+++ public/stylesheets/application.css	(working copy)
@@ -658,6 +658,8 @@
 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
 .task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }  
 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
+.task_none { background:transparent; border-style: none; }
+.task_none { background:transparent; border-style: none; }
 .milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
 
 /***** Icons *****/
  |