Yet more Search/Virtual Folder fixes/improvements
authorMichael M Slusarz <slusarz@curecanti.org>
Tue, 29 Sep 2009 04:34:21 +0000 (22:34 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 29 Sep 2009 04:34:21 +0000 (22:34 -0600)
Big addition: ability to right click user-editable Virtual Folders in
DIMP and receieve a context menu with Edit/Delete options.
Add notifications when deleting virtual folders.
Correctly populate label input when editing virtual folders.

imp/ajax.php
imp/folders.php
imp/js/DimpBase.js
imp/js/search.js
imp/lib/Dimp.php
imp/search.php
imp/templates/index/index-dimp.inc
imp/themes/silver/screen-dimp.css

index cb90c8c..6d50b24 100644 (file)
@@ -230,8 +230,15 @@ case 'DeleteFolder':
     $imptree = IMP_Imap_Tree::singleton();
     $imptree->eltDiffStart();
 
-    $imp_folder = IMP_Folder::singleton();
-    $result = $imp_folder->delete(array($mbox));
+    if ($imp_search->isEditableVFolder($mbox)) {
+        $notification->push(sprintf(_("Deleted Virtual Folder \"%s\"."), $imp_search->getLabel($mbox)), 'horde.success');
+        $imp_search->deleteSearchQuery($mbox);
+        $result = true;
+    } else {
+        $imp_folder = IMP_Folder::singleton();
+        $result = $imp_folder->delete(array($mbox));
+    }
+
     if ($result) {
         $result = IMP_Dimp::getFolderResponse($imptree);
     }
index bf1f2e1..f4e740c 100644 (file)
@@ -100,6 +100,7 @@ case 'delete_folder':
 case 'delete_search_query':
     $queryid = Horde_Util::getFormData('queryid');
     if (!empty($queryid)) {
+        $notification->push(sprintf(_("Deleted Virtual Folder \"%s\"."), $imp_search->getLabel($queryid)), 'horde.success');
         $imp_search->deleteSearchQuery($queryid);
     }
     break;
index 33250e6..a6ab98f 100644 (file)
@@ -261,9 +261,14 @@ var DimpBase = {
 
         switch (loc) {
         case 'search':
+            // data: 'edit_query' = folder to edit; otherwise, loads search
+            //       screen with current mailbox as default search mailbox
+            if (!data) {
+                data = { search_mailbox: f };
+            }
             this.highlightSidebar();
             DimpCore.setTitle(DIMP.text.search);
-            this.iframeContent(loc, DimpCore.addURLParam(DIMP.conf.URI_SEARCH, { search_mailbox: f }));
+            this.iframeContent(loc, DimpCore.addURLParam(DIMP.conf.URI_SEARCH, data));
             break;
 
         case 'portal':
@@ -672,16 +677,17 @@ var DimpBase = {
             break;
 
         case 'ctx_folder_empty':
-            mbox = baseelt.up('LI').retrieve('mbox');
-            if (window.confirm(DIMP.text.empty_folder.replace(/%s/, mbox))) {
-                DimpCore.doAction('EmptyFolder', { view: mbox }, null, this._emptyFolderCallback.bind(this));
+            tmp = baseelt.up('LI');
+            if (window.confirm(DIMP.text.empty_folder.replace(/%s/, tmp.readAttribute('title')))) {
+                DimpCore.doAction('EmptyFolder', { view: tmp.retrieve('mbox') }, null, this._emptyFolderCallback.bind(this));
             }
             break;
 
         case 'ctx_folder_delete':
-            mbox = baseelt.up('LI').readAttribute('title');
-            if (window.confirm(DIMP.text.delete_folder.replace(/%s/, mbox))) {
-                DimpCore.doAction('DeleteFolder', { view: mbox }, null, this.bcache.get('folderC') || this.bcache.set('folderC', this._folderCallback.bind(this)));
+        case 'ctx_vfolder_delete':
+            tmp = baseelt.up('LI');
+            if (window.confirm(DIMP.text.delete_folder.replace(/%s/, tmp.readAttribute('title')))) {
+                DimpCore.doAction('DeleteFolder', { view: tmp.retrieve('mbox') }, null, this.bcache.get('folderC') || this.bcache.set('folderC', this._folderCallback.bind(this)));
             }
             break;
 
@@ -787,8 +793,12 @@ var DimpBase = {
             new Ajax.Request(DIMP.conf.URI_SEARCH_BASIC, { parameters: DimpCore.addRequestParams($H({ search_mailbox: this.folder })), onComplete: function(r) { RedBox.showHtml(r.responseText); } });
             break;
 
+        case 'ctx_vfolder_edit':
+            tmp = { edit_query: baseelt.up('LI').retrieve('mbox') };
+            // Fall through
+
         case 'ctx_qsearchopts_advanced':
-            this.go('search');
+            this.go('search', tmp);
             break;
 
         case 'ctx_qsearchopts_all':
@@ -2187,6 +2197,11 @@ var DimpBase = {
             new Drag(li, this._folderDragConfig);
             this._addMouseEvents({ id: fid, type: ftype });
             break;
+
+        case 'scontainer':
+        case 'virtual':
+            this._addMouseEvents({ id: fid, type: (ob.v == 2) ? 'vfolder' : 'noactions' });
+            break;
         }
     },
 
index 65336b4..614870b 100644 (file)
@@ -104,6 +104,12 @@ var ImpSearch = {
         });
     },
 
+    updateSavedSearches: function(label, type)
+    {
+        $('search_label').setValue(label);
+        // TODO: type
+    },
+
     resetCriteria: function()
     {
         $('search_criteria_table').childElements().invoke('remove');
index 2fd5a51..8848da5 100644 (file)
@@ -153,7 +153,7 @@ class IMP_Dimp
         }
 
         if (!empty($changes['d'])) {
-            $result['d'] = array_map('rawurlencode', array_reverse($changes['d']));
+            $result['d'] = array_reverse($changes['d']);
         }
 
         return $result;
@@ -183,7 +183,8 @@ class IMP_Dimp
      * 'u' (unseen) = The number of unseen messages. [integer]
      * 'un' (unsubscribed) = Is this folder unsubscribed? [boolean]
      *                       [DEFAULT: no]
-     * 'v' (virtual) = Is this a virtual folder? [boolean] [DEFAULT: no]
+     * 'v' (virtual) = Virtual folder? 0 = not vfolder, 1 = system vfolder,
+     *                 2 = user vfolder [integer] [DEFAULT: 0]
      * </pre>
      */
     static private function _createFolderElt($elt)
@@ -205,7 +206,7 @@ class IMP_Dimp
             $ob->po = 1;
         }
         if ($elt['vfolder']) {
-            $ob->v = 1;
+            $ob->v = $GLOBALS['imp_search']->isEditableVFolder($elt['value']) ? 2 : 1;
         }
         if (!$elt['sub']) {
             $ob->un = 1;
index 86639f3..68fd343 100644 (file)
@@ -111,7 +111,7 @@ if (Horde_Util::getFormData('show_unsub') !== null) {
     Horde::sendHTTPResponse($folders, 'json');
 }
 
-$on_domload = array(
+$js_load = array(
     'ImpSearch.updateFolderList(' . Horde_Serialize::serialize($folders, Horde_Serialize::JSON, $charset) . ')'
 );
 
@@ -126,11 +126,11 @@ if (!empty($saved_searches)) {
             'v' => $key
         );
     }
-    $on_domload[] = 'ImpSearch.updateSavedSearches(' . Horde_Serialize::serialize($ss, Horde_Serialize::JSON, $charset) . ')';
+    $js_load[] = 'ImpSearch.updateSavedSearches(' . Horde_Serialize::serialize($ss, Horde_Serialize::JSON, $charset) . ')';
 }
 
 /* Preselect mailboxes. */
-$on_domload[] = 'ImpSearch.updateSelectedFolders(' . Horde_Serialize::serialize(array($search_mailbox), Horde_Serialize::JSON, $charset) . ')';
+$js_load[] = 'ImpSearch.updateSelectedFolders(' . Horde_Serialize::serialize(array($search_mailbox), Horde_Serialize::JSON, $charset) . ')';
 
 /* Prepare the search template. */
 $t = new Horde_Template();
@@ -150,7 +150,8 @@ if (!is_null($edit_query) && $imp_search->isSearchMbox($edit_query)) {
         }
         $t->set('edit_query_vfolder', htmlspecialchars($edit_query));
     }
-    $on_domload[] = 'ImpSearch.updateSearchCriteria(' . Horde_Serialize::serialize($imp_search->getCriteria($edit_query), Horde_Serialize::JSON, $charset) . ')';
+    $js_load[] = 'ImpSearch.updateSearchCriteria(' . Horde_Serialize::serialize($imp_search->getCriteria($edit_query), Horde_Serialize::JSON, $charset) . ')';
+    $js_load[] = 'ImpSearch.updateSavedSearches(' . Horde_Serialize::serialize($imp_search->getLabel($edit_query), Horde_Serialize::JSON, $charset) . ')';
 }
 
 $f_fields = $s_fields = $types = array();
@@ -201,7 +202,7 @@ Horde::addInlineScript(array(
     'ImpSearch.data = ' . Horde_Serialize::serialize($js_data, Horde_Serialize::JSON, $charset),
     'ImpSearch.text = ' . Horde_Serialize::serialize($gettext_strings, Horde_Serialize::JSON, $charset)
 ));
-Horde::addInlineScript($on_domload, 'dom');
+Horde::addInlineScript($js_load, 'dom');
 
 $title = _("Search");
 Horde::addScriptFile('horde.js', 'horde', true);
index 1ecf010..ad668bb 100644 (file)
@@ -367,6 +367,15 @@ function _simpleButton($id, $text, $image, $imagedir = null)
 </div>
 <?php endif; ?>
 
+<div class="context" id="ctx_noactions" style="display:none">
+ <span>No actions available</span>
+</div>
+
+<div class="context" id="ctx_vfolder" style="display:none">
+ <a id="ctx_vfolder_edit"><span class="contextImg"></span><?php echo _("Edit Virtual Folder") ?></a>
+ <a id="ctx_vfolder_delete"><span class="contextImg"></span><?php echo _("Delete Virtual Folder") ?></a>
+</div>
+
 <div class="context" id="ctx_message" style="display:none">
  <a id="ctx_message_reply"><span class="contextImg"></span><?php echo _("Reply") ?></a>
  <a id="ctx_message_forward" class="sep"><span class="contextImg"></span><?php echo _("Forward") ?></a>
index e5b6468..4cf06d5 100644 (file)
@@ -100,10 +100,10 @@ span.dimpactionDrafts {
 #ctx_folder_create span.contextImg, #ctx_container_create span.contextImg, #ctx_folderopts_new span.contextImg {
     background-image: url("graphics/folders/create.png");
 }
-#ctx_folder_rename span.contextImg, #ctx_container_rename span.contextImg {
+#ctx_folder_rename span.contextImg, #ctx_container_rename span.contextImg, #ctx_vfolder_edit span.contextImg {
     background-image: url("graphics/folders/edit.png");
 }
-#ctx_folder_delete span.contextImg {
+#ctx_folder_delete span.contextImg, #ctx_vfolder_delete span.contextImg {
     background-image: url("graphics/folders/delete.png");
 }
 #ctx_message_spam span.contextImg {