Begin reworking the search interface in dimp
authorMichael M Slusarz <slusarz@curecanti.org>
Fri, 10 Sep 2010 19:19:25 +0000 (13:19 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Fri, 10 Sep 2010 22:51:43 +0000 (16:51 -0600)
imp/js/dimpbase.js
imp/lib/Views/ListMessages.php
imp/templates/dimp/index.inc
imp/themes/dimp/ie7.css
imp/themes/dimp/screen.css
imp/themes/dimp/webkit.css
imp/themes/silver/dimp/screen.css

index d775d37..163d7cd 100644 (file)
@@ -188,7 +188,7 @@ var DimpBase = {
                 }
 
                 // This catches the refresh case - no need to re-add to history
-                if (!Object.isUndefined(this.folder) && !this.search) {
+                if (!Object.isUndefined(this.folder)) {
                     this.setHash(loc);
                 }
             } else if (this.folder == f) {
@@ -345,13 +345,10 @@ var DimpBase = {
 
                 this.folder = f;
 
-                if (this.isSearch(f)) {
-                    if (!this.search || this.search.flag) {
-                        this._quicksearchDeactivate(!this.search);
-                    }
-                    $('refreshlink').show();
-                } else {
-                    $('refreshlink').hide();
+                if (!this.isSearch(f)) {
+                    $('searchbar').hide();
+                } else if (!this.search || this.search.flag) {
+                    $('qsearch').hide();
                 }
             }
         }
@@ -551,9 +548,18 @@ var DimpBase = {
                 l = this.viewport.getMetaData('label');
 
             this.setMessageListTitle();
-            if (!this.isSearch()) {
+
+            if (this.isSearch()) {
+                tmp = this.viewport.getMetaData('slabel');
+                if (tmp) {
+                    $('search_label').update(tmp.stripTags().escapeHTML());
+                }
+                [ $('search_edit') ].invoke(this.search ? 'hide' : 'show');
+                $('searchbar').show();
+            } else {
                 this.setFolderLabel(this.folder, this.viewport.getMetaData('unseen') || 0);
             }
+
             this.updateTitle(this.viewport.getMetaData('noexist'));
 
             if (this.rownum) {
@@ -881,7 +887,7 @@ var DimpBase = {
                     mbox: this.folder,
                     not: menu.endsWith('_filternot')
                 };
-                this.loadMailbox(DIMP.conf.fsearchid);
+                this.go('folder:' + DIMP.conf.fsearchid);
             } else {
                 parentfunc(e);
             }
@@ -994,8 +1000,10 @@ var DimpBase = {
             // Label is HTML encoded - but this is not HTML code so unescape.
             label = this.viewport.getMetaData('label').unescapeHTML();
 
-        if (this.isSearch(null, true)) {
-            label += ' (' + this.search.label + ')';
+        if (this.isSearch()) {
+            if (this.isSearch(null, true)) {
+                label += ' (' + this.search.label + ')';
+            }
         } else {
             elt = $(this.getFolderId(this.folder));
             if (elt) {
@@ -1431,10 +1439,11 @@ var DimpBase = {
     },
 
     /* Folder list updates. */
-    poll: function(force)
+
+    // search = (boolean) If true, update search results as well.
+    poll: function(search)
     {
-        var args = {},
-            check = 'checkmaillink';
+        var args = {};
 
         // Reset poll folder counter.
         this.setPoll();
@@ -1448,12 +1457,11 @@ var DimpBase = {
             args = this.viewport.addRequestParams({});
         }
 
-        if (force) {
+        if (search) {
             args.set('forceUpdate', 1);
-            check = 'refreshlink';
         }
 
-        $(check).down('A').update('[' + DIMP.text.check + ']');
+        $('checkmaillink').down('A').update('[' + DIMP.text.check + ']');
         DimpCore.doAction('poll', args);
     },
 
@@ -1470,9 +1478,6 @@ var DimpBase = {
         }
 
         $('checkmaillink').down('A').update(DIMP.text.getmail);
-        if ($('refreshlink').visible()) {
-            $('refreshlink').down('A').update(DIMP.text.refresh);
-        }
     },
 
     _displayQuota: function(r)
@@ -1540,7 +1545,7 @@ var DimpBase = {
                 mbox: this.folder,
                 query: q
             };
-            this.loadMailbox(DIMP.conf.qsearchid);
+            this.go('folder:' + DIMP.conf.qsearchid);
         }
     },
 
@@ -1562,7 +1567,7 @@ var DimpBase = {
             this.resetSelected();
             $(qs, 'qsearch_icon', 'qsearch_input').invoke('show');
             if (!noload) {
-                this.loadMailbox(this.search ? this.search.mbox : 'INBOX');
+                this.go('folder:' + (this.search ? this.search.mbox : 'INBOX'));
             }
             this.viewport.deleteView(f);
             this.search = null;
@@ -1574,20 +1579,6 @@ var DimpBase = {
     {
         $('qsearch_input').setValue(d ? DIMP.text.search + ' (' + $('ctx_qsearchby_' + DIMP.conf.qsearchfield).getText() + ')' : '');
         [ $('qsearch') ].invoke(d ? 'removeClassName' : 'addClassName', 'qsearchActive');
-        if ($('qsearch_input').visible()) {
-            $('qsearch_close').hide().next().hide();
-        }
-    },
-
-    // hideall = (boolean) Hide entire searchbox?
-    _quicksearchDeactivate: function(hideall)
-    {
-        if (hideall) {
-            $('qsearch').hide();
-        } else {
-            $('qsearch_close').show().next().show();
-            $('qsearch_icon', 'qsearch_input').invoke('hide');
-        }
     },
 
     /* Enable/Disable DIMP action buttons as needed. */
@@ -1755,12 +1746,6 @@ var DimpBase = {
                     e.stop();
                 }
                 break;
-
-            default:
-                if (elt.readAttribute('id') == 'qsearch_input') {
-                    $('qsearch_close').show();
-                }
-                break;
             }
 
             return;
@@ -1990,8 +1975,13 @@ var DimpBase = {
                 return;
 
             case 'checkmaillink':
-            case 'refreshlink':
-                this.poll(id == 'refreshlink');
+            case 'search_refresh':
+                this.poll(id == 'search_refresh');
+                e.stop();
+                return;
+
+            case 'search_edit':
+                this.go('search', { edit_query: this.folder });
                 e.stop();
                 return;
 
@@ -2100,18 +2090,7 @@ var DimpBase = {
                 }
                 break;
 
-            case 'qsearch':
-                if (e.element().readAttribute('id') != 'qsearch_icon') {
-                    elt.addClassName('qsearchFocus');
-                    if (!elt.hasClassName('qsearchActive')) {
-                        this._setQsearchText(false);
-                    }
-                    $('qsearch_input').focus();
-                }
-                break;
-
-            case 'qsearch_close':
-            case 'qsearch_close_filter':
+            case 'search_close':
                 this.quicksearchClear();
                 e.stop();
                 return;
@@ -2135,6 +2114,21 @@ var DimpBase = {
         parentfunc(e);
     },
 
+    mousedownHandler: function(e)
+    {
+        var elt;
+
+        if (e.findElement('#qsearch') &&
+            (e.element().readAttribute('id') != 'qsearch_icon')) {
+            elt = $('qsearch');
+            elt.addClassName('qsearchFocus');
+            if (!elt.hasClassName('qsearchActive')) {
+                this._setQsearchText(false);
+            }
+            $('qsearch_input').focus();
+        }
+    },
+
     mouseoverHandler: function(e)
     {
         if (DragDrop.Drags.drag) {
@@ -3004,7 +2998,6 @@ var DimpBase = {
 
         /* Store these text strings for updating purposes. */
         DIMP.text.getmail = $('checkmaillink').down('A').innerHTML;
-        DIMP.text.refresh = $('refreshlink').down('A').innerHTML;
         DIMP.text.showalog = $('alertsloglink').down('A').innerHTML;
 
         /* Initialize the starting page. */
@@ -3177,6 +3170,7 @@ DimpCore.onDoActionComplete = function(r) {
 
 /* Click handler. */
 DimpCore.clickHandler = DimpCore.clickHandler.wrap(DimpBase.clickHandler.bind(DimpBase));
+document.observe('mousedown', DimpBase.mousedownHandler.bindAsEventListener(DimpBase));
 
 /* ContextSensitive handlers. */
 DimpCore.contextOnClick = DimpCore.contextOnClick.wrap(DimpBase.contextOnClick.bind(DimpBase));
index 9787c94..1f1c9af 100644 (file)
@@ -35,17 +35,34 @@ class IMP_Views_ListMessages
 
             if (strlen($args['qsearchflag'])) {
                 $query->flag($args['qsearchflag'], empty($args['qsearchflagnot']));
+                $tmp = new stdClass;
+                $tmp->t = 'flag';
+                $tmp->v = $args['qsearchflag'];
+                $criteria = array($tmp);
+
                 $is_search = true;
             } elseif (strlen($args['qsearch'])) {
                 $field = $GLOBALS['prefs']->getValue('dimp_qsearch_field');
+                $is_search = true;
+
                 switch ($field) {
                 case 'body':
                     $query->text($args['qsearch'], true);
+
+                    $tmp = new stdClass;
+                    $tmp->t = 'body';
+                    $tmp->v = $args['qsearch'];
+                    $criteria = array($tmp);
                     break;
 
                 case 'from':
                 case 'subject':
                     $query->headerText($field, $args['qsearch']);
+
+                    $tmp = new stdClass;
+                    $tmp->t = $field;
+                    $tmp->v = $args['qsearch'];
+                    $criteria = array($tmp);
                     break;
 
                 case 'to':
@@ -57,23 +74,54 @@ class IMP_Views_ListMessages
 
                     $query->headerText('to', $args['qsearch']);
                     $query->orSearch(array($query2, $query3));
+
+                    $tmp = new stdClass;
+                    $tmp->t = 'to';
+                    $tmp->v = $args['qsearch'];
+                    $criteria = array($tmp);
+
+                    $tmp = new stdClass;
+                    $tmp->t = 'or';
+                    $criteria[] = $tmp;
+
+                    $tmp = new stdClass;
+                    $tmp->t = 'cc';
+                    $tmp->v = $args['qsearch'];
+                    $criteria[] = $tmp;
+
+                    $tmp = new stdClass;
+                    $tmp->t = 'or';
+                    $criteria[] = $tmp;
+
+                    $tmp = new stdClass;
+                    $tmp->t = 'bcc';
+                    $tmp->v = $args['qsearch'];
+                    $criteria[] = $tmp;
                     break;
 
                 case 'all':
-                default:
                     $query->text($args['qsearch'], false);
+
+                    $tmp = new stdClass;
+                    $tmp->t = 'text';
+                    $tmp->v = $args['qsearch'];
+                    $criteria = array($tmp);
                     break;
-                }
 
-                $is_search = true;
+                default:
+                    $is_search = false;
+                    break;
+                }
             }
 
             /* Set the search in the IMP session. */
             if ($is_search) {
-                $GLOBALS['injector']->getInstance('IMP_Search')->createSearchQuery($query, array($args['qsearchmbox']), array(), _("Search Results"), $mbox);
+                $imp_search = $GLOBALS['injector']->getInstance('IMP_Search');
+                $imp_search->createSearchQuery($query, array($args['qsearchmbox']), $criteria, _("Search Results"), $mbox);
             }
         } else {
-            $is_search = $GLOBALS['injector']->getInstance('IMP_Search')->isSearchMbox($mbox);
+            $imp_search = $GLOBALS['injector']->getInstance('IMP_Search');
+            $is_search = $imp_search->isSearchMbox($mbox);
         }
 
         /* Set the current time zone. */
@@ -132,6 +180,12 @@ class IMP_Views_ListMessages
             $md->flags = array_keys($GLOBALS['injector']->getInstance('IMP_Imap_Flags')->getList(array('imap' => true, 'mailbox' => $is_search ? null : $mbox)));
         }
 
+        /* The search query may have changed. */
+        if ($is_search &&
+            ($args['initial'] || strlen($args['qsearchmbox']))) {
+            $md->slabel = $imp_search->searchQueryText($mbox);
+        }
+
         $imp_imap = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb();
 
         /* These entries may change during a session, so always need to
index 4f75305..0669133 100644 (file)
@@ -62,7 +62,6 @@ function _simpleButton($id, $text, $image, $nodisplay = false)
    <ul id="dimpbarActions">
     <?php echo _simpleButton('composelink', _("_New Message"), 'dimpactionCompose') ?>
     <?php echo _simpleButton('checkmaillink', _("_Get Mail"), 'dimpactionCheckmail') ?>
-    <?php echo _simpleButton('refreshlink', _("_Refresh Search"), 'dimpactionRefresh', true) ?>
     <?php echo _simpleButton('alertsloglink', _("Alerts _Log"), 'infoIcon') ?>
 <?php if (!empty($_SESSION['imp']['filteravail'])): ?>
     <?php echo _simpleButton('applyfilterlink', _("Apply Filters"), 'filtersIcon') ?>
@@ -179,8 +178,6 @@ function _simpleButton($id, $text, $image, $nodisplay = false)
        <form action="#" method="post">
         <input autocomplete="off" id="qsearch_input" type="text" />
        </form>
-       <span class="closeImg" id="qsearch_close" style="display:none" title="<?php echo _("Clear Search") ?>"></span>
-       <span id="qsearch_close_filter" style="display:none">Clear Filter</span>
       </div>
 <?php endif; ?>
       <div><?php echo IMP_Dimp::actionButton(array('class' => 'noselectDisable', 'icon' => 'Reply', 'id' => 'button_reply', 'title' => _("Reply"))) ?></div>
@@ -197,6 +194,13 @@ function _simpleButton($id, $text, $image, $nodisplay = false)
       <div><?php echo IMP_Dimp::actionButton(array('icon' => 'Other', 'id' => 'button_other', 'title' => _("Other Actions"))) ?></div>
      </div>
 
+    <div id="searchbar" style="display:none">
+     <span id="search_label"></span>
+     <span class="iconImg closeImg" id="search_close" title="<?php echo _("Clear Search") ?>"></span>
+     <span class="iconImg dimpactionRefresh" id="search_refresh" title="<?php echo _("Refresh Search Results") ?>"></span>
+     <span class="iconImg dimpactionEditsearch" id="search_edit" style="display:none" title="<?php echo _("Edit Search Query") ?>"></span>
+    </div>
+
      <div id="msglistHeader" class="item">
       <div class="msgStatus"></div>
       <div class="msgFrom sep"></div>
index 8129240..1afaec6 100644 (file)
@@ -39,7 +39,7 @@ div.msgSubject span.treeImg {
 }
 
 /* Fixes broken inline-block. */
-div.msgStatus div, #msgHeadersContent .subject span, span.iconImg, span.contextImg, span.spellcheckPopdownImg, span.popdownImg, #qsearch_icon, #qsearch_close, #upload_wait, #noticerow .notices li {
+div.msgStatus div, #msgHeadersContent .subject span, span.iconImg, span.contextImg, span.spellcheckPopdownImg, span.popdownImg, #qsearch_icon, #upload_wait, #noticerow .notices li {
     zoom: 1;
     *display: inline;
 }
index f574a78..d7ad9fb 100644 (file)
@@ -788,12 +788,9 @@ a.address:hover img {
 #qsearch form {
     display: inline;
 }
-#qsearch_icon, #qsearch_close {
-    cursor: pointer;
-    padding: 2px 0 0;
-}
 #qsearch_icon {
     background: #f3f3f3 url("../graphics/search.png") center no-repeat;
+    cursor: pointer;
     padding-top: 2px;
 }
 #qsearch_input {
@@ -803,11 +800,6 @@ a.address:hover img {
     padding: 0 2px 0 0;
     width: 150px;
 }
-#qsearch_close_filter {
-    cursor: pointer;
-    padding-right: 3px;
-    vertical-align: middle;
-}
 .qsearchFocus, .qsearchFocus #qsearch_icon, .qsearchFocus #qsearch_input {
     background-color: #fff !important;
 }
@@ -819,6 +811,21 @@ a.address:hover img {
     text-decoration: underline;
 }
 
+#searchbar {
+    background-color: #ffa;
+    border: 1px solid gray;
+    padding: 3px 2px;
+}
+#search_close, #search_edit, #search_refresh {
+    cursor: pointer;
+    float: right;
+    margin-top: -1px;
+}
+#searchbar #search_label {
+    font-size: 90%;
+    font-weight: bold;
+}
+
 /* Redbox styles. */
 .RBForm {
     width: 20em;
@@ -851,7 +858,7 @@ a.address:hover img {
 }
 
 /* Images */
-div.msgStatus div, #msgHeadersContent .subject span, span.iconImg, span.contextImg, span.spellcheckPopdownImg, span.popdownImg, #qsearch_icon, #qsearch_close {
+div.msgStatus div, #msgHeadersContent .subject span, span.iconImg, span.contextImg, span.spellcheckPopdownImg, span.popdownImg, #qsearch_icon {
     display: -moz-inline-stack;
     display: inline-block;
     height: 16px;
@@ -914,6 +921,9 @@ span.dimpactionSpellcheck {
 span.dimpactionDrafts {
     background-image: url("../graphics/drafts.png");
 }
+span.dimpactionEditsearch {
+    background-image: url("../graphics/edit.png");
+}
 
 /* Context menu images */
 #ctx_message_reply span.contextImg {
index ce58f69..ad8b182 100644 (file)
@@ -2,6 +2,6 @@
  * CSS corrections for WebKit.
  */
 
-div.msgStatus div, #msgHeadersContent .subject span, span.iconImg, span.contextImg, span.spellcheckPopdownImg, span.popdownImg, #qsearch_icon, #qsearch_close {
+div.msgStatus div, #msgHeadersContent .subject span, span.iconImg, span.contextImg, span.spellcheckPopdownImg, span.popdownImg, #qsearch_icon {
     vertical-align: middle;
 }
index 0f0c715..502f2da 100644 (file)
@@ -74,6 +74,9 @@ span.dimpactionSpellcheck {
 span.dimpactionDrafts {
     background-image: url("../graphics/drafts.png");
 }
+span.dimpactionEditsearch {
+    background-image: url("../graphics/edit.png");
+}
 
 /* Context menu images */
 #ctx_message_reply span.contextImg {