Index: app/helpers/issues_helper.rb
===================================================================
--- app/helpers/issues_helper.rb	(revision 43)
+++ app/helpers/issues_helper.rb	(revision 59)
@@ -19,6 +19,12 @@
 
 module IssuesHelper
   include ApplicationHelper
+  
+  def issue_ancestors(issue=@issue)
+    ancestors = ""
+    return "" if issue.parent == nil
+    ancestors += "issue-#{issue.parent.id}-child " + issue_ancestors(issue.parent)        
+  end
 
   def render_issue_tooltip(issue)
     @cached_label_start_date ||= l(:field_start_date)
@@ -69,6 +75,9 @@
       when 'fixed_version_id'
         v = Version.find_by_id(detail.value) and value = v.name if detail.value
         v = Version.find_by_id(detail.old_value) and old_value = v.name if detail.old_value
+      when 'potential_parent'
+        value = detail.value == '0' ? l(:general_text_No) : l(:general_text_Yes) if detail.value
+        old_value = detail.old_value == '0' ? l(:general_text_No) : l(:general_text_Yes) if detail.old_value
       end
     when 'cf'
       custom_field = CustomField.find_by_id(detail.prop_key)
@@ -174,4 +183,22 @@
     export.rewind
     export
   end
+  
+  def set_parent(issue, parent_id)
+    if (issue && parent_id.to_s.size > 0)
+      issue.relations_from.each do |relation|
+        if relation.relation_type == IssueRelation::TYPE_PARENTS
+          relation.destroy
+        end
+      end
+      issue.reload
+      IssueRelation.new do |relation|
+        relation.issue_from = issue
+        relation.issue_to = Issue.find(parent_id)
+        relation.relation_type = IssueRelation::TYPE_PARENTS
+        relation.save
+      end unless parent_id = '0'
+    end    
+  end
+  
 end
Index: app/helpers/queries_helper.rb
===================================================================
--- app/helpers/queries_helper.rb	(revision 43)
+++ app/helpers/queries_helper.rb	(revision 59)
@@ -40,8 +40,7 @@
       else
         case column.name
         when :subject
-        h((@project.nil? || @project != issue.project) ? "#{issue.project.name} - " : '') +
-          link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
+          subject_in_tree(issue, value)
         when :done_ratio
           progress_bar(value, :width => '80px')
         else
@@ -50,4 +49,31 @@
       end
     end
   end
+  
+  def subject_in_tree(issue, value)
+    image = ""
+    unless issue.edge? #don't show + or - icons for leaf issues
+      #o controle das tarefas a ser mostradas não está sendo feito por _list? verificar
+      image = @show_all_issues || 
+      @show_children ? 
+      link_to_remote(image_tag("contract.png", :class=>'contract-icon'), {:url => {:controller => 'issues', :action => "hide_children", :id => issue}}, :class=>'contract-link') : 
+      link_to_remote(image_tag("expand.png", :class=>'expand-icon'), {:url => {:controller => 'issues', :action => "show_children", :id => issue}}, :class=>'expand-link')
+    end
+    content_tag('span', image + content_tag('div', subject_text(issue, value), :class=>'issue-subject'), :class=>"issue-subject-level-#{issue.hierarchical_level}")
+  end
+  
+  def subject_text(issue, value)
+    if User.current.allowed_to?(:edit_issues, issue.project)            
+      subject_id = "issue-" +"#{issue.id}" + "-subject"
+      subject_text = "<span id=#{subject_id}>#{issue.subject}</span>\
+              <script type=\"text/javascript\">\
+              new Ajax.InPlaceEditor('#{subject_id}', '" + 
+              url_for({:controller => 'issues', :action => 'update_subject', :id => issue, :back_to => @back}) + "', \
+              {okButton:false, callback: function(form, value) { return 'subject=' + value }});</script>"
+    else
+      subject_text = link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
+    end
+    h((@project.nil? || @project != issue.project) ? "#{issue.project.name} - " : '') + subject_text
+  end
+  
 end
Index: app/models/issue.rb
===================================================================
--- app/models/issue.rb	(revision 43)
+++ app/models/issue.rb	(revision 59)
@@ -130,7 +130,7 @@
         @current_journal.details << JournalDetail.new(:property => 'attr',
                                                       :prop_key => c,
                                                       :old_value => @issue_before_change.send(c),
-                                                      :value => send(c)) unless send(c)==@issue_before_change.send(c)
+                                                      :value => send(c)) unless send(c)==@issue_before_change.send(c) || (!self.edge? && %w(status_id priority_id fixed_version_id start_date due_date done_ratio estimated_hours).include?(c))
       }
       # custom fields changes
       custom_values.each {|c|
@@ -230,6 +230,10 @@
     relations.select {|r| r.relation_type == IssueRelation::TYPE_DUPLICATES}.collect {|r| r.other_issue(self)}
   end
   
+  def duration1
+    (start_date && due_date) ? (due_date - start_date + 1) : 0
+  end
+  
   def duration
     (start_date && due_date) ? due_date - start_date : 0
   end
@@ -244,6 +248,173 @@
     end
   end
   
+  def done_ratio
+    if children?
+      @total_planned_days ||= 0
+      @total_actual_days ||= 0
+      children.each do |child| # from every subtask get the total number of days and the number of days already "worked"
+        planned_days = child.duration1
+        actual_days = child.done_ratio ?  (planned_days * child.done_ratio / 100).floor : 0
+        @total_planned_days += planned_days
+        @total_actual_days += actual_days
+      end
+      @total_done_ratio = @total_planned_days != 0 ? (@total_actual_days * 100 / @total_planned_days).floor : 0
+    else
+      read_attribute(:done_ratio)
+    end
+  end
+  
+  def estimated_hours
+    if children?
+      is_set = false
+      children.each do |child|
+        if child.estimated_hours
+          if is_set
+            @est_hours += child.estimated_hours
+          else
+            @est_hours = child.estimated_hours
+            is_set = true
+          end
+        end     
+      end
+      @est_hours
+    else
+      read_attribute(:estimated_hours)
+    end
+  end
+  
+  def start_date
+    calculate 'start_date'
+  end  
+  
+  def due_date
+    calculate 'due_date'
+  end  
+  
+  def priority
+    if children?
+      @pri = children.first.priority 
+      children.each do |child|
+        if @pri.id < child.priority.id
+          @pri = child.priority
+        end
+      end
+      @pri     
+    else
+      Enumeration.find(self[:priority_id]) if self[:priority_id] && self[:priority_id] != 0
+    end     
+  end
+  
+  def fixed_version
+    if children?
+      @fxd_version = children.first.fixed_version
+      children.each do |child|
+        if child.fixed_version && (!self[:fixed_version_id] || Version.find(self[:fixed_version_id]).id < child.fixed_version.id)
+          @fxd_version = child.fixed_version
+        end
+      end
+      @fxd_version     
+    else
+      Version.find(self[:fixed_version_id]) if self[:fixed_version_id]  && self[:fixed_version_id] != 0
+    end 
+  end
+  
+  def status    
+    if children?
+      @sta = children.first.status
+      children.each do |child|
+        if @sta.id > child.status.id
+          @sta = child.status
+        end
+      end
+      @sta
+    else
+      IssueStatus.find(self[:status_id]) if self[:status_id] && self[:status_id] != 0
+    end     
+  end
+   
+  def calculate(field)
+    if children?
+      @value = eval "children.first.#{field}" 
+      children.each do |child|        
+        case field
+          when 'start_date'
+          if child.start_date && (!@value || @value > child.start_date)
+            @value = child.start_date
+          end
+          when 'due_date'
+          if child.due_date && (!@value || @value < child.due_date)
+            @value = child.due_date
+          end
+        end        
+      end
+      @value
+    else
+      read_attribute(eval(":#{field}"))
+    end
+  end  
+
+  def children?
+    children != []
+  end
+  
+  def children
+    children = []
+    relations_to.each do |relation|
+      if relation.relation_type == IssueRelation::TYPE_PARENTS
+        children << relation.other_issue(self)
+      end
+    end
+    children
+  end
+  
+  def parent
+    relations_from.each do |relation|
+      if relation.relation_type == IssueRelation::TYPE_PARENTS
+        return parent = relation.other_issue(self)
+      end
+    end
+    return nil
+  end
+ 
+  def parent_issue=(parent_id)
+    #workaround that allows the use of a select box for choosing the parent issue in the create issue form
+    #is it possible to have a select box in a form without a corresponding method in the model?
+  end
+  
+  def parent_issue
+    #workaround that allows the use of a select box for choosing the parent issue in the create issue form
+    #is it possible to have a select box in a form without a corresponding method in the model?
+  end
+   
+  def parent?
+    parent != nil
+  end 
+  
+  def root?
+    !parent?
+  end
+  
+  def ancestors(issue=self)
+    a = []
+    return a if ! issue.parent?
+    (a << issue.parent) | ancestors(issue.parent)
+  end
+  
+  #First level tasks have hierarchical level = 1 and so on
+  def hierarchical_level(issue=self)
+    issue.parent? ? (1 + hierarchical_level(issue.parent)) : 1
+  end
+  
+  def edge?
+    relations_to.each do |relation|
+      if relation.relation_type == IssueRelation::TYPE_PARENTS
+        return false
+      end
+    end
+    return true
+  end
+  
   def to_s
     "#{tracker} ##{id}: #{subject}"
   end
Index: app/models/issue_relation.rb
===================================================================
--- app/models/issue_relation.rb	(revision 43)
+++ app/models/issue_relation.rb	(revision 59)
@@ -23,6 +23,7 @@
   TYPE_DUPLICATES   = "duplicates"
   TYPE_BLOCKS       = "blocks"
   TYPE_PRECEDES     = "precedes"
+  TYPE_PARENTS     = "parents"
   
   TYPES = { TYPE_RELATES =>     { :name => :label_relates_to, :sym_name => :label_relates_to, :order => 1 },
             TYPE_DUPLICATES =>  { :name => :label_duplicates, :sym_name => :label_duplicates, :order => 2 },
@@ -28,6 +29,7 @@
             TYPE_DUPLICATES =>  { :name => :label_duplicates, :sym_name => :label_duplicates, :order => 2 },
             TYPE_BLOCKS =>      { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 3 },
             TYPE_PRECEDES =>    { :name => :label_precedes, :sym_name => :label_follows, :order => 4 },
+            TYPE_PARENTS =>    { :name => :label_parents, :sym_name => :label_children, :order => 5 },
           }.freeze
   
   validates_presence_of :issue_from, :issue_to, :relation_type
@@ -32,6 +34,7 @@
   
   validates_presence_of :issue_from, :issue_to, :relation_type
   validates_inclusion_of :relation_type, :in => TYPES.keys
+  validates_uniqueness_of :relation_type, :scope => [:issue_from_id, :relation_type], :message=>l(:error_issue_can_have_only_one_parent)
   validates_numericality_of :delay, :allow_nil => true
   validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
   
Index: app/controllers/issues_controller.rb
===================================================================
--- app/controllers/issues_controller.rb	(revision 43)
+++ app/controllers/issues_controller.rb	(revision 59)
@@ -19,10 +19,10 @@
   layout 'base'
   menu_item :new_issue, :only => :new
   
-  before_filter :find_issue, :only => [:show, :edit, :destroy_attachment]
+  before_filter :find_issue, :only => [:show, :edit, :destroy_attachment, :update_subject, :show_children, :hide_children]
   before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
   before_filter :find_project, :only => [:new, :update_form, :preview]
-  before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu]
+  before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu, :show_children, :hide_children]
   before_filter :find_optional_project, :only => [:index, :changes]
   accept_key_auth :index, :changes
 
@@ -43,7 +43,52 @@
   helper :sort
   include SortHelper
   include IssuesHelper
+  include ActionView::Helpers::PrototypeHelper
+  
+  def update_subject
+    @notes = params[:notes]
+    journal = @issue.init_journal(User.current, @notes)
+    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
+    # User can change issue attributes only if he has :edit permission or if a workflow transition is allowed
+    if (@edit_allowed || !@allowed_statuses.empty?) && params[:subject]
+      @issue.subject = params[:subject]
+    end    
+    if @issue.save
+      if !journal.new_record?
+      # Only send notification if something was actually changed
+      flash[:notice] = l(:notice_successful_update)
+      Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
+    end
+      render(:text => params[:subject])
+    end    
+  rescue ActiveRecord::StaleObjectError
+    # Optimistic locking exception
+    flash.now[:error] = l(:notice_locking_conflict)       
+  end
+  
+  def show_children
+    retrieve_query
+    if @query.valid?
+      render :update do |page|
+        page.replace "issue-#{@issue.id}", :partial => 'show_children', :locals => {:issue => @issue, :query => @query}
+      end
+    end    
+  end
 
+  def hide_children
+    retrieve_query #verificar necessidade
+    if @query.valid?
+      render :update do |page|
+        page.select(".issue-#{@issue.id}-child").each do |child|
+          child.remove
+        end
+        page.select("#issue-#{@issue.id} a.contract-link").each do |contractIcon|
+          contractIcon.replace link_to_remote(image_tag("expand.png", :class=>'expand-icon'), {:url => {:controller => 'issues', :action => "show_children", :id => @issue}}, :class=>'expand-link')
+        end
+      end
+    end    
+  end
+  
   def index
     sort_init "#{Issue.table_name}.id", "desc"
     sort_update
@@ -146,6 +191,7 @@
                                                                                                        :value => (params[:custom_fields] ? params[:custom_fields][x.id.to_s] : nil)) }
       @issue.custom_values = @custom_values
       if @issue.save
+        set_parent(@issue, params[:issue][:parent_issue]) if params[:issue][:parent_issue]
         attach_files(@issue, params[:attachments])
         flash[:notice] = l(:notice_successful_create)
         Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
@@ -191,6 +237,7 @@
       attachments = attach_files(@issue, params[:attachments])
       attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
       if @issue.save
+        set_parent(@issue, params[:issue][:parent_issue]) if params[:issue][:parent_issue]
         # Log spend time
         if current_role.allowed_to?(:log_time)
           @time_entry.save
@@ -227,8 +274,10 @@
         issue.start_date = params[:start_date] unless params[:start_date].blank?
         issue.due_date = params[:due_date] unless params[:due_date].blank?
         issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
+        issue.potential_parent = params[:potential_parent] unless params[:potential_parent].blank?
         # Don't save any change to the issue if the user is not authorized to apply the requested status
         if (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
+          set_parent(issue, params[:parent_issue]) unless params[:parent_issue].blank?
           # Send notification for each issue (if changed)
           Mailer.deliver_issue_edit(journal) if journal.details.any? && Setting.notified_events.include?('issue_updated')
         else
Index: app/controllers/projects_controller.rb
===================================================================
--- app/controllers/projects_controller.rb	(revision 43)
+++ app/controllers/projects_controller.rb	(revision 59)
@@ -381,16 +381,35 @@
     @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
     
     @events = []
+    @issues = []
+    @versions = []
     @project.issues_with_subprojects(@with_subprojects) do
-      @events += Issue.find(:all, 
+      @issues = Issue.find(:all, 
                            :order => "start_date, due_date",
                            :include => [:tracker, :status, :assigned_to, :priority, :project], 
-                           :conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
+                           :conditions => ["(#{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))"]
                            ) unless @selected_tracker_ids.empty?
-      @events += Version.find(:all, :include => :project,
+      @versions = Version.find(:all, :include => :project,
                                     :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
     end
-    @events.sort! {|x,y| x.start_date <=> y.start_date }
+    @issues = @issues.select {|issue| issue.start_date and issue.due_date and ((issue.start_date>=@date_from and issue.start_date<=@date_to) || (issue.due_date>=@date_from and issue.due_date<=@date_to) || (issue.start_date<@date_from and issue.due_date>@date_to))}
+    
+    case params[:display]
+      when 'first-level-only'
+      @issues = @issues.select {|issue| !issue.parent?}
+      when 'tree'
+      Array.new(@issues).each {|issue| @issues += issue.ancestors}
+      @issues.uniq!
+      @issues = sort_as_tree(@issues)
+      @events = integrate_versions_with_issues_tree(@issues, @versions)
+    end
+    
+    unless params[:display] == 'tree' 
+      @events += @issues
+      @events += @versions
+      @events.sort! {|x,y| x.start_date <=> y.start_date }
+    end
+    
     
     if params[:format]=='pdf'
       @options_for_rfpdf ||= {}
@@ -430,4 +449,48 @@
       @selected_tracker_ids = selectable_trackers.collect {|t| t.id.to_s }
     end
   end
+  
+  
+  def sort_as_tree(issues)
+    issues.sort!{|a,b| a.hierarchical_level <=> b.hierarchical_level}
+    @sorted_issues = []
+    issues.each do |issue|
+      if @sorted_issues.empty?
+        @sorted_issues << issue
+        next
+      end
+      @time_to_stop = false #indicates when this task reaches its parent task (important because it has to stop between its parent task and the next aunt task
+      @sorted_issues.each do |sorted_issue|
+        #if same parent and smaller date, stop; if same parent, same date and smaller id, stop; after parent and before next parent, stop; 
+        if ((sorted_issue.parent == issue.parent) && (sorted_issue.start_date > issue.start_date)) ||
+         ((sorted_issue.parent == issue.parent) && (sorted_issue.start_date == issue.start_date) && (sorted_issue.id > issue.id)) ||
+         (@time_to_stop && (sorted_issue.hierarchical_level < issue.hierarchical_level))
+          @sorted_issues.insert(@sorted_issues.index(sorted_issue), issue)
+          break
+        end
+        @time_to_stop = true if sorted_issue == issue.parent      
+      end
+      #if this issue's parent is the last element
+      @sorted_issues << issue if @time_to_stop
+    end
+    @sorted_issues
+  end
+  
+  #assumes that first level issues are ordered by date (sort_as_tree)
+  def integrate_versions_with_issues_tree(issues, versions)
+    versions.sort! {|x,y| x.start_date <=> y.start_date }    
+    versions.each do |version|
+      issues << version if issues.empty?
+      issues.each do |issue|
+        if ((issue.is_a? Issue && issue.root?) || (issue.is_a? Version)) && version.start_date < issue.start_date
+          #insert version before a root task or another version whose date is immediately after this task's one 
+          issues.insert(issues.index(issue), version)
+        elsif issue == issues.last
+          issues << version        
+        end
+      end
+    end
+    issues
+  end  
+  
 end
Index: app/views/issues/bulk_edit.rhtml
===================================================================
--- app/views/issues/bulk_edit.rhtml	(revision 43)
+++ app/views/issues/bulk_edit.rhtml	(revision 59)
@@ -38,6 +38,17 @@
 <label><%= l(:field_done_ratio) %>: 
 <%= select_tag 'done_ratio', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></label>
 </p>
+
+<p>
+<label><%= l(:field_parent_issue) %>: 
+<%= select_tag('parent_issue', content_tag('option', l(:label_no_change_option), :value => '') +
+                                 content_tag('option', l(:label_none), :value => '0') +
+                                 options_from_collection_for_select(Issue.find(:all, :conditions => [ "potential_parent = true"]).sort {|a, b| a.id <=> b.id}, :id, :subject)) %></label>
+<label><%= l(:field_potential_parent) %>: 
+<%= select_tag('potential_parent', content_tag('option', l(:label_no_change_option), :value => '') +
+                                 content_tag('option', l(:general_text_Yes), :value => 'true') +
+								 content_tag('option', l(:general_text_No), :value => 'false')) %></label>
+</p>
 </fieldset>
 
 <fieldset><legend><%= l(:field_notes) %></legend>
Index: app/views/issues/_form.rhtml
===================================================================
--- app/views/issues/_form.rhtml	(revision 43)
+++ app/views/issues/_form.rhtml	(revision 59)
@@ -16,7 +16,7 @@
 </div>
 
 <div class="splitcontentleft">
-<% if @issue.new_record? || @allowed_statuses.any? %>
+<% if (@issue.new_record? || @allowed_statuses.any?) && @issue.edge? %>
 <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
 <% else %>
 <p><label><%= l(:field_status) %></label> <%= @issue.status.name %></p>
@@ -22,7 +22,12 @@
 <p><label><%= l(:field_status) %></label> <%= @issue.status.name %></p>
 <% end %>
 
+<% if @issue.edge? %>
 <p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
+<% else %>
+<p><label><%= l(:field_priority) %></label> <%= @issue.priority.name %></p>
+<% end %>
+
 <p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
 <p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
 <%= prompt_to_remote(l(:label_issue_category_new),
@@ -29,12 +34,18 @@
                      l(:label_issue_category_new), 'category[name]', 
                      {:controller => 'projects', :action => 'add_issue_category', :id => @project},
                      :class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
+
+<% if @issue.edge? %>
 <%= content_tag('p', f.select(:fixed_version_id, 
                               (@project.versions.sort.collect {|v| [v.name, v.id]}),
                               { :include_blank => true })) unless @project.versions.empty? %>
+<% else %>
+<p><label><%= l(:field_fixed_version) %></label> <%= @issue.fixed_version ? @issue.fixed_version.name : '-' %></p>
+<% end %>
 </div>
 
 <div class="splitcontentright">
+<% if @issue.edge? %>	
 <p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
 <p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
 <p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
@@ -39,7 +50,14 @@
 <p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
 <p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
 <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
+<% else %>
+<p><label><%= l(:field_start_date) %></label> <%= format_date(@issue.start_date) %></p>
+<p><label><%= l(:field_due_date) %></label> <%= format_date(@issue.due_date) %></p>
+<p><label><%= l(:field_done_ratio) %></label> <%= "#{@issue.done_ratio}%" %></p>
+<% end %>
+<p><%= f.check_box :potential_parent %></p>
 </div>
+<p><%= f.select :parent_issue, (Issue.find(:all, :conditions => [ "potential_parent = true"]).sort {|a, b| a.id <=> b.id}.collect {|p| ['#' << p.id.to_s << ' - ' << (p.subject.length > 50 ? p.subject[0..50] << '...' : p.subject), p.id]}),  :include_blank => true  %></p>
 
 <div style="clear:both;"> </div>
 <%= render :partial => 'form_custom_fields', :locals => {:values => @custom_values} %>
Index: app/views/issues/_form_update.rhtml
===================================================================
--- app/views/issues/_form_update.rhtml	(revision 43)
+++ app/views/issues/_form_update.rhtml	(revision 59)
@@ -1,8 +1,13 @@
 <div class="splitcontentleft">
+<% if @issue.edge? %>
 <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
+<% else %>
+<p><label><%= l(:field_status) %></label> <%= @issue.status.name %></p>
+<% end %>
 <p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
 </div>
 <div class="splitcontentright">
+<% if @issue.edge? %>
 <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
 <%= content_tag('p', f.select(:fixed_version_id, 
                           (@project.versions.sort.collect {|v| [v.name, v.id]}),
@@ -7,4 +12,8 @@
 <%= content_tag('p', f.select(:fixed_version_id, 
                           (@project.versions.sort.collect {|v| [v.name, v.id]}),
                           { :include_blank => true })) unless @project.versions.empty? %>
+<% else %>
+<p><label><%= l(:field_done_ratio) %></label> <%= "#{@issue.done_ratio}%" %></p>
+<p><label><%= l(:field_fixed_version) %></label> <%= @issue.fixed_version ? @issue.fixed_version.name : '-' %></p>
+<% end %>
 </div>
Index: app/views/issues/context_menu.rhtml
===================================================================
--- app/views/issues/context_menu.rhtml	(revision 43)
+++ app/views/issues/context_menu.rhtml	(revision 59)
@@ -2,6 +2,7 @@
 <% if !@issue.nil? -%>
 	<li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
 	        :class => 'icon-edit', :disabled => !@can[:edit] %></li>
+	<% if @issue.edge? %>
 	<li class="folder">			
 		<a href="#" class="submenu" onclick="return false;"><%= l(:field_status) %></a>
 		<ul>
@@ -10,7 +11,7 @@
 		                              :selected => (s == @issue.status), :disabled => !(@can[:update] && @allowed_statuses.include?(s)) %></li>
 		<% end -%>
 		</ul>
-	</li>
+	</li>	
 	<li class="folder">			
 		<a href="#" class="submenu"><%= l(:field_priority) %></a>
 		<ul>
@@ -20,6 +21,7 @@
 		<% end -%>
 		</ul>
 	</li>
+	<% end %>
 	<li class="folder">			
 		<a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
 		<ul>
@@ -31,6 +33,7 @@
 		                              :selected => @issue.assigned_to.nil?, :disabled => !@can[:update] %></li>
 		</ul>
 	</li>
+	<% if @issue.edge? %>
 	<li class="folder">
 		<a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
 		<ul>
@@ -39,9 +42,10 @@
 		                                  :selected => (p == @issue.done_ratio), :disabled => !@can[:edit] %></li>
 		<% end -%>
 		</ul>
-	</li>
+	</li>	
 	<li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue},
 	        :class => 'icon-copy', :disabled => !@can[:copy] %></li>
+	<% end %>
 <% else -%>
 	<li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id)},
 	        :class => 'icon-edit', :disabled => !@can[:edit] %></li>
Index: app/views/issues/_list.rhtml
===================================================================
--- app/views/issues/_list.rhtml	(revision 43)
+++ app/views/issues/_list.rhtml	(revision 59)
@@ -10,7 +10,8 @@
         <% end %>
 	</tr></thead>
 	<tbody>
-	<% issues.each do |issue| -%>
+	<% issues.each do |issue| 
+	   next if !@show_all_issues && (issue.hierarchical_level != 1) -%>	    
 	<tr id="issue-<%= issue.id %>" class="issue hascontextmenu <%= cycle('odd', 'even') %> <%= "status-#{issue.status.position} priority-#{issue.priority.position}" %>">
 	    <td class="checkbox"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
 		<td><%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %></td>
Index: app/views/issues/show.rhtml
===================================================================
--- app/views/issues/show.rhtml	(revision 43)
+++ app/views/issues/show.rhtml	(revision 59)
@@ -43,6 +43,9 @@
     <% end %>
 </tr>
 <tr>
+    <td><b><%=l(:field_potential_parent)%> :</b></td><td><%= @issue.potential_parent ? l(:general_text_Yes) : l(:general_text_No) %></td>
+</tr>
+<tr>
 <% n = 0
 for custom_value in @custom_values %>
     <td valign="top"><b><%= custom_value.custom_field.name %> :</b></td><td valign="top"><%= simple_format(h(show_value(custom_value))) %></td>
Index: app/views/issues/index.rfpdf
===================================================================
--- app/views/issues/index.rfpdf	(revision 43)
+++ app/views/issues/index.rfpdf	(revision 59)
@@ -24,6 +24,7 @@
    	pdf.Cell(30, row_height, l(:field_priority), 0, 0, 'L', 1)
    	pdf.Cell(40, row_height, l(:field_assigned_to), 0, 0, 'L', 1)
    	pdf.Cell(25, row_height, l(:field_updated_on), 0, 0, 'L', 1)
+   	pdf.Cell(15, row_height, l(:field_parent_issue), 0, 0, 'L', 1)
    	pdf.Cell(0, row_height, l(:field_subject), 0, 0, 'L', 1)
    	pdf.Line(10, pdf.GetY, 287, pdf.GetY)
    	pdf.Ln
@@ -42,6 +43,7 @@
 	   	pdf.Cell(30, row_height, issue.priority.name, 0, 0, 'L', 1)
 	   	pdf.Cell(40, row_height, issue.assigned_to ? issue.assigned_to.name : '', 0, 0, 'L', 1)
 	   	pdf.Cell(25, row_height, format_date(issue.updated_on), 0, 0, 'L', 1)
+   		pdf.Cell(15, row_height, issue.parent ? "# #{issue.parent.id}" : '', 0, 0, 'L', 1)
 	   	pdf.MultiCell(0, row_height, (@project == issue.project ? issue.subject : "#{issue.project.name} - #{issue.subject}"))
    		pdf.Line(10, pdf.GetY, 287, pdf.GetY)
    		pdf.SetY(pdf.GetY() + 1)
Index: app/views/issues/_edit.rhtml
===================================================================
--- app/views/issues/_edit.rhtml	(revision 43)
+++ app/views/issues/_edit.rhtml	(revision 59)
@@ -14,7 +14,7 @@
         <%= render :partial => (@edit_allowed ? 'form' : 'form_update'), :locals => {:f => f} %>
         </fieldset>
     <% end %>
-    <% if authorize_for('timelog', 'edit') %>
+    <% if authorize_for('timelog', 'edit') && @issue.edge? %>
         <fieldset class="tabular"><legend><%= l(:button_log_time) %></legend>
         <% fields_for :time_entry, @time_entry, { :builder => TabularFormBuilder, :lang => current_language} do |time_entry| %>
         <div class="splitcontentleft">
Index: app/views/issues/_show_children.rhtml
===================================================================
--- app/views/issues/_show_children.rhtml	(revision 0)
+++ app/views/issues/_show_children.rhtml	(revision 59)
@@ -0,0 +1,14 @@
+<%	
+issues = [@issue]
+issues += @issue.children
+issues.each do |issue|
+	is_parent = (issue == @issue)
+    #used in queries_helper.rb when deciding which icon will be shown (if + or -)  
+	@show_children = is_parent -%>	    
+	<tr id="issue-<%=issue.id%>" class="issue <%= issue_ancestors(issue) %> hascontextmenu <%= cycle('odd', 'even') %> <%= "status-#{issue.status.position} priority-#{issue.priority.position}" %>">
+	    <td class="checkbox"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
+		<td><%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %></td>
+	    <% query.columns.each do |column| %><%= content_tag 'td', column_content(column, issue), :class => column.name %><% end %>
+	</tr>
+<%	
+end -%>
\ No newline at end of file
Index: lang/lt.yml
===================================================================
--- lang/lt.yml	(revision 43)
+++ lang/lt.yml	(revision 59)
@@ -126,6 +126,8 @@
 field_assigned_to: Paskirtas 
 field_priority: Prioritetas 
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Vartotojas 
 field_role: Vaidmuo 
 field_homepage: Pagrindinis puslapis 
@@ -414,6 +416,8 @@
 label_blocked_by: blokuotas 
 label_precedes: įvyksta pirma 
 label_follows: seka 
+label_parents: child of
+label_children: parent of
 label_end_to_start: užbaigti, kad pradėti
 label_end_to_end: užbaigti, kad pabaigti 
 label_start_to_start: pradėkite pradėti 
@@ -618,6 +622,7 @@
 setting_default_projects_public: Naujas projektas viešas pagal nutylėjimą
 error_scm_annotate: "Įrašas neegzituoja arba negalima jo atvaizduoti."
 label_planning: Planavimas
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Šis(ie) subprojektas(ai): %s taip pat bus ištrintas(i).'
 label_and_its_subprojects: %s projektas ir jo subprojektai
 
Index: lang/uk.yml
===================================================================
--- lang/uk.yml	(revision 43)
+++ lang/uk.yml	(revision 59)
@@ -123,6 +123,8 @@
 field_assigned_to: Призначена до
 field_priority: Пріоритет
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Користувач
 field_role: Роль
 field_homepage: Домашня сторінка
@@ -411,6 +413,8 @@
 label_blocked_by: заблоковане 
 label_precedes: передує
 label_follows: наступний за
+label_parents: child of
+label_children: parent of
 label_end_to_start: з кінця до початку
 label_end_to_end: з кінця до кінця
 label_start_to_start: з початку до початку
@@ -619,4 +623,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/ro.yml
===================================================================
--- lang/ro.yml	(revision 43)
+++ lang/ro.yml	(revision 59)
@@ -118,6 +118,8 @@
 field_assigned_to: Atribuit pentru
 field_priority: Prioritate
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Utilizator
 field_role: Rol
 field_homepage: Pagina principala
@@ -393,6 +395,8 @@
 label_blocked_by: blocat de
 label_precedes: precedes
 label_follows: follows
+label_parents: child of
+label_children: parent of
 label_end_to_start: de la sfarsit la capat
 label_end_to_end: de la sfarsit la sfarsit
 label_start_to_start: de la capat la capat
@@ -617,4 +621,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/zh.yml
===================================================================
--- lang/zh.yml	(revision 43)
+++ lang/zh.yml	(revision 59)
@@ -131,6 +131,8 @@
 field_assigned_to: 指派给
 field_priority: 优先级
 field_fixed_version: 目标版本
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: 用户
 field_role: 角色
 field_homepage: 主页
@@ -452,6 +454,8 @@
 label_blocked_by: 被阻挡
 label_precedes: 优先于
 label_follows: 跟随于
+label_parents: child of
+label_children: parent of
 label_end_to_start: 结束-开始
 label_end_to_end: 结束-结束
 label_start_to_start: 开始-开始
@@ -560,6 +564,7 @@
 text_regexp_info: 例如：^[A-Z0-9]+$
 text_min_max_length_info: 0 表示没有限制
 text_project_destroy_confirmation: 您确信要删除这个项目以及所有相关的数据吗？
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: '以下子项目也将被同时删除：%s'
 text_workflow_edit: 选择角色和跟踪标签来编辑工作流程
 text_are_you_sure: 您确定？
Index: lang/pt.yml
===================================================================
--- lang/pt.yml	(revision 43)
+++ lang/pt.yml	(revision 59)
@@ -118,6 +118,8 @@
 field_assigned_to: Atribuído para
 field_priority: Prioridade
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Usuário
 field_role: Regra
 field_homepage: Página inicial
@@ -395,6 +397,8 @@
 label_blocked_by: bloqueado por
 label_precedes: procede
 label_follows: segue
+label_parents: child of
+label_children: parent of
 label_end_to_start: fim ao início
 label_end_to_end: fim ao fim
 label_start_to_start: ínícia ao inícia
@@ -617,4 +621,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/da.yml
===================================================================
--- lang/da.yml	(revision 43)
+++ lang/da.yml	(revision 59)
@@ -127,6 +127,8 @@
 field_assigned_to: Tildelt til
 field_priority: Prioritet
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Bruger
 field_role: Rolle
 field_homepage: Hjemmeside
@@ -442,6 +444,8 @@
 label_blocked_by: blokeret af
 label_precedes: kommer før
 label_follows: følger
+label_parents: child of
+label_children: parent of
 label_end_to_start: slut til start
 label_end_to_end: slut til slut
 label_start_to_start: start til start
@@ -619,4 +623,5 @@
 setting_default_projects_public: Nye projekter er offentlige som default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planlægning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/pt-br.yml
===================================================================
--- lang/pt-br.yml	(revision 43)
+++ lang/pt-br.yml	(revision 59)
@@ -118,6 +118,8 @@
 field_assigned_to: Atribuído para
 field_priority: Prioridade
 field_fixed_version: Versão
+field_parent_issue: Filha de
+field_potential_parent: Potential tarefa-mãe
 field_user: Usuário
 field_role: Papel
 field_homepage: Página inicial
@@ -395,6 +397,8 @@
 label_blocked_by: bloqueado por
 label_precedes: precede
 label_follows: segue
+label_parents: filha de
+label_children: mãe de
 label_end_to_start: fim para o início
 label_end_to_end: fim para fim
 label_start_to_start: início para início
@@ -616,5 +620,6 @@
 setting_default_projects_public: Novos projetos são públicos por padrão
 error_scm_annotate: "Esta entrada não existe ou não pode ser anotada."
 label_planning: Planejamento
+error_issue_can_have_only_one_parent: permite apenas uma relação (uma tarefa pode ter apenas uma tarefa-mãe).
 text_subprojects_destroy_warning: 'Seu(s) subprojeto(s): %s também serão excluídos.'
 label_age: Age
Index: lang/sr.yml
===================================================================
--- lang/sr.yml	(revision 43)
+++ lang/sr.yml	(revision 59)
@@ -122,6 +122,8 @@
 field_assigned_to: Dodeljeno
 field_priority: Prioritet
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Korisnik
 field_role: Uloga
 field_homepage: Homepage
@@ -405,6 +407,8 @@
 label_blocked_by: blokiran od strane
 label_precedes: prethodi
 label_follows: sledi
+label_parents: child of
+label_children: parent of
 label_end_to_start: od kraja do početka
 label_end_to_end: od kraja do kraja
 label_start_to_start: od početka do pocetka
@@ -618,4 +622,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/ru.yml
===================================================================
--- lang/ru.yml	(revision 43)
+++ lang/ru.yml	(revision 59)
@@ -128,6 +128,8 @@
 field_assigned_to: Назначена
 field_priority: Приоритет
 field_fixed_version: Версия
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Пользователь
 field_role: Роль
 field_homepage: Стартовая страница
@@ -418,6 +420,8 @@
 label_blocked_by: заблокировано 
 label_precedes: предшествует
 label_follows: следующий
+label_parents: child of
+label_children: parent of
 label_end_to_start: с конца к началу
 label_end_to_end: с конца к концу
 label_start_to_start: с начала к началу
@@ -621,6 +625,7 @@
 setting_default_projects_public: Новые проекты являются публичными
 error_scm_annotate: "Данные отсутствуют или не могут быть подписаны."
 label_planning: Планирование
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Подпроекты: %s также будут удалены.'
 label_and_its_subprojects: %s и все подпроекты
 mail_body_reminder: "%d назначенных на вас задач на следующие %d дней:" 
Index: lang/de.yml
===================================================================
--- lang/de.yml	(revision 43)
+++ lang/de.yml	(revision 59)
@@ -129,6 +129,8 @@
 field_assigned_to: Zugewiesen an
 field_priority: Priorität
 field_fixed_version: Zielversion
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Benutzer
 field_role: Rolle
 field_homepage: Projekt-Homepage
@@ -449,6 +451,8 @@
 label_blocked_by: Blockiert durch
 label_precedes: Vorgänger von
 label_follows: folgt
+label_parents: child of
+label_children: parent of
 label_end_to_start: Ende - Anfang
 label_end_to_end: Ende - Ende
 label_start_to_start: Anfang - Anfang
@@ -618,4 +622,5 @@
 enumeration_issue_priorities: Ticket-Prioritäten
 enumeration_doc_categories: Dokumentenkategorien
 enumeration_activities: Aktivitäten (Zeiterfassung)
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/bg.yml
===================================================================
--- lang/bg.yml	(revision 43)
+++ lang/bg.yml	(revision 59)
@@ -118,6 +118,8 @@
 field_assigned_to: Възложена на
 field_priority: Приоритет
 field_fixed_version: Планувана версия
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Потребител
 field_role: Роля
 field_homepage: Начална страница
@@ -395,6 +397,8 @@
 label_blocked_by: блокирана от
 label_precedes: предшества
 label_follows: изпълнява се след
+label_parents: child of
+label_children: parent of
 label_end_to_start: end to start
 label_end_to_end: end to end
 label_start_to_start: start to start
@@ -617,4 +621,5 @@
 setting_default_projects_public: Новите проекти са публични по подразбиране
 error_scm_annotate: "Обектът не съществува или не може да бъде анотиран."
 label_planning: Планиране
+error_issue_can_have_only_one_parent: allows only one relationship (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/sv.yml
===================================================================
--- lang/sv.yml	(revision 43)
+++ lang/sv.yml	(revision 59)
@@ -118,6 +118,8 @@
 field_assigned_to: Tilldelad
 field_priority: Prioritet
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Användare
 field_role: Roll
 field_homepage: Hemsida
@@ -395,6 +397,8 @@
 label_blocked_by: blocked by
 label_precedes: precedes
 label_follows: follows
+label_parents: child of
+label_children: parent of
 label_end_to_start: end to start
 label_end_to_end: end to end
 label_start_to_start: start to start
@@ -618,4 +622,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/ja.yml
===================================================================
--- lang/ja.yml	(revision 43)
+++ lang/ja.yml	(revision 59)
@@ -119,6 +119,8 @@
 field_assigned_to: 担当者
 field_priority: 優先度
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: ユーザ
 field_role: 役割
 field_homepage: ホームページ
@@ -396,6 +398,8 @@
 label_blocked_by: ブロックされている
 label_precedes: 先行する
 label_follows: 後続する
+label_parents: child of
+label_children: parent of
 label_end_to_start: end to start
 label_end_to_end: end to end
 label_start_to_start: start to start
@@ -618,4 +622,5 @@
 setting_default_projects_public: デフォルトで新しいプロジェクトは公開にする
 error_scm_annotate: "エントリが存在しない、もしくはアノテートできません。"
 label_planning: 計画
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/he.yml
===================================================================
--- lang/he.yml	(revision 43)
+++ lang/he.yml	(revision 59)
@@ -120,6 +120,8 @@
 field_assigned_to: מוצב ל
 field_priority: עדיפות
 field_fixed_version: גירסאת יעד
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: מתשמש
 field_role: תפקיד
 field_homepage: דף הבית
@@ -400,6 +402,8 @@
 label_blocked_by: חסום ע"י
 label_precedes: מקדים את
 label_follows: עוקב אחרי
+label_parents: child of
+label_children: parent of
 label_end_to_start: מהתחלה לסוף
 label_end_to_end: מהסוף לסוף
 label_start_to_start: מהתחלה להתחלה
@@ -617,4 +621,5 @@
 setting_default_projects_public: פרויקטים חדשים הינם פומביים כברירת מחדל
 error_scm_annotate: "הכניסה לא קיימת או שלא ניתן לתאר אותה."
 label_planning: תכנון
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/fi.yml
===================================================================
--- lang/fi.yml	(revision 43)
+++ lang/fi.yml	(revision 59)
@@ -127,6 +127,8 @@
 field_assigned_to: Nimetty
 field_priority: Prioriteetti
 field_fixed_version: Kohde versio
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Käyttäjä
 field_role: Rooli
 field_homepage: Kotisivu
@@ -416,6 +418,8 @@
 label_blocked_by: estetty
 label_precedes: edeltää
 label_follows: seuraa
+label_parents: child of
+label_children: parent of
 label_end_to_start: loppu alkuun
 label_end_to_end: loppu loppuun
 label_start_to_start: alku alkuun
@@ -617,4 +621,5 @@
 label_overall_activity: Kokonaishistoria
 error_scm_annotate: "Merkintää ei ole tai siihen ei voi lisätä selityksiä."
 label_planning: Suunnittelu
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Tämän alaprojekti(t): %s tullaan myös poistamaan.'
Index: lang/en.yml
===================================================================
--- lang/en.yml	(revision 43)
+++ lang/en.yml	(revision 59)
@@ -129,6 +129,8 @@
 field_assigned_to: Assigned to
 field_priority: Priority
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: User
 field_role: Role
 field_homepage: Homepage
@@ -449,6 +451,8 @@
 label_blocked_by: blocked by
 label_precedes: precedes
 label_follows: follows
+label_parents: child of
+label_children: parent of
 label_end_to_start: end to start
 label_end_to_end: end to end
 label_start_to_start: start to start
@@ -557,6 +561,7 @@
 text_regexp_info: eg. ^[A-Z0-9]+$
 text_min_max_length_info: 0 means no restriction
 text_project_destroy_confirmation: Are you sure you want to delete this project and related data ?
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
 text_workflow_edit: Select a role and a tracker to edit the workflow
 text_are_you_sure: Are you sure ?
Index: lang/cs.yml
===================================================================
--- lang/cs.yml	(revision 43)
+++ lang/cs.yml	(revision 59)
@@ -132,6 +132,8 @@
 field_assigned_to: Přiřazeno
 field_priority: Priorita
 field_fixed_version: Přiřazeno k verzi
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Uživatel
 field_role: Role
 field_homepage: Homepage
@@ -452,6 +454,8 @@
 label_blocked_by: zablokován
 label_precedes: předchází
 label_follows: následuje
+label_parents: child of
+label_children: parent of
 label_end_to_start: od konce do začátku
 label_end_to_end: od konce do konce
 label_start_to_start: od začátku do začátku
@@ -622,4 +626,5 @@
 enumeration_activities: Aktivity (sledování času)
 error_scm_annotate: "Položka neexistuje nebo nemůže být komentována."
 label_planning: Plánování
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/fr.yml
===================================================================
--- lang/fr.yml	(revision 43)
+++ lang/fr.yml	(revision 59)
@@ -129,6 +129,8 @@
 field_assigned_to: Assigné à
 field_priority: Priorité
 field_fixed_version: Version cible
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Utilisateur
 field_role: Rôle
 field_homepage: Site web
@@ -449,6 +451,8 @@
 label_blocked_by: bloqué par
 label_precedes: précède
 label_follows: suit
+label_parents: child of
+label_children: parent of
 label_end_to_start: fin à début
 label_end_to_end: fin à fin
 label_start_to_start: début à début
@@ -557,6 +561,7 @@
 text_regexp_info: ex. ^[A-Z0-9]+$
 text_min_max_length_info: 0 pour aucune restriction
 text_project_destroy_confirmation: Etes-vous sûr de vouloir supprimer ce projet et toutes ses données ?
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Ses sous-projets: %s seront également supprimés.'
 text_workflow_edit: Sélectionner un tracker et un rôle pour éditer le workflow
 text_are_you_sure: Etes-vous sûr ?
Index: lang/es.yml
===================================================================
--- lang/es.yml	(revision 43)
+++ lang/es.yml	(revision 59)
@@ -115,6 +115,8 @@
 field_assigned_to: Asignado a
 field_priority: Prioridad
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Usuario
 field_role: Perfil
 field_homepage: Sitio web
@@ -386,6 +388,8 @@
 label_blocked_by: bloqueado por
 label_precedes: anterior a
 label_follows: posterior a 
+label_parents: child of
+label_children: parent of
 label_end_to_start: fin a principio
 label_end_to_end: fin a fin
 label_start_to_start: principio a principio
@@ -620,4 +624,5 @@
 setting_default_projects_public: Los proyectos nuevos son públicos por defecto 
 error_scm_annotate: "No existe la entrada o no ha podido ser anotada"
 label_planning: Planificación
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Sus subprojectos: %s también se eliminarán' 
Index: lang/nl.yml
===================================================================
--- lang/nl.yml	(revision 43)
+++ lang/nl.yml	(revision 59)
@@ -118,6 +118,8 @@
 field_assigned_to: Toegewezen aan
 field_priority: Prioriteit
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Gebruiker
 field_role: Rol
 field_homepage: Homepage
@@ -395,6 +397,8 @@
 label_blocked_by: geblokkeerd door
 label_precedes: gaat vooraf aan
 label_follows: volgt op
+label_parents: child of
+label_children: parent of
 label_end_to_start: eind tot start
 label_end_to_end: eind tot eind
 label_start_to_start: start tot start
@@ -618,4 +622,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/ko.yml
===================================================================
--- lang/ko.yml	(revision 43)
+++ lang/ko.yml	(revision 59)
@@ -120,6 +120,8 @@
 field_assigned_to: 담당자
 field_priority: 우선순위
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: 유저
 field_role: 역할
 field_homepage: 홈페이지
@@ -402,6 +404,8 @@
 label_blocked_by: 막고 있는 이슈
 label_precedes: 다음 이슈보다 앞서서 처리해야 함.
 label_follows: 선처리 이슈
+label_parents: child of
+label_children: parent of
 label_end_to_start: end to start
 label_end_to_end: end to end
 label_start_to_start: start to start
@@ -617,4 +621,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/zh-tw.yml
===================================================================
--- lang/zh-tw.yml	(revision 43)
+++ lang/zh-tw.yml	(revision 59)
@@ -131,6 +131,8 @@
 field_assigned_to: 分派給
 field_priority: 優先權
 field_fixed_version: 版本
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: 用戶
 field_role: 角色
 field_homepage: 網站首頁
@@ -453,6 +455,8 @@
 label_blocked_by: 被阻擋
 label_precedes: 優先於
 label_follows: 跟隨於
+label_parents: child of
+label_children: parent of
 label_end_to_start: end to start
 label_end_to_end: end to end
 label_start_to_start: start to start
@@ -561,6 +565,7 @@
 text_regexp_info: eg. ^[A-Z0-9]+$
 text_min_max_length_info: 0 代表「不限制」
 text_project_destroy_confirmation: 您確定要刪除這個專案和其他相關資料？
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: '下列子專案： %s 將一併被刪除。'
 text_workflow_edit: 選擇角色與追蹤標籤以設定其工作流程
 text_are_you_sure: 確定執行？
Index: lang/pl.yml
===================================================================
--- lang/pl.yml	(revision 43)
+++ lang/pl.yml	(revision 59)
@@ -115,6 +115,8 @@
 field_assigned_to: Przydzielony do
 field_priority: Priorytet
 field_fixed_version: Wersja docelowa
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Użytkownik
 field_role: Rola
 field_homepage: Strona www
@@ -386,6 +388,8 @@
 label_blocked_by: zablokowane przez
 label_precedes: poprzedza
 label_follows: podąża
+label_parents: child of
+label_children: parent of
 label_end_to_start: koniec do początku
 label_end_to_end: koniec do końca
 label_start_to_start: początek do początku
@@ -617,4 +621,5 @@
 setting_default_projects_public: Nowe projekty są domyślnie publiczne
 error_scm_annotate: "Wpis nie istnieje lub nie można do niego dodawać adnotacji."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: lang/th.yml
===================================================================
--- lang/th.yml	(revision 43)
+++ lang/th.yml	(revision 59)
@@ -129,6 +129,8 @@
 field_assigned_to: มอบหมายให้
 field_priority: ความสำคัญ
 field_fixed_version: รุ่น
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: ผู้ใช้
 field_role: บทบาท
 field_homepage: หน้าแรก
@@ -451,6 +453,8 @@
 label_blocked_by: กีดกันโดย
 label_precedes: นำหน้า
 label_follows: ตามหลัง
+label_parents: child of
+label_children: parent of
 label_end_to_start: จบ-เริ่ม
 label_end_to_end: จบ-จบ
 label_start_to_start: เริ่ม-เริ่ม
@@ -559,6 +563,7 @@
 text_regexp_info: ตัวอย่าง ^[A-Z0-9]+$
 text_min_max_length_info: 0 หมายถึงไม่จำกัด
 text_project_destroy_confirmation: คุณแน่ใจไหมว่าต้องการลบโครงการและข้อมูลที่เกี่ยวข้่อง ?
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'โครงการย่อย: %s จะถูกลบด้วย.'
 text_workflow_edit: เลือกบทบาทและการติดตาม เพื่อแก้ไขลำดับงาน
 text_are_you_sure: คุณแน่ใจไหม ?
Index: lang/no.yml
===================================================================
--- lang/no.yml	(revision 43)
+++ lang/no.yml	(revision 59)
@@ -131,6 +131,8 @@
 field_assigned_to: Tildelt til
 field_priority: Prioritet
 field_fixed_version: Mål-versjon
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Bruker
 field_role: Rolle
 field_homepage: Hjemmeside
@@ -453,6 +455,8 @@
 label_blocked_by: blokkert av
 label_precedes: kommer før
 label_follows: følger
+label_parents: child of
+label_children: parent of
 label_end_to_start: slutt til start
 label_end_to_end: slutt til slutt
 label_start_to_start: start til start
@@ -561,6 +565,7 @@
 text_regexp_info: eg. ^[A-Z0-9]+$
 text_min_max_length_info: 0 betyr ingen begrensning
 text_project_destroy_confirmation: Er du sikker på at du vil slette dette prosjekter og alle relatert data ?
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Underprojekt(ene): %s vil også bli slettet.'
 text_workflow_edit: Velg en rolle og en sakstype for å endre arbeidsflyten
 text_are_you_sure: Er du sikker ?
Index: lang/it.yml
===================================================================
--- lang/it.yml	(revision 43)
+++ lang/it.yml	(revision 59)
@@ -118,6 +118,8 @@
 field_assigned_to: Assegnato a
 field_priority: Priorita'
 field_fixed_version: Target version
+field_parent_issue: Child of
+field_potential_parent: Potential parent
 field_user: Utente
 field_role: Ruolo
 field_homepage: Homepage
@@ -395,6 +397,8 @@
 label_blocked_by: blocked by
 label_precedes: precedes
 label_follows: follows
+label_parents: child of
+label_children: parent of
 label_end_to_start: end to start
 label_end_to_end: end to end
 label_start_to_start: start to start
@@ -617,4 +621,5 @@
 setting_default_projects_public: New projects are public by default
 error_scm_annotate: "The entry does not exist or can not be annotated."
 label_planning: Planning
+error_issue_can_have_only_one_parent: allows only one relation (a task can have only one parent).
 text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.'
Index: db/migrate/093_add_potential_parent_to_issues.rb
===================================================================
--- db/migrate/093_add_potential_parent_to_issues.rb	(revision 0)
+++ db/migrate/093_add_potential_parent_to_issues.rb	(revision 59)
@@ -0,0 +1,9 @@
+class AddPotentialParentToIssues < ActiveRecord::Migration
+  def self.up
+    add_column :issues, :potential_parent, :boolean
+  end
+
+  def self.down
+    remove_column :issues, :potential_parent
+  end
+end
Index: lib/redmine.rb
===================================================================
--- lib/redmine.rb	(revision 43)
+++ lib/redmine.rb	(revision 59)
@@ -32,7 +32,7 @@
                                   :queries => :index,
                                   :reports => :issue_report}, :public => true                    
     map.permission :add_issues, {:issues => :new}
-    map.permission :edit_issues, {:issues => [:edit, :bulk_edit, :destroy_attachment]}
+    map.permission :edit_issues, {:issues => [:edit, :bulk_edit, :destroy_attachment, :update_subject]}
     map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
     map.permission :add_issue_notes, {:issues => :edit}
     map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
Index: public/images/contract.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: public/images/contract.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: public/stylesheets/application.css
===================================================================
--- public/stylesheets/application.css	(revision 43)
+++ public/stylesheets/application.css	(revision 59)
@@ -600,3 +600,44 @@
   #main { background: #fff; }
   #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; }
 }
+
+/***** Subtasks *****/
+/*blocks composed of icon (+, - or none), project identification (if there is one) and link to the task*/
+.issue-subject-level-1, .issue-subject-level-1 .issue-subject { 
+margin-left: 0em;
+}
+
+.issue-subject-level-2, .issue-subject-level-2 .issue-subject { 
+margin-left: 2em;
+}
+
+.issue-subject-level-3, .issue-subject-level-3 .issue-subject { 
+margin-left: 4em;
+}
+
+.issue-subject-level-4, .issue-subject-level-4 .issue-subject { 
+margin-left: 6em;
+}
+
+.issue-subject-level-5, .issue-subject-level-5 .issue-subject { 
+margin-left: 8em;
+}
+
+.expanded-issue {
+	background-image: url(contract.png);
+	background-repeat: no-repeat;
+}
+
+.contracted-issue {
+	background-image: url(expand.png);
+	background-repeat: no-repeat;
+}
+
+.expand-icon, .contract-icon{
+	position: absolute;
+}
+
+/*text after the icon, which needs to be indented so that all its lines stay completely after the icon*/
+.issue-subject{
+	padding-left: 1em;
+}
\ No newline at end of file

