Use Horde_Tree to render folder/search trees.
authorMichael M Slusarz <slusarz@curecanti.org>
Wed, 18 Aug 2010 18:51:07 +0000 (12:51 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 24 Aug 2010 06:00:58 +0000 (00:00 -0600)
This isn't complete yet.  TODO list:
1. Auto JSON loading of collapsed->expanded levels.
2. Save expanded/collapse information on folders page.
3. Use tree to render MIMP & Folder drop-down lists.

imp/folders-mimp.php
imp/folders.php
imp/js/search.js
imp/lib/Ajax/Application.php
imp/lib/Block/tree_folders.php
imp/lib/Imap/Tree.php
imp/lib/Ui/Folder.php [deleted file]
imp/search.php
imp/templates/imp/folders/folders.html [deleted file]
imp/templates/imp/search/search.html
imp/themes/screen.css

index 9402d7b..fa9812b 100644 (file)
@@ -49,7 +49,7 @@ $t = $injector->createInstance('Horde_Template');
 
 /* Start iterating through the list of mailboxes, displaying them. */
 $rows = array();
-foreach ($imptree->folderList($mask) as $val) {
+foreach ($imptree as $val) {
     $poll_info = $val->polled
         ? $val->poll_info
         : null;
index f42d945..a20044f 100644 (file)
@@ -354,9 +354,6 @@ if ($_SESSION['imp']['file_upload'] && ($vars->actionID == 'import_mbox')) {
     exit;
 }
 
-/* Build the folder tree. */
-$imaptree->setIteratorFilter(IMP_Imap_Tree::FLIST_CONTAINER | IMP_Imap_Tree::FLIST_VFOLDER | IMP_Imap_Tree::FLIST_EXPANDED);
-
 /* Prepare the header template. */
 $refresh_title = _("Reload View");
 $head_template = $injector->createInstance('Horde_Template');
@@ -399,13 +396,18 @@ $a_template->set('file_upload', $_SESSION['imp']['file_upload']);
 $a_template->set('expand_all', Horde::widget($folders_url_ob->copy()->add(array('actionID' => 'expand_all_folders', 'folders_token' => $folders_token)), _("Expand All Folders"), 'widget', '', '', _("Expand All"), true));
 $a_template->set('collapse_all', Horde::widget($folders_url_ob->copy()->add(array('actionID' => 'collapse_all_folders', 'folders_token' => $folders_token)), _("Collapse All Folders"), 'widget', '', '', _("Collapse All"), true));
 
-/* Get the tree images. */
-$imp_ui_folder = new IMP_Ui_Folder();
-$tree_imgs = $imp_ui_folder->getTreeImages($imaptree, array('expand_url' => $folders_url_ob));
+/* Build the folder tree. */
+// TODO: Javascript JSON loading; save expanded view.
+//$imaptree->setIteratorFilter(IMP_Imap_Tree::FLIST_CONTAINER | IMP_Imap_Tree::FLIST_VFOLDER | IMP_Imap_Tree::FLIST_EXPANDED);
+$imaptree->setIteratorFilter(IMP_Imap_Tree::FLIST_CONTAINER | IMP_Imap_Tree::FLIST_VFOLDER);
+
+$tree = $imaptree->createTree('imp_folders', array(
+    'checkbox' => true,
+    'editvfolder' => true,
+    'poll_info' => true
+));
 
-$displayNames = $fullNames = $newmsgs = $rows = array();
-$name_url = Horde::applicationUrl('mailbox.php');
-$rowct = 0;
+$displayNames = $fullNames = array();
 
 foreach ($imaptree as $key => $val) {
     $tmp = $displayNames[] = $val->display;
@@ -414,61 +416,17 @@ foreach ($imaptree as $key => $val) {
     if ($tmp != $tmp2) {
         $fullNames[$key] = $tmp2;
     }
-
-    $row = array();
-
-    $row['nocheckbox'] = !empty($val->vfolder);
-    if (!empty($val->vfolder) && $val->editvfolder) {
-        $imp_search = $injector->getInstance('IMP_Search');
-        $row['delvfolder'] = $imp_search->deleteUrl($val->value)->link(array('title' => _("Delete Virtual Folder"))) . _("Delete") . '</a>';
-        $row['editvfolder'] = $imp_search->editUrl($val->value)->link(array('title' => _("Edit Virtual Folder"))) . _("Edit") . '</a>';
-    }
-
-    $row['cname'] = 'item' . (++$rowct % 2);
-
-    if ($val->container) {
-        $row['name'] = $val->name;
-    } else {
-        /* Highlight line differently if folder/mailbox is unsubscribed. */
-        if ($showAll && $subscribe && !$val->sub) {
-            $row['cname'] .= ' folderunsub';
-        }
-
-        $row['name'] = $val->name;
-
-        if ($val->polled) {
-            $row['polled'] = true;
-
-            $poll_info = $val->poll_info;
-            if ($poll_info->recent) {
-                $newmsgs[$val->value] = $poll_info->recent;
-            }
-
-            if ($poll_info->unseen) {
-                $row['name'] = '<strong>' . $val->name . '</strong>';
-            }
-
-            $row['msgs'] = $poll_info->msgs;
-            $row['unseen'] = $poll_info->unseen;
-        }
-
-        $row['name'] = $name_url->copy()->add('mailbox', $val->value)->link(array('title' => $val->vfolder ? $val->label : $val->display)) . $row['name'] . '</a>';
-    }
-
-    $row['line'] = $tree_imgs[$key];
-
-    $rows[] = $row;
 }
 
 /* Check to see if user wants new mail notification */
-if (!empty($newmsgs)) {
+if (!empty($imaptree->recent)) {
     /* Open the mailbox R/W so we ensure the 'recent' flags are cleared from
      * the current mailbox. */
-    foreach ($newmsgs as $mbox => $nm) {
+    foreach ($imaptree->recent as $mbox => $nm) {
         $injector->getInstance('IMP_Imap')->getOb()->openMailbox($mbox, Horde_Imap_Client::OPEN_READWRITE);
     }
 
-    IMP::newmailAlerts($newmsgs);
+    IMP::newmailAlerts($imaptree->recent);
 }
 
 Horde::addInlineScript(array(
@@ -476,11 +434,6 @@ Horde::addInlineScript(array(
     'ImpFolders.fullNames = ' . Horde_Serialize::serialize($fullNames, Horde_Serialize::JSON, $charset)
 ));
 
-/* Render the rows now. */
-$template = $injector->createInstance('Horde_Template');
-$template->setOption('gettext', true);
-$template->set('rows', $rows);
-
 $title = _("Folder Navigator");
 IMP::prepareMenu();
 Horde::metaRefresh($refresh_time, Horde::applicationUrl('folders.php', true));
@@ -491,8 +444,8 @@ IMP::quota();
 
 echo $head_template->fetch(IMP_TEMPLATES . '/imp/folders/head.html');
 echo $a_template->fetch(IMP_TEMPLATES . '/imp/folders/actions.html');
-echo $template->fetch(IMP_TEMPLATES . '/imp/folders/folders.html');
-if (count($rows) > 10) {
+$tree->renderTree();
+if (count($tree) > 10) {
     $a_template->set('id', 1);
     echo $a_template->fetch(IMP_TEMPLATES . '/imp/folders/actions.html');
 }
index c762baf..431c44c 100644 (file)
@@ -10,11 +10,10 @@ var ImpSearch = {
     //   data, text
     criteria: {},
     saved_searches: {},
-    show_unsub: false,
 
     _getAll: function()
     {
-        return $('search_form').getInputs(null, 'search_folders_form[]');
+        return $('search_form').getInputs(null, 'folder_list[]');
     },
 
     selectFolders: function(checked)
@@ -26,22 +25,6 @@ var ImpSearch = {
         });
     },
 
-    updateFolderList: function(folders)
-    {
-        var fragment = document.createDocumentFragment(),
-            node = $($('folder_row').clone(true)).writeAttribute('id', false).show(),
-            div = $('search_folders_hdr').next('DIV');
-
-        folders.each(function(f) {
-            var n = $(node.clone(true));
-            n.down().writeAttribute({ disabled: Boolean(f.c), value: (f.co ? null : f.v.escapeHTML()) }).insert({ after: f.l });
-            fragment.appendChild(n);
-        });
-
-        div.update('').appendChild(fragment);
-        Horde.stripeElement(div);
-    },
-
     updateRecentSearches: function(searches)
     {
         var fragment = document.createDocumentFragment(),
@@ -395,18 +378,6 @@ var ImpSearch = {
                 e.stop();
                 return;
 
-            case 'link_sub':
-                tmp = this._getAll();
-                this.show_unsub = !this.show_unsub;
-                $('search_folders_hdr').next('DIV').update(this.text.loading);
-                new Ajax.Request($('search_form').readAttribute('action'), {
-                    parameters: { show_unsub: Number(this.show_unsub) },
-                    onComplete: this._showFoldersCallback.bind(this, tmp)
-                });
-                elt.childElements().invoke('toggle');
-                e.stop();
-                return;
-
             default:
                 if (elt.hasClassName('arrowExpanded') ||
                     elt.hasClassName('arrowCollapsed')) {
@@ -430,17 +401,14 @@ var ImpSearch = {
     _toggleHeader: function(elt)
     {
         elt.down().toggle().next().toggle().up().next().toggle();
-        if (elt.descendantOf('search_folders_hdr')) {
-            elt.next('SPAN.searchuiFoldersActions').toggle();
+        if (elt.readAttribute('id') == 'search_folders_hdr') {
+            elt.down('SPAN.searchuiFoldersActions').toggle();
+            if (window.imp_search && elt.next().visible()) {
+                window.imp_search.stripe();
+            }
         }
     },
 
-    _showFoldersCallback: function(flist, r)
-    {
-        this.updateFolderList(r.responseJSON);
-        this.updateSelectedFolders(flist);
-    },
-
     calendarSelectHandler: function(e)
     {
         var elt = e.element();
index 45c6644..4e0c9c4 100644 (file)
@@ -300,7 +300,7 @@ class IMP_Ajax_Application extends Horde_Core_Ajax_Application
                     $mask |= IMP_Imap_Tree::FLIST_NOCHILDREN;
                 }
             } else {
-                $mask |= IMP_Imap_Tree::FLIST_NOCHILDREN;
+                $mask |= IMP_Imap_Tree::FLIST_NOCHILDREN | IMP_Imap_Tree::FLIST_NOBASE;
             }
         }
 
index 52be43c..57894c8 100644 (file)
@@ -63,34 +63,11 @@ class Horde_Block_imp_tree_folders extends Horde_Block
         /* Initialize the IMP_Tree object. */
         $imaptree = $injector->getInstance('IMP_Imap_Tree');
         $imaptree->setIteratorFilter(IMP_Imap_Tree::FLIST_CONTAINER | IMP_Imap_Tree::FLIST_VFOLDER);
-
-        $unseen = 0;
-
-        foreach ($imaptree as $val) {
-            $label = $val->name;
-
-            if ($val->polled) {
-                $poll_info = $val->poll_info;
-                if (!empty($poll_info->unseen)) {
-                    $unseen += $poll_info->unseen;
-                    $label = '<span dir="ltr"><strong>' . $label . '</strong> (' . $poll_info->unseen . '/' . $poll_info->msgs . ')</span>';
-                }
-            }
-
-            $icon = $val->icon;
-            $tree->addNode(
-                $parent . $val->value,
-                ($val->level) ? $parent . $val->parent : $parent,
-                $label,
-                $indent + $val->level,
-                $val->is_open,
-                array(
-                    'icon' => $icon->icon,
-                    'iconopen' => $icon->iconopen,
-                    'url' => ($val->container) ? null : $name_url->add('mailbox', $val->value),
-                )
-            );
-        }
+        $imaptree->createTree($tree, array(
+            'indent' => $indent,
+            'parent' => $parent,
+            'poll_info' => true
+        ));
 
         /* We want to rewrite the parent node of the INBOX to include new mail
          * notification. */
@@ -106,9 +83,9 @@ class Horde_Block_imp_tree_folders extends Horde_Block
         );
         $name = $registry->get('name', $parent);
 
-        if ($unseen) {
+        if ($imaptree->unseen) {
             $node_params['icon'] = Horde_Themes::img('newmail.png');
-            $name = sprintf('<strong>%s</strong> (%s)', $name, $unseen);
+            $name = sprintf('<strong>%s</strong> (%s)', $name, $imaptree->unseen);
         }
 
         $tree->addNode(
index c1cdcc9..b8d166c 100644 (file)
@@ -42,9 +42,10 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
     const FLIST_UNSUB = 2;
     const FLIST_VFOLDER = 4;
     const FLIST_NOCHILDREN = 8;
-    const FLIST_ANCESTORS = 16;
-    const FLIST_SAMELEVEL = 32;
-    const FLIST_EXPANDED = 64;
+    const FLIST_EXPANDED = 16;
+    const FLIST_ANCESTORS = 32;
+    const FLIST_SAMELEVEL = 64;
+    const FLIST_NOBASE = 128;
 
     /* The string used to indicate the base of the tree. This must include
      * null since this is the only 7-bit character not allowed in IMAP
@@ -67,6 +68,20 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
     public $changed = false;
 
     /**
+     * Recent messages.
+     *
+     * @var array
+     */
+    public $recent = array();
+
+    /**
+     * Unseen count.
+     *
+     * @var array
+     */
+    public $unseen = 0;
+
+    /**
      * Array containing the mailbox tree.
      *
      * @var array
@@ -181,7 +196,7 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
         /* Reset class variables to the defaults. */
         $this->changed = true;
         $this->_currkey = $this->_currparent = null;
-        $this->_tree = $this->_parent = array();
+        $this->recent = $this->_tree = $this->_parent = array();
         $this->_showunsub = $unsubmode;
         unset($this->_cache['fulllist'], $this->_cache['subscribed']);
 
@@ -1440,6 +1455,113 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
         return $mbox . $new;
     }
 
+    /**
+     * Creates a Horde_Tree representation of the current tree (respecting
+     * the current iterator filter).
+     *
+     * @param string|Horde_Tree $name  Either the tree name, or a Horde_Tree
+     *                                 object to add nodes to.
+     * @param array $opts              Additional options:
+     * <pre>
+     * 'checkbox' - (boolean) Display checkboxes?
+     *              DEFAULT: false
+     * 'editvfolder' - (boolean) Display vfolder edit links?
+     *                 DEFAULT: false
+     * 'indent' - (integer) The base level to add nodes to.
+     *            DEFAULT: 0
+     * 'parent' - (string) The parent object of the current level.
+     *            DEFAULT: null (add to base level)
+     * 'poll_info' - (boolean) Include poll information?
+     *               DEFAULT: false
+     * </pre>
+     *
+     * @return Horde_Tree  The tree object.
+     */
+    public function createTree($name, array $opts = array())
+    {
+        $this->recent = array();
+        $this->unseen = 0;
+
+        if ($name instanceof Horde_Tree) {
+            $tree = $name;
+            $indent = $opts['indent'];
+            $parent = $opts['parent'];
+        } else {
+            $tree = $GLOBALS['injector']->getInstance('Horde_Tree')->getTree($name, 'Javascript', array(
+                'alternate' => true,
+                'lines' => true,
+                'lines_base' => true
+            ));
+            $indent = 0;
+            $parent = null;
+        }
+        $mailbox_url = Horde::applicationUrl('mailbox.php');
+
+        foreach ($this as $val) {
+            $after = $class = '';
+            $label = $val->name;
+            $url = null;
+
+            if (!empty($opts['poll_info']) && $val->polled) {
+                $poll_info = $val->poll_info;
+
+                if ($poll_info->unseen) {
+                    $this->unseen += $poll_info->unseen;
+                    if ($poll_info->recent) {
+                        $recent[$val->value] = $poll_info->recent;
+                    }
+
+                    $label = '<strong>' . $label . '</strong>';
+                }
+
+                $after = '&nbsp;(' . $poll_info->unseen . '/' . $poll_info->msgs . ')';
+            }
+
+            if (!$val->container) {
+                $url = $mailbox_url->add('mailbox', $val->value);
+
+                if ($this->_showunsub && !$val->sub) {
+                    $class = 'folderunsub';
+                }
+            }
+
+            $checkbox = '<input type="checkbox" class="checkbox" name="folder_list[]" value="' . IMP::formMbox($val->value, true) . '"';
+
+            if ($val->vfolder) {
+                $checkbox .= ' disabled="disabled"';
+
+                if (!empty($opts['editvfolder']) && $val->editvfolder) {
+                    $imp_search = $GLOBALS['injector']->getInstance('IMP_Search');
+                    $after = '&nbsp[' .
+                        $imp_search->deleteUrl($val->value)->link(array('title' => _("Delete Virtual Folder"))) . _("Delete") . '</a>'.
+                        ']&nbsp;|&nbsp|[' .
+                        $imp_search->editUrl($val->value)->link(array('title' => _("Edit Virtual Folder"))) . _("Edit") . '</a>'.
+                        ']';
+                    exit;
+                }
+            }
+
+            $icon = $val->icon;
+            $tree->addNode(
+                strval($parent) . $val->value,
+                ($val->level) ? strval($parent) . $val->parent : $parent,
+                $label,
+                $indent + $val->level,
+                $val->is_open,
+                array(
+                    'class' => $class,
+                    'icon' => $icon->icon,
+                    'iconopen' => $icon->iconopen,
+                    'url' => $url
+                ),
+                $after,
+                empty($opts['checkbox']) ? null : $checkbox . ' />'
+            );
+        }
+
+        return $tree;
+    }
+
     /* ArrayAccess methods. */
 
     public function offsetExists($offset)
@@ -1543,8 +1665,7 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
 
         /* If showing unsubscribed, toggle subscribed flag to make sure we
          * have subscribed mailbox information. */
-        if (!$this->_showunsub &&
-            $c['mask'] & self::FLIST_UNSUB) {
+        if (!$this->_showunsub && ($c['mask'] & self::FLIST_UNSUB)) {
             $this->showUnsubscribed(true);
             $this->showUnsubscribed(false);
         }
@@ -1559,6 +1680,12 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
                         $c['ancestors'][$parent[0]] = $parent[1];
                         $p = $parent[0];
                     }
+                } elseif ($c['mask'] & self::FLIST_NOBASE) {
+                    $this->_currparent = $tmp->value;
+                    $this->_currkey = isset($this->_parent[$tmp->value])
+                        ? 0
+                        : null;
+                    $c['samelevel'] = $tmp->value;
                 } else {
                     $this->_currparent = $tmp->parent;
                     $this->_currkey = array_search($tmp->value, $this->_parent[$tmp->parent]);
@@ -1591,10 +1718,13 @@ class IMP_Imap_Tree implements ArrayAccess, Iterator
      * IMP_Imap_Tree::FLIST_UNSUB - Include unsubscribed elements.
      * IMP_Imap_Tree::FLIST_VFOLDER - Include Virtual Folders.
      * IMP_Imap_Tree::FLIST_NOCHILDREN - Don't include child elements.
+     * IMP_Imap_Tree::FLIST_EXPANDED - Only include expanded folders.
+     * ---
+     * These options require that $base be set:
      * IMP_Imap_Tree::FLIST_ANCESTORS - Include ancestors of $base.
      * IMP_Imap_Tree::FLIST_SAMELEVEL - Include all mailboxes at the same
      *                                  level as $base.
-     * IMP_Imap_Tree::FLIST_EXPANDED - Only include expanded folders.
+     * IMP_Imap_Tree::FLIST_NOBASE - Don't include $base in the return.
      * </pre>
      * @param string $base  Include all mailboxes below this element.
      */
diff --git a/imp/lib/Ui/Folder.php b/imp/lib/Ui/Folder.php
deleted file mode 100644 (file)
index 402edd7..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * The IMP_Ui_Folder:: class is designed to provide a place to store common
- * code shared among IMP's various UI views for folders.
- *
- * Copyright 2009-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
- *
- * @author   Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @license  http://www.fsf.org/copyleft/gpl.html GPL
- * @package  IMP
- */
-class IMP_Ui_Folder
-{
-    /**
-     * Temporary array used to determine tree levels.
-     *
-     * @var array
-     */
-    protected $_moreMbox = array();
-
-    /**
-     * Create the tree images for a list of folder elements.
-     *
-     * @param IMP_Imap_Tree $tree  The tree object.
-     * @param array $opts          Additional options:
-     * <pre>
-     * 'expand_url' - (Horde_Url) The URL to use for expand/collapse links.
-     * </pre>
-     *
-     * @return array  An array of tree image strings.
-     */
-    public function getTreeImages(IMP_Imap_Tree $tree, $opts = array())
-    {
-        $this->_moreMbox = array();
-        $out = array();
-
-        foreach ($tree as $key => $val) {
-            $out[$key] = $this->_getTreeImage($val, $opts);
-        }
-
-        return $out;
-    }
-
-    /**
-     * Create a tree image from a folder element entry.
-     *
-     * @param IMP_Imap_Tree_Element $elt  A mailbox element object.
-     * @param array $opts                 See self::getTreeImages().
-     *
-     * @return string  The image string.
-     */
-    protected function _getTreeImage($elt, $opts = array())
-    {
-        global $registry;
-
-        $alt = $dir = null;
-        $line = '';
-
-        $icon = $elt->icon;
-        $peek = false;
-
-        $dir2 = $icon->user_icon
-            ? Horde::img($icon->icon, $icon->alt)
-            : '<span class="foldersImg ' . $icon->class . '"></span>';
-
-        if ($elt->children && isset($opts['expand_url'])) {
-            $dir = $opts['expand_url']->copy()->add('folder', $elt->value);
-
-            if ($elt->is_open) {
-                if (!is_null($dir)) {
-                    $dir->add('actionID', 'collapse_folder');
-                    $alt = _("Collapse Folder");
-                }
-
-                $tree_img = ($elt->value == 'INBOX')
-                    ? 5
-                    : ($peek ? 6 : 7);
-            } else {
-                if (!is_null($dir)) {
-                    $dir->add('actionID', 'expand_folder');
-                    $alt = _("Expand Folder");
-                }
-
-                $tree_img = ($elt->value == 'INBOX')
-                        ? 9
-                        : ($peek ? 10 : 11);
-            }
-
-            if (!is_null($dir)) {
-                $dir = Horde::link($dir, $alt) . '<span class="treeImg treeImg' . $tree_img . '"></span></a>' . $dir2;
-            }
-        } else {
-            if (($elt->value == 'INBOX') && !$peek) {
-                $dir = '<span class="treeImg"></span>' . $dir2;
-            } else {
-                $tree_img = ($elt->value == 'INBOX')
-                    ? 3
-                    : ($peek ? 2 : 4);
-                $dir = '<span class="treeImg treeImg' . $tree_img . '"></span>' . $dir2;
-            }
-        }
-
-        $this->_moreMbox[$elt->level] = $peek;
-        for ($i = 0; $i < $elt->level; ++$i) {
-            $line .= $this->_moreMbox[$i]
-                ? '<span class="treeImg treeImg1"></span>'
-                : '<span class="treeImg"></span>';
-        }
-
-        return $line . $dir;
-    }
-
-}
index e087bfe..bc8166e 100644 (file)
@@ -9,14 +9,12 @@
  * 'criteria_form' - (string) JSON representation of the search query.
  * 'edit_query' - (string) The search query to edit.
  * 'edit_query_vfolder' - (string) The name of the vfolder being edited.
- * 'search_folders_form' - (array) The list of folders to add to the query.
+ * 'folder_list' - (array) The list of folders to add to the query.
  * 'search_label' - (string) The label to use when saving the search.
  * 'search_mailbox' - (string) Use this mailbox as the default value.
  *                    DEFAULT: INBOX
- * 'search_save' - (boolean) If set, save search.
+ * 'search_save' - (integer) If set, save search.
  * 'search_type' - (string) The type of saved search ('vfolder').
- * 'show_unsub' - (integer) If set, return a JSON object with folder
- *                information used to create the folder list.
  *
  * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
  *
@@ -64,13 +62,13 @@ if ($vars->criteria_form) {
     if ($vars->search_save) {
         switch ($vars->search_type) {
         case 'vfolder':
-            $id = $imp_search->addVFolder($query, $vars->search_folders_form, $criteria, $vars->search_label, $vars->edit_query_vfolder);
+            $id = $imp_search->addVFolder($query, $vars->folder_list, $criteria, $vars->search_label, $vars->edit_query_vfolder);
             $notification->push(sprintf(_("Virtual Folder \"%s\" created succesfully."), $vars->search_label), 'horde.success');
             break;
         }
     } else {
         /* Set the search in the session. */
-        $id = $imp_search->createSearchQuery($query, $vars->search_folders_form, $criteria, _("Search Results"));
+        $id = $imp_search->createSearchQuery($query, $vars->folder_list, $criteria, _("Search Results"));
     }
 
     /* Redirect to the mailbox page. */
@@ -89,34 +87,10 @@ if ($vars->criteria_form) {
 
 /* Generate master folder list. */
 $imp_imap_tree = $injector->getInstance('IMP_Imap_Tree');
-$mask = IMP_Imap_Tree::FLIST_CONTAINER;
-
-$subscribe = $prefs->getValue('subscribe');
-if (!$subscribe || $vars->show_unsub) {
-    $mask |= IMP_Imap_Tree::FLIST_UNSUB;
-}
-
-$imp_imap_tree->setIteratorFilter($mask);
-
-$imp_ui_folder = new IMP_Ui_Folder();
-$tree_imgs = $imp_ui_folder->getTreeImages($imp_imap_tree);
-
-$folders = array();
-foreach ($imp_imap_tree as $key => $val) {
-    $folders[] = array(
-        'c' => intval($val->container),
-        'l' => $tree_imgs[$key] . ' ' . $val->name,
-        'v' => $val->value
-    );
-}
-
-if ($vars->show_unsub) {
-    Horde::sendHTTPResponse($folders, 'json');
-}
-
-$js_load = array(
-    'ImpSearch.updateFolderList(' . Horde_Serialize::serialize($folders, Horde_Serialize::JSON, $charset) . ')'
-);
+$imp_imap_tree->setIteratorFilter(IMP_Imap_Tree::FLIST_CONTAINER);
+$tree = $imp_imap_tree->createTree('imp_search', array(
+    'checkbox' => true,
+));
 
 /* Process list of recent searches. */
 $recent_searches = $imp_search->listQueries(IMP_Search::LIST_SEARCH | IMP_Search::NO_BASIC_SEARCH, false);
@@ -139,7 +113,6 @@ $js_load[] = 'ImpSearch.updateSelectedFolders(' . Horde_Serialize::serialize(arr
 $t = $injector->createInstance('Horde_Template');
 $t->setOption('gettext', true);
 $t->set('action', Horde::applicationUrl('search.php'));
-$t->set('subscribe', $subscribe);
 $t->set('virtualfolder', $_SESSION['imp']['protocol'] != 'pop');
 
 /* Determine if we are editing a current search folder. */
@@ -175,6 +148,7 @@ foreach ($imp_search->flagFields() as $key => $val) {
     $types[$key] = 'flag';
 }
 $t->set('f_fields', $f_fields);
+$t->set('tree', $tree->getTree());
 
 Horde_Core_Ui_JsCalendar::init();
 
diff --git a/imp/templates/imp/folders/folders.html b/imp/templates/imp/folders/folders.html
deleted file mode 100644 (file)
index 3c9d5f9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<loop:rows>
-<div class="<tag:rows.cname />">
- &nbsp;<input type="checkbox" class="checkbox" name="folder_list[]" <if:rows.nocheckbox>disabled="disabled" </if:rows.nocheckbox>value="<tag:rows.mbox_val />" /> <tag:rows.line /> <tag:rows.name /><if:rows.polled> (<tag:rows.unseen />/<tag:rows.msgs />)</if:rows.polled> <if:rows.editvfolder>&nbsp;&nbsp;[<tag:rows.delvfolder />] [<tag:rows.editvfolder />]</if:rows.editvfolder>
-</div>
-</loop:rows>
index 409b652..db0154b 100644 (file)
   <span class="searchuiFoldersActions" style="display:none">
    <a id="link_sel_all" href="#"><gettext>Select all</gettext></a> |
    <a id="link_sel_none" href="#"><gettext>Select none</gettext></a>
-<if:subscribe>
-| <a id="link_sub" href="#"><span><gettext>Show All</gettext></span><span style="display:none"><gettext>Show Subscribed Only</gettext></span></a>
-</if:subscribe>
   </span>
  </div>
 
- <div class="item striped" style="display:none">
+ <div class="item" id="search_folders_tree" style="display:none">
+  <tag:tree />
  </div>
 
 <if:virtualfolder>
index c235889..da42970 100644 (file)
@@ -199,17 +199,13 @@ div.msgActions, #fmanager div.folderActions {
 #search_form div.item {
     padding: 1px 0 1px 0;
 }
-#search_form .checkbox {
-    vertical-align: middle;
-    margin-right: 2px;
-}
-#search_form .foldersImg {
-    vertical-align: middle;
-}
 #search_form em.join {
     font-style: normal;
     font-weight: bold;
 }
+#search_folders_tree input.checkbox {
+    vertical-align: middle;
+}
 
 .searchuiCalendar {
     background-image: url("graphics/calendar.png");
@@ -226,12 +222,14 @@ div.msgActions, #fmanager div.folderActions {
 }
 
 /* Folder view. */
-#checkAll0, #checkAll1, #fmanager input.checkbox, #fmanager span.folderImg {
+#checkAll0, #checkAll1, #fmanager input.checkbox {
     vertical-align: middle;
 }
+
 #fmanager div.folderChoose {
     padding-left: 5px;
 }
+
 span.folderImg {
     background-image: url("graphics/folders/folder.png");
 }
@@ -504,9 +502,11 @@ span.spellcheckPopdownImg:hover {
 /* Expand/Collapse graphic. */
 span.arrowCollapsed {
     background-image: url("graphics/arrow_collapsed.png");
+    cursor: pointer;
 }
 span.arrowExpanded {
     background-image: url("graphics/arrow_expanded.png");
+    cursor: pointer;
 }
 
 /* Loading graphic */