diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 1f72e8f..e1c3460 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -22,7 +22,7 @@ class IssuesController < ApplicationController
   before_filter :find_issue, :only => [:show, :edit, :reply]
   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, :update_column]
   before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
   accept_key_auth :index, :show, :changes
 
@@ -415,31 +415,54 @@ class IssuesController < ApplicationController
   end
   
   def context_menu
-    @issues = Issue.find_all_by_id(params[:ids], :include => :project)
-    if (@issues.size == 1)
-      @issue = @issues.first
-      @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
+    # Wants issue context menu
+    if params[:header_context_menu].nil? && !params[:ids].blank?
+      @issues = Issue.find_all_by_id(params[:ids], :include => :project)
+      if (@issues.size == 1)
+        @issue = @issues.first
+        @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
+      end
+      projects = @issues.collect(&:project).compact.uniq
+      @project = projects.first if projects.size == 1
+
+      @can = {
+        :edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
+        :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
+        :update => (@project && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && @allowed_statuses && !@allowed_statuses.empty?))),
+        :move => (@project && User.current.allowed_to?(:move_issues, @project)),
+        :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
+        :delete => (@project && User.current.allowed_to?(:delete_issues, @project))
+      }
+
+      if @project
+        @assignables = @project.assignable_users
+        @assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
+      end
+
+      @priorities = IssuePriority.all.reverse
+      @statuses = IssueStatus.find(:all, :order => 'position')
+      @back = params[:back_url] || request.env['HTTP_REFERER']
+      
+      render :layout => false
+    else
+      # Wants a header context menu
+      find_project unless params[:project_id].blank?
+      retrieve_query
+      @back = params[:back_url] || request.env['HTTP_REFERER']
+      
+      render :action => 'header_context_menu', :layout => false
     end
-    projects = @issues.collect(&:project).compact.uniq
-    @project = projects.first if projects.size == 1
+  end
+
+  # Takes the params and stores the updated column information from the index
+  def update_column
+    find_project unless params[:project_id].blank?
+    retrieve_query
 
-    @can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
-            :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
-            :update => (@project && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && @allowed_statuses && !@allowed_statuses.empty?))),
-            :move => (@project && User.current.allowed_to?(:move_issues, @project)),
-            :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
-            :delete => (@project && User.current.allowed_to?(:delete_issues, @project))
-            }
-    if @project
-      @assignables = @project.assignable_users
-      @assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
+    respond_to do |format|
+      format.html { redirect_to :action => 'index', :project_id => params[:project_id] }
+      format.js {render(:update) {|page| page.redirect_to :action => 'index', :project_id => params[:project_id] }}
     end
-    
-    @priorities = IssuePriority.all.reverse
-    @statuses = IssueStatus.find(:all, :order => 'position')
-    @back = params[:back_url] || request.env['HTTP_REFERER']
-    
-    render :layout => false
   end
 
   def update_form
@@ -498,13 +521,20 @@ private
       cond << " OR project_id = #{@project.id}" if @project
       @query = Query.find(params[:query_id], :conditions => cond)
       @query.project = @project
-      session[:query] = {:id => @query.id, :project_id => @query.project_id}
       sort_clear
+      @query.column_names = session[:query][:column_names] unless session[:query].nil? || session[:query][:column_names].nil? || session[:query][:id] != @query.id
+      
+      # Update column list
+      if params[:column].present?
+        @query.column_names = update_columns_from_session(@query, params[:column].to_sym)
+      end
+      session[:query] = {:id => @query.id, :project_id => @query.project_id, :column_names => @query.column_names}
     else
       if params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
         # Give it a name, required to be valid
         @query = Query.new(:name => "_")
         @query.project = @project
+        @query.column_names = session[:query][:column_names] unless session[:query].nil? || session[:query][:column_names].nil? || session[:query][:id] != @query.id
         if params[:fields] and params[:fields].is_a? Array
           params[:fields].each do |field|
             @query.add_filter(field, params[:operators][field], params[:values][field])
@@ -514,13 +544,46 @@ private
             @query.add_short_filter(field, params[field]) if params[field]
           end
         end
+
+        # Update column list
+        if params[:column].present?
+          columns = update_columns_from_session(@query, params[:column].to_sym)
+
+          # Order columns based on the Query ordering
+          columns = @query.available_columns.select {|c| columns.include?(c.name)}.collect(&:name)
+
+          @query.column_names = columns
+        end
+        
         @query.group_by = params[:group_by]
-        session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by}
+        session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
       else
         @query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
-        @query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters], :group_by => session[:query][:group_by])
+        @query.column_names = session[:query][:column_names] if session[:query][:id] && session[:query][:column_names]
+        @query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
         @query.project = @project
       end
     end
   end
+  
+  def update_columns_from_session(query, column_name)
+    # Force to symbol
+    column_symbol = column_name.to_sym
+    
+    columns = @query.columns.collect(&:name) # Current columns
+    # Columns from session
+    if session[:query] && session[:query][:column_names]
+      # Set Union
+      columns = columns | session[:query][:column_names]
+    end
+    
+    # Delete if the update column exists, otherwise add it
+    if columns.include?(column_symbol)
+      columns.delete(column_symbol)
+    else
+      columns << column_symbol
+    end
+    
+    return columns
+  end
 end
diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb
index 16755a1..b634c3b 100644
--- a/app/controllers/queries_controller.rb
+++ b/app/controllers/queries_controller.rb
@@ -27,6 +27,11 @@ class QueriesController < ApplicationController
     @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
     @query.column_names = nil if params[:default_columns]
     
+    # Use the columns from the session if they are set
+    if @query.column_names.nil? && session[:query] && session[:query][:column_names]
+      @query.column_names = session[:query][:column_names]
+    end
+
     params[:fields].each do |field|
       @query.add_filter(field, params[:operators][field], params[:values][field])
     end if params[:fields]
@@ -52,6 +57,8 @@ class QueriesController < ApplicationController
       @query.column_names = nil if params[:default_columns]
       
       if @query.save
+        # Clear the session[:query] to use the saved query
+        session[:query] = { :id => @query.id, :project_id => @query.project_id, :column_names => @query.column_names}
         flash[:notice] = l(:notice_successful_update)
         redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
       end
diff --git a/app/views/issues/_list.rhtml b/app/views/issues/_list.rhtml
index f51a708..5c0ce26 100644
--- a/app/views/issues/_list.rhtml
+++ b/app/views/issues/_list.rhtml
@@ -1,8 +1,11 @@
 <% form_tag({}) do -%>	
 <%= hidden_field_tag 'back_url', url_for(params) %>
 <table class="list issues">
-    <thead><tr>
-        <th><%= link_to image_tag('toggle_check.png'), {}, :onclick => 'toggleIssuesSelection(Element.up(this, "form")); return false;',
+    <thead><tr id="issue-header" class="no-select hascontextmenu">
+      <th><%= check_box_tag("header_context_menu", false, false, :style => 'display: none;', :class => 'no-select' ) %>
+          <%= hidden_field_tag("query_id", @query.id) if @query %>
+          <%= hidden_field_tag("project_id", @project.id) if @project %>
+          <%= link_to image_tag('toggle_check.png'), {}, :onclick => 'toggleIssuesSelection(this.up("form")); return false;',
                                                            :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
         </th>
 		<%= sort_header_tag('id', :caption => '#', :default_order => 'desc') %>
diff --git a/app/views/issues/header_context_menu.rhtml b/app/views/issues/header_context_menu.rhtml
new file mode 100644
index 0000000..e67e337
--- /dev/null
+++ b/app/views/issues/header_context_menu.rhtml
@@ -0,0 +1,22 @@
+<ul>
+  <% @query.available_columns.each do |column| %>
+  <li>
+    <%= link_to_remote(column.caption,
+                       {
+                        :url => {
+                          :controller => 'issues',
+                          :action => 'update_column',
+                          :project_id => @project,
+                          :set_filter => true,
+                          :column => column.name,
+                          :query_id => @query.id
+                        },
+                        :with => "Form.serialize('query_form')"
+                       },
+                       {
+                        :class => @query.columns.include?(column) ? 'icon-checked' : 'icon-none',
+                        :method => :post
+                       })%>
+  </li>
+  <% end %>
+</ul>
diff --git a/public/javascripts/context_menu.js b/public/javascripts/context_menu.js
index dac5076..4985192 100644
--- a/public/javascripts/context_menu.js
+++ b/public/javascripts/context_menu.js
@@ -34,7 +34,7 @@ ContextMenu.prototype = {
 		var tr = Event.findElement(e, 'tr');
 		if (tr == document || tr == undefined  || !tr.hasClassName('hascontextmenu')) { return; }
 		Event.stop(e);
-		if (!this.isSelected(tr)) {
+    	        if (!this.isSelected(tr)) {
 			this.unselectAll();
 			this.addSelection(tr);
 			this.lastSelected = tr;
@@ -48,7 +48,7 @@ ContextMenu.prototype = {
     if (window.opera && e.altKey) {	return; }
     if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) {      
       var tr = Event.findElement(e, 'tr');
-      if (tr!=null && tr!=document && tr.hasClassName('hascontextmenu')) {
+        if (tr!=null && tr!=document && tr.hasClassName('hascontextmenu') && !tr.hasClassName('no-select')) {
         // a row was clicked, check if the click was on checkbox
         var box = Event.findElement(e, 'input');
         if (box!=document && box!=undefined) {
@@ -155,7 +155,9 @@ ContextMenu.prototype = {
   },
   
   addSelection: function(tr) {
-    tr.addClassName('context-menu-selection');
+    if (!tr.hasClassName('no-select')) {
+      tr.addClassName('context-menu-selection');
+    }
     this.checkSelectionBox(tr, true);
   },
   
@@ -197,7 +199,7 @@ function toggleIssuesSelection(el) {
 		if (all_checked) {
 			boxes[i].checked = false;
 			boxes[i].up('tr').removeClassName('context-menu-selection');
-		} else if (boxes[i].checked == false) {
+		} else if (boxes[i].checked == false && !boxes[i].hasClassName('no-select')) {
 			boxes[i].checked = true;
 			boxes[i].up('tr').addClassName('context-menu-selection');
 		}
diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb
index 7356b13..30656f9 100644
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -1093,7 +1093,39 @@ class IssuesControllerTest < ActionController::TestCase
                             :attributes => { :href => '#',
                                              :class => 'icon-del disabled' }
   end
-  
+
+  def test_context_menu_headers
+    @request.session[:user_id] = 2
+    get :context_menu, :header_context_menu => '1'
+    assert_response :success
+    assert_template 'header_context_menu'
+
+    assert_select 'ul' do
+      assert_select 'a', 'Project'
+      assert_select 'a', 'Tracker'
+    end
+  end
+
+  def test_update_column_to_add_a_column
+    @request.session[:user_id] = 2
+    post :update_column, :project_id => 'ecookbook', :column => 'author'
+    assert_redirected_to :action =>'index', :project_id => 'ecookbook'
+
+    assert session[:query]
+    assert session[:query][:column_names]
+    assert session[:query][:column_names].include?(:author)
+  end
+
+  def test_update_column_to_remove_a_column
+    @request.session[:user_id] = 2
+    post :update_column, :project_id => 'ecookbook', :column => 'status'
+    assert_redirected_to :action =>'index', :project_id => 'ecookbook'
+
+    assert session[:query]
+    assert session[:query][:column_names]
+    assert !session[:query][:column_names].include?(:status)
+  end
+
   def test_destroy_routing
     assert_recognizes( #TODO: use DELETE on issue URI (need to change forms)
       {:controller => 'issues', :action => 'destroy', :id => '1'},
diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb
index af2a86e..a663cb3 100644
--- a/test/functional/queries_controller_test.rb
+++ b/test/functional/queries_controller_test.rb
@@ -58,6 +58,21 @@ class QueriesControllerTest < ActionController::TestCase
                                                  :disabled => nil }
   end
   
+  def test_get_new_project_query_with_columns_from_session
+    @request.session[:user_id] = 2
+    @request.session[:query] = {:column_names => ['tracker', 'subject']}
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select '#query_default_columns[checked=checked]', false
+
+    assert_select 'select#selected_columns' do
+      assert_select 'option[value=tracker]'
+      assert_select 'option[value=subject]'
+    end
+  end
+
   def test_new_project_public_query
     @request.session[:user_id] = 2
     post :new,

