From f5aa16541e6901d2fc543f9044be1c898365b61e Mon Sep 17 00:00:00 2001
From: svncommit <devs@roundcube.net>
Date: Thu, 28 Aug 2008 04:15:31 -0400
Subject: [PATCH] Add folder hierarchy collapsing.

---
 CHANGELOG                                |    4 ++
 index.php                                |    8 ++++
 program/include/html.php                 |    4 +-
 skins/default/images/icons/expanded.png  |    0 
 program/include/main.inc                 |   12 +++++-
 skins/default/images/icons/collapsed.png |    0 
 skins/default/mail.css                   |   28 ++++++++++++++
 program/js/app.js                        |   36 +++++++++++++++++-
 8 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 5367fab..69254a6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,10 @@
 CHANGELOG RoundCube Webmail
 ---------------------------
 
+2008/08/28 (robin)
+----------
+- Added folder hierarchy collapsing
+
 2008/08/27 (alec)
 ----------
 - Added options to use syslog instead of log file (#1484850)
diff --git a/index.php b/index.php
index 05ef875..aa6bf12 100644
--- a/index.php
+++ b/index.php
@@ -201,6 +201,14 @@
   )
 );
 
+// save preference value
+if ($RCMAIL->action=='save-pref')
+  {
+  $USER->save_prefs(array(get_input_value('_name', RCUBE_INPUT_POST) => get_input_value('_value', RCUBE_INPUT_POST)));
+  $OUTPUT->reset();
+  $OUTPUT->send();
+  }
+
 // include task specific functions
 include_once 'program/steps/'.$RCMAIL->task.'/func.inc';
 
diff --git a/program/include/html.php b/program/include/html.php
index 704d10a..7ab82d8 100644
--- a/program/include/html.php
+++ b/program/include/html.php
@@ -98,7 +98,7 @@
         if (is_string($attr)) {
             $attr = array('class' => $attr);
         }
-        return self::tag('div', $attr, $cont, self::$common_attrib);
+        return self::tag('div', $attr, $cont, array_merge(self::$common_attrib, array('onclick')));
     }
 
     /**
@@ -644,4 +644,4 @@
     }
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/program/include/main.inc b/program/include/main.inc
index 2b47978..869921e 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -1000,7 +1000,7 @@
  */
 function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, $maxlength, $realnames=false, $nestLevel=0)
   {
-  global $COMM_PATH, $IMAP, $CONFIG, $OUTPUT;
+  global $COMM_PATH, $IMAP, $CONFIG, $OUTPUT, $RCMAIL;
 
   $idx = 0;
   $out = '';
@@ -1046,11 +1046,17 @@
     if ($folder['id'] == $mbox_name)
       $classes[] = 'selected';
 
+    $collapsed = preg_match('/&'.rawurlencode($folder['id']).'&/', $RCMAIL->config->get('collapsed_folders'));
+
     $js_name = JQ($folder['id']);
     $out .= html::tag('li', array(
         'id' => "rcmli".$folder_id,
         'class' => join(' ', $classes),
         'noclose' => true),
+      html::div(array(
+        'class' => empty($folder['folders']) ? 'nocollapse' : ($collapsed ? 'collapsed' : 'expanded'),
+        'onclick' => sprintf("%s.command('collapse-folder', '%s')", JS_OBJECT_NAME, $js_name)
+      ), '&nbsp;') .
       html::a(array(
         'href' => rcmail_url('', array('_mbox' => $folder['id'])),
         'onclick' => sprintf("return %s.command('list','%s',this)", JS_OBJECT_NAME, $js_name),
@@ -1061,12 +1067,14 @@
       ), Q($foldername)));
     
     if (!empty($folder['folders']))
-      $out .= "\n<ul>\n" . rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $maxlength, $realnames, $nestLevel+1) . "</ul>\n";
+      $out .= "\n<ul" . ($collapsed ? " style=\"display: none;\"" : "") . ">\n" . rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $maxlength, $realnames, $nestLevel+1) . "</ul>\n";
 
     $out .= "</li>\n";
     $idx++;
     }
 
+  $OUTPUT->set_env('collapsed_folders', $RCMAIL->config->get('collapsed_folders'));
+
   return $out;
   }
 
diff --git a/program/js/app.js b/program/js/app.js
index b5073da..f81f19d 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -151,7 +151,7 @@
           this.set_message_coltypes(this.env.coltypes);
 
         // enable mail commands
-        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', true);
+        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
 
         if (this.env.search_text != null && document.getElementById('quicksearchbox') != null)
           document.getElementById('quicksearchbox').value = this.env.search_text;
@@ -982,6 +982,11 @@
           this.list_contacts(this.env.source);
         break;
 
+      // collapse/expand folder
+      case 'collapse-folder':
+        if (props)
+          this.collapse_folder(props);
+        break;
 
       // user settings commands
       case 'preferences':
@@ -1140,6 +1145,33 @@
     var li;
     if (this.drag_active && (li = this.get_folder_li(id)))
       this.set_classname(li, 'droptarget', false);
+    }
+
+  this.collapse_folder = function(id)
+    {
+    var div;
+    if ((li = this.get_folder_li(id)) &&
+        (div = li.getElementsByTagName("div")[0]) &&
+        (div.className.match(/collapsed/) || div.className.match(/expanded/)))
+      {
+      var ul = li.getElementsByTagName("ul")[0];
+      if (div.className.match(/collapsed/))
+        {
+        ul.style.display = '';
+        this.set_classname(div, 'collapsed', false);
+        this.set_classname(div, 'expanded', true);
+        var reg = new RegExp('&'+escape(id)+'&');
+        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
+        }
+      else
+        {
+        ul.style.display = 'none';
+        this.set_classname(div, 'expanded', false);
+        this.set_classname(div, 'collapsed', true);
+        this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+escape(id)+'&');
+        }
+      this.http_post('save-pref', '_name=collapsed_folders&_value='+escape(this.env.collapsed_folders));
+      }
     }
 
   // onmouseup handler for folder list item
@@ -3441,7 +3473,7 @@
     if (item = this.get_folder_li(mbox))
       {
       // set new text
-      text_obj = item.firstChild;
+      text_obj = item.firstChild.nextSibling;
       reg = /\s+\([0-9]+\)$/i;
 
       if (count && text_obj.innerHTML.match(reg))
diff --git a/skins/default/images/icons/collapsed.png b/skins/default/images/icons/collapsed.png
new file mode 100644
index 0000000..e483b17
--- /dev/null
+++ b/skins/default/images/icons/collapsed.png
Binary files differ
diff --git a/skins/default/images/icons/expanded.png b/skins/default/images/icons/expanded.png
new file mode 100644
index 0000000..74726c8
--- /dev/null
+++ b/skins/default/images/icons/expanded.png
Binary files differ
diff --git a/skins/default/mail.css b/skins/default/mail.css
index e58af7d..69c1809 100644
--- a/skins/default/mail.css
+++ b/skins/default/mail.css
@@ -284,6 +284,32 @@
   border-bottom: 1px solid #EBEBEB;
 }
 
+#mailboxlist li div
+{
+  position: absolute;
+  padding-left: 10px;
+  padding-top: 2px;
+  padding-bottom: 2px;
+  margin-right: 2px;
+  width: 12px;
+}
+
+#mailboxlist li div.collapsed,
+#mailboxlist li div.expanded
+{
+  cursor: pointer;
+}
+
+#mailboxlist li div.collapsed
+{
+  background: url(images/icons/collapsed.png) bottom right no-repeat;
+}
+
+#mailboxlist li div.expanded
+{
+  background: url(images/icons/expanded.png) bottom right no-repeat;
+}
+
 #mailboxlist li.inbox
 {
   background-image: url(images/icons/folder-inbox.png);
@@ -316,6 +342,8 @@
   padding-top: 2px;
   padding-bottom: 2px;
   text-decoration: none;
+  /* css hack for IE */
+  margin-top: expression('-12px');
 }
 
 #mailboxlist li.unread

--
Gitblit v1.9.1