From c83535876c0a8903f1e77effef90d765eb96ab7f Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Mon, 07 Apr 2014 06:53:06 -0400
Subject: [PATCH] Small refactoring of message list column configuration; fixes table column resorting issues with hidden 'folder' column

---
 program/steps/mail/func.inc |   27 ++++++---
 program/js/app.js           |   86 +++++++++++++++++++---------
 skins/larry/ui.js           |   37 ++++++------
 3 files changed, 96 insertions(+), 54 deletions(-)

diff --git a/program/js/app.js b/program/js/app.js
index f548ad8..7c27d21 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -213,6 +213,11 @@
             .addEventListener('listupdate', function(o) { p.triggerEvent('listupdate', o); })
             .init();
 
+          // TODO: this should go into the list-widget code
+          $(this.message_list.thead).on('click', 'a.sortcol', function(e){
+            return rcmail.command('sort', $(this).attr('rel'), this);
+          });
+
           document.onmouseup = function(e){ return p.doc_mouse_up(e); };
           this.gui_objects.messagelist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
 
@@ -1687,21 +1692,21 @@
   {
     var i, found, name, cols = list.thead.rows[0].cells;
 
-    this.env.coltypes = [];
+    this.env.listcols = [];
 
     for (i=0; i<cols.length; i++)
       if (cols[i].id && cols[i].id.startsWith('rcm')) {
         name = cols[i].id.slice(3);
-        this.env.coltypes.push(name);
+        this.env.listcols.push(name);
       }
 
-    if ((found = $.inArray('flag', this.env.coltypes)) >= 0)
+    if ((found = $.inArray('flag', this.env.listcols)) >= 0)
       this.env.flagged_col = found;
 
-    if ((found = $.inArray('subject', this.env.coltypes)) >= 0)
+    if ((found = $.inArray('subject', this.env.listcols)) >= 0)
       this.env.subject_col = found;
 
-    this.command('save-pref', { name: 'list_cols', value: this.env.coltypes, session: 'list_attrib/columns' });
+    this.command('save-pref', { name: 'list_cols', value: this.env.listcols, session: 'list_attrib/columns' });
   };
 
   this.check_droptarget = function(id)
@@ -1927,9 +1932,13 @@
     }
 
     // add each submitted col
-    for (n in this.env.coltypes) {
-      c = this.env.coltypes[n];
+    for (n in this.env.listcols) {
+      c = this.env.listcols[n];
       col = { className: String(c).toLowerCase() };
+
+      if (this.env.coltypes[c] && this.env.coltypes[c].hidden) {
+        col.className += ' hidden';
+      }
 
       if (c == 'flag') {
         css_class = (flags.flagged ? 'flagged' : 'unflagged');
@@ -2019,7 +2028,7 @@
 
     if (cols && cols.length) {
       // make sure new columns are added at the end of the list
-      var i, idx, name, newcols = [], oldcols = this.env.coltypes;
+      var i, idx, name, newcols = [], oldcols = this.env.listcols;
       for (i=0; i<oldcols.length; i++) {
         name = oldcols[i];
         idx = $.inArray(name, cols);
@@ -4223,6 +4232,33 @@
     this.enable_command('set-listmode', this.env.threads);
   };
 
+  this.set_searchscope = function(scope)
+  {
+    var old = this.env.search_scope;
+    this.env.search_scope = scope;
+
+    // re-send search query with new scope
+    if (scope != old && this.env.search_request) {
+      this.qsearch(this.gui_objects.qsearchbox.value);
+      if (scope == 'base')
+        this.select_folder(this.env.mailbox, '', true);
+    }
+  };
+
+  this.set_searchmods = function(mods)
+  {
+    var mbox = rcmail.env.mailbox,
+      scope = this.env.search_scope || 'base';
+
+    if (scope == 'all')
+      mbox = '*';
+
+    if (!this.env.search_mods)
+      this.env.search_mods = {};
+
+    this.env.search_mods[mbox] = mods;
+  };
+
   this.sent_successfully = function(type, msg, folders)
   {
     this.display_message(msg, type);
@@ -6413,18 +6449,18 @@
 
   // for reordering column array (Konqueror workaround)
   // and for setting some message list global variables
-  this.set_message_coltypes = function(coltypes, repl, smart_col)
+  this.set_message_coltypes = function(listcols, repl, smart_col)
   {
     var list = this.message_list,
       thead = list ? list.thead : null,
-      cell, col, n, len, th, tr;
+      repl, cell, col, n, len, tr;
 
-    this.env.coltypes = coltypes;
+    this.env.listcols = listcols;
 
     // replace old column headers
     if (thead) {
       if (repl) {
-        th = document.createElement('thead');
+        thead.innerHTML = '';
         tr = document.createElement('tr');
 
         for (c=0, len=repl.length; c < len; c++) {
@@ -6434,20 +6470,13 @@
           if (repl[c].className) cell.className = repl[c].className;
           tr.appendChild(cell);
         }
-        th.appendChild(tr);
-        thead.parentNode.replaceChild(th, thead);
-        list.thead = thead = th;
+        thead.appendChild(tr);
       }
 
-      for (n=0, len=this.env.coltypes.length; n<len; n++) {
-        col = this.env.coltypes[n];
+      for (n=0, len=this.env.listcols.length; n<len; n++) {
+        col = this.env.listcols[n];
         if ((cell = thead.rows[0].cells[n]) && (col == 'from' || col == 'to' || col == 'fromto')) {
-          cell.id = 'rcm'+col;
-          $('span,a', cell).text(this.get_label(col == 'fromto' ? smart_col : col));
-          // if we have links for sorting, it's a bit more complicated...
-          $('a', cell).click(function(){
-            return rcmail.command('sort', this.id.replace(/^rcm/, ''), this);
-          });
+          $(cell).attr('rel', col).find('span,a').text(this.get_label(col == 'fromto' ? smart_col : col));
         }
       }
     }
@@ -6456,18 +6485,21 @@
     this.env.flagged_col = null;
     this.env.status_col = null;
 
-    if ((n = $.inArray('subject', this.env.coltypes)) >= 0) {
+    if (this.env.coltypes.folder)
+      this.env.coltypes.folder.hidden = !(this.env.search_request || this.env.search_id) || this.env.search_scope == 'base';
+
+    if ((n = $.inArray('subject', this.env.listcols)) >= 0) {
       this.env.subject_col = n;
       if (list)
         list.subject_col = n;
     }
-    if ((n = $.inArray('flag', this.env.coltypes)) >= 0)
+    if ((n = $.inArray('flag', this.env.listcols)) >= 0)
       this.env.flagged_col = n;
-    if ((n = $.inArray('status', this.env.coltypes)) >= 0)
+    if ((n = $.inArray('status', this.env.listcols)) >= 0)
       this.env.status_col = n;
 
     if (list) {
-      list.hide_column('folder', !(this.env.search_request || this.env.search_id) || this.env.search_scope == 'base');
+      list.hide_column('folder', this.env.coltypes.folder && this.env.coltypes.folder.hidden);
       list.init_header();
     }
   };
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 066d381..7c9b491 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -346,7 +346,7 @@
     $OUTPUT->set_env('sort_col', $_SESSION['sort_col']);
     $OUTPUT->set_env('sort_order', $_SESSION['sort_order']);
     $OUTPUT->set_env('messages', array());
-    $OUTPUT->set_env('coltypes', $a_show_cols);
+    $OUTPUT->set_env('listcols', $a_show_cols);
 
     $OUTPUT->include_script('list.js');
 
@@ -549,7 +549,7 @@
         $list_menu = '';
     }
 
-    $cells = array();
+    $cells = $coltypes = array();
 
     // get name of smart From/To column in folder context
     if (array_search('fromto', $a_show_cols) !== false) {
@@ -557,32 +557,39 @@
     }
 
     foreach ($a_show_cols as $col) {
+        $label = '';
+        $sortable = false;
+
         // get column name
         switch ($col) {
         case 'flag':
-            $col_name = '<span class="flagged">&nbsp;</span>';
+            $col_name = html::span('flagged', '&nbsp;');
             break;
         case 'attachment':
         case 'priority':
         case 'status':
-            $col_name = '<span class="' . $col .'">&nbsp;</span>';
+            $col_name = html::span($col, '&nbsp;');
             break;
         case 'threads':
             $col_name = $list_menu;
             break;
         case 'fromto':
-            $col_name = rcube::Q($RCMAIL->gettext($smart_col));
+            $label = $RCMAIL->gettext($smart_col);
+            $col_name = rcube::Q($label);
             break;
         default:
-            $col_name = rcube::Q($RCMAIL->gettext($col));
+            $label = $RCMAIL->gettext($col);
+            $col_name = rcube::Q($label);
         }
 
         // make sort links
         if (in_array($col, $a_sort_cols)) {
+            $sortable = true;
             $col_name = html::a(array(
-                    'href'    => "./#sort",
-                    'onclick' => 'return '.rcmail_output::JS_OBJECT_NAME.".command('sort','".$col."',this)",
-                    'title'   => $RCMAIL->gettext('sortby')
+                    'href'  => "./#sort",
+                    'class' => 'sortcol',
+                    'rel'   => $col,
+                    'title' => $RCMAIL->gettext('sortby')
                 ), $col_name);
         }
         else if ($col_name[0] != '<') {
@@ -594,8 +601,10 @@
 
         // put it all together
         $cells[] = array('className' => $class_name, 'id' => "rcm$col", 'html' => $col_name);
+        $coltypes[$col] = array('className' => $class_name, 'id' => "rcm$col", 'label' => $label, 'sortable' => $sortable);
     }
 
+    $RCMAIL->output->set_env('coltypes', $coltypes);
     return $cells;
 }
 
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index 74aef8d..b002311 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -770,7 +770,7 @@
           mbox = '*';
         mods = mods[mbox] ? mods[mbox] : mods['*'];
         all = 'text';
-        $('#s_scope_'+scope).attr('checked',true);
+        $('input:radio[name="s_scope"]').prop('checked', false).filter('#s_scope_'+scope).prop('checked', true);
       }
       else {
         all = '*';
@@ -861,7 +861,7 @@
 
     // set checkboxes
     $('input[name="list_col[]"]').each(function() {
-      $(this).prop('checked', $.inArray(this.value, rcmail.env.coltypes) != -1);
+      $(this).prop('checked', $.inArray(this.value, rcmail.env.listcols) != -1);
     });
 
     $dialog.dialog({
@@ -927,28 +927,29 @@
       m[elem.value] = 1;
 
     // mark all fields
-    if (elem.value != all)
-      return;
+    if (elem.value == all) {
+      $('input:checkbox[name="s_mods[]"]').map(function() {
+        if (this == elem)
+          return;
 
-    $('input:checkbox[name="s_mods[]"]').map(function() {
-      if (this == elem)
-        return;
+        this.checked = true;
+        if (elem.checked) {
+          this.disabled = true;
+          delete m[this.value];
+        }
+        else {
+          this.disabled = false;
+          m[this.value] = 1;
+        }
+      });
+    }
 
-      this.checked = true;
-      if (elem.checked) {
-        this.disabled = true;
-        delete m[this.value];
-      }
-      else {
-        this.disabled = false;
-        m[this.value] = 1;
-      }
-    });
+    rcmail.set_searchmods(m);
   }
 
   function set_searchscope(elem)
   {
-    rcmail.env.search_scope = elem.value;
+    rcmail.set_searchscope(elem.value);
   }
 
   function push_contactgroup(p)

--
Gitblit v1.9.1