!import
1 //@line 41 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/mail/base/content/searchBar.js"
2
3 var gSearchSession = null;
4 var gPreQuickSearchView = null;
5 var gSearchTimer = null;
6 var gViewSearchListener;
7 var gSearchBundle;
8 var gStatusBar = null;
9 var gSearchInProgress = false;
10 var gSearchInput = null;
11 var gDefaultSearchViewTerms = null;
12 var gQSViewIsDirty = false;
13 var gIgnoreFocus = false;
14 var gIgnoreClick = false;
15 var gNumTotalMessages;
16 var gNumUnreadMessages;
17
18 // search criteria mode values
19 // Note: If you change these constants, please update the menuitem values in
20 // quick-search-menupopup. Note: These values are stored in localstore.rdf so we
21 // can remember the users last quick search state. If you add values here, you must add
22 // them to the end of the list!
23 const kQuickSearchSubject = 0;
24 const kQuickSearchFrom = 1;
25 const kQuickSearchFromOrSubject = 2;
26 const kQuickSearchBody = 3;
27 // const kQuickSearchHighlight = 4; // * We no longer support this quick search mode..*
28 const kQuickSearchRecipient = 5;
29
30
SetQSStatusText
31 function SetQSStatusText(aNumHits)
32 {
33 var statusMsg;
34 // if there are no hits, it means no matches were found in the search.
35 if (aNumHits == 0)
36 statusMsg = gSearchBundle.getString("searchFailureMessage");
37 else
38 {
39 if (aNumHits == 1)
40 statusMsg = gSearchBundle.getString("searchSuccessMessage");
41 else
42 statusMsg = gSearchBundle.getFormattedString("searchSuccessMessages", [aNumHits]);
43 }
44
45 statusFeedback.showStatusString(statusMsg);
46 }
47
48 // nsIMsgSearchNotify object
49 var gSearchNotificationListener =
50 {
onSearchHit
51 onSearchHit: function(header, folder)
52 {
53 gNumTotalMessages++;
54 if (!header.isRead)
55 gNumUnreadMessages++;
56 // XXX todo
57 // update status text?
58 },
59
onSearchDone
60 onSearchDone: function(status)
61 {
62 SetQSStatusText(gDBView.QueryInterface(Components.interfaces.nsITreeView).rowCount)
63 statusFeedback.showProgress(0);
64 gStatusBar.setAttribute("mode","normal");
65 gSearchInProgress = false;
66
67 // ### TODO need to find out if there's quick search within a virtual folder.
68 if (gCurrentVirtualFolderUri &&
69 (!gSearchInput || gSearchInput.value == "" || gSearchInput.showingSearchCriteria))
70 {
71 var vFolder = GetMsgFolderFromUri(gCurrentVirtualFolderUri, false);
72 var dbFolderInfo = vFolder.getMsgDatabase(msgWindow).dBFolderInfo;
73 dbFolderInfo.NumUnreadMessages = gNumUnreadMessages;
74 dbFolderInfo.NumMessages = gNumTotalMessages;
75 vFolder.updateSummaryTotals(true); // force update from db.
76 var msgdb = vFolder.getMsgDatabase(msgWindow);
77 const MSG_DB_LARGE_COMMIT = 1;
78 msgdb.Commit(MSG_DB_LARGE_COMMIT);
79 // now that we have finished loading a virtual folder,
80 // scroll to the correct message if there is at least one.
81 if (vFolder.getTotalMessages(false) > 0)
82 ScrollToMessageAfterFolderLoad(vFolder);
83 }
84 },
85
onNewSearch
86 onNewSearch: function()
87 {
88 statusFeedback.showProgress(0);
89 statusFeedback.showStatusString(gSearchBundle.getString("searchingMessage"));
90 gStatusBar.setAttribute("mode","undetermined");
91 gSearchInProgress = true;
92 gNumTotalMessages = 0;
93 gNumUnreadMessages = 0;
94 }
95 }
96
getDocumentElements
97 function getDocumentElements()
98 {
99 gSearchBundle = document.getElementById("bundle_search");
100 gStatusBar = document.getElementById('statusbar-icon');
101 GetSearchInput();
102 }
103
addListeners
104 function addListeners()
105 {
106 gViewSearchListener = gDBView.QueryInterface(Components.interfaces.nsIMsgSearchNotify);
107 gSearchSession.registerListener(gViewSearchListener);
108 }
109
removeListeners
110 function removeListeners()
111 {
112 gSearchSession.unregisterListener(gViewSearchListener);
113 }
114
removeGlobalListeners
115 function removeGlobalListeners()
116 {
117 removeListeners();
118 gSearchSession.unregisterListener(gSearchNotificationListener);
119 }
120
initializeGlobalListeners
121 function initializeGlobalListeners()
122 {
123 // Setup the javascript object as a listener on the search results
124 gSearchSession.registerListener(gSearchNotificationListener);
125 }
126
createQuickSearchView
127 function createQuickSearchView()
128 {
129 //if not already in quick search view
130 if (gDBView.viewType != nsMsgViewType.eShowQuickSearchResults)
131 {
132 var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView); //clear selection
133 if (treeView && treeView.selection)
134 treeView.selection.clearSelection();
135 gPreQuickSearchView = gDBView;
136 if (gDBView.viewType == nsMsgViewType.eShowVirtualFolderResults)
137 {
138 // remove the view as a listener on the search results
139 var saveViewSearchListener = gDBView.QueryInterface(Components.interfaces.nsIMsgSearchNotify);
140 gSearchSession.unregisterListener(saveViewSearchListener);
141 }
142 // if grouped by sort, turn that off, as well as threaded, since we don't
143 // group quick search results yet.
144 var viewFlags = gDBView.viewFlags;
145 if (viewFlags & nsMsgViewFlagsType.kGroupBySort)
146 viewFlags &= ~(nsMsgViewFlagsType.kGroupBySort | nsMsgViewFlagsType.kThreadedDisplay);
147 CreateDBView(gDBView.msgFolder, (gXFVirtualFolderTerms) ? nsMsgViewType.eShowVirtualFolderResults : nsMsgViewType.eShowQuickSearchResults, viewFlags, gDBView.sortType, gDBView.sortOrder);
148 }
149 }
150
initializeSearchBar
151 function initializeSearchBar()
152 {
153 createQuickSearchView();
154 if (!gSearchSession)
155 {
156 getDocumentElements();
157 var searchSessionContractID = "@mozilla.org/messenger/searchSession;1";
158 gSearchSession = Components.classes[searchSessionContractID].createInstance(Components.interfaces.nsIMsgSearchSession);
159 initializeGlobalListeners();
160 }
161 else
162 {
163 if (gSearchInProgress)
164 {
165 onSearchStop();
166 gSearchInProgress = false;
167 }
168 removeListeners();
169 }
170 addListeners();
171 }
172
onEnterInSearchBar
173 function onEnterInSearchBar()
174 {
175 if (!gSearchInput || gSearchInput.value == "" || gSearchInput.showingSearchCriteria)
176 {
177 if (gDBView.viewType == nsMsgViewType.eShowQuickSearchResults
178 || gDBView.viewType == nsMsgViewType.eShowVirtualFolderResults)
179 {
180 statusFeedback.showStatusString("");
181
182 viewDebug ("onEnterInSearchBar gDefaultSearchViewTerms = " + gDefaultSearchViewTerms + "gVirtualFolderTerms = "
183 + gVirtualFolderTerms + "gXFVirtualFolderTerms = " + gXFVirtualFolderTerms + "\n");
184 var addTerms = gDefaultSearchViewTerms || gVirtualFolderTerms || gXFVirtualFolderTerms;
185 if (addTerms)
186 {
187 viewDebug ("addTerms = " + addTerms + " count = " + addTerms.Count() + "\n");
188 initializeSearchBar();
189 onSearch(addTerms);
190 }
191 else
192 restorePreSearchView();
193 }
194 else if (gPreQuickSearchView && !gDefaultSearchViewTerms)// may be a quick search from a cross-folder virtual folder
195 restorePreSearchView();
196
197 if (gSearchInput)
198 gSearchInput.showingSearchCriteria = true;
199
200 gQSViewIsDirty = false;
201 return;
202 }
203
204 initializeSearchBar();
205
206 ClearThreadPaneSelection();
207 ClearMessagePane();
208
209 onSearch(null);
210 gQSViewIsDirty = false;
211 }
212
restorePreSearchView
213 function restorePreSearchView()
214 {
215 var selectedHdr = null;
216 //save selection
217 try
218 {
219 selectedHdr = gDBView.hdrForFirstSelectedMessage;
220 }
221 catch (ex)
222 {}
223
224 //we might have to sort the view coming out of quick search
225 var sortType = gDBView.sortType;
226 var sortOrder = gDBView.sortOrder;
227 var viewFlags = gDBView.viewFlags;
228 var folder = gDBView.msgFolder;
229
230 gDBView.close();
231 gDBView = null;
232
233 if (gPreQuickSearchView)
234 {
235 gDBView = gPreQuickSearchView;
236 if (gDBView.viewType == nsMsgViewType.eShowVirtualFolderResults)
237 {
238 // read the view as a listener on the search results
239 var saveViewSearchListener = gDBView.QueryInterface(Components.interfaces.nsIMsgSearchNotify);
240 if (gSearchSession)
241 gSearchSession.registerListener(saveViewSearchListener);
242 }
243 // dump ("view type = " + gDBView.viewType + "\n");
244
245 if (sortType != gDBView.sortType || sortOrder != gDBView.sortOrder)
246 {
247 gDBView.sort(sortType, sortOrder);
248 }
249 UpdateSortIndicators(sortType, sortOrder);
250
251 gPreQuickSearchView = null;
252 }
253 else //create default view type
254 {
255 CreateDBView(folder, nsMsgViewType.eShowAllThreads, viewFlags, sortType, sortOrder);
256 }
257
258 RerootThreadPane();
259
260 var scrolled = false;
261
262 // now restore selection
263 if (selectedHdr)
264 {
265 gDBView.selectMsgByKey(selectedHdr.messageKey);
266 var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
267 var selectedIndex = treeView.selection.currentIndex;
268 if (selectedIndex >= 0)
269 {
270 // scroll
271 EnsureRowInThreadTreeIsVisible(selectedIndex);
272 scrolled = true;
273 }
274 else
275 ClearMessagePane();
276 }
277
278 if (!scrolled)
279 ScrollToMessageAfterFolderLoad(null);
280 }
281
onSearch
282 function onSearch(aSearchTerms)
283 {
284 viewDebug("in OnSearch, searchTerms = " + aSearchTerms + "\n");
285 RerootThreadPane();
286
287 if (aSearchTerms)
288 createSearchTermsWithList(aSearchTerms);
289 else
290 createSearchTerms();
291
292 gDBView.searchSession = gSearchSession;
293 try
294 {
295 gSearchSession.search(msgWindow);
296 }
297 catch(ex)
298 {
299 dump("Search Exception\n");
300 }
301 }
302
createSearchTermsWithList
303 function createSearchTermsWithList(aTermsArray)
304 {
305 var nsMsgSearchScope = Components.interfaces.nsMsgSearchScope;
306 var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
307 var nsMsgSearchOp = Components.interfaces.nsMsgSearchOp;
308
309 gSearchSession.clearScopes();
310 var searchTerms = gSearchSession.searchTerms;
311 var searchTermsArray = searchTerms.QueryInterface(Components.interfaces.nsISupportsArray);
312 searchTermsArray.Clear();
313
314 var i;
315 var selectedFolder = GetThreadPaneFolder();
316 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
317 .getService(Components.interfaces.nsIIOService);
318
319 var termsArray = aTermsArray.QueryInterface(Components.interfaces.nsISupportsArray);
320
321 if (gXFVirtualFolderTerms)
322 {
323 var msgDatabase = selectedFolder.getMsgDatabase(msgWindow);
324 if (msgDatabase)
325 {
326 var dbFolderInfo = msgDatabase.dBFolderInfo;
327 var srchFolderUri = dbFolderInfo.getCharProperty("searchFolderUri");
328 viewDebug("createSearchTermsWithList xf vf scope = " + srchFolderUri + "\n");
329 var srchFolderUriArray = srchFolderUri.split('|');
330 for (i in srchFolderUriArray)
331 {
332 var realFolderRes = GetResourceFromUri(srchFolderUriArray[i]);
333 var realFolder = realFolderRes.QueryInterface(Components.interfaces.nsIMsgFolder);
334 if (!realFolder.isServer)
335 gSearchSession.addScopeTerm(getScopeToUse(termsArray, realFolder, ioService.offline), realFolder);
336 }
337 }
338 }
339 else
340 {
341 viewDebug ("in createSearchTermsWithList, adding scope term for selected folder\n");
342 gSearchSession.addScopeTerm(getScopeToUse(termsArray, selectedFolder, ioService.offline), selectedFolder);
343 }
344
345 // add each item in termsArray to the search session
346 for (i = 0; i < termsArray.Count(); ++i)
347 gSearchSession.appendTerm(termsArray.GetElementAt(i).QueryInterface(Components.interfaces.nsIMsgSearchTerm));
348 }
349
getScopeToUse
350 function getScopeToUse(aTermsArray, aFolderToSearch, aIsOffline)
351 {
352 if (aIsOffline || aFolderToSearch.server.type != 'imap')
353 return nsMsgSearchScope.offlineMail;
354
355 var scopeToUse = gSearchInput && gSearchInput.searchMode == kQuickSearchBody && !gSearchInput.showingSearchCriteria
356 ? nsMsgSearchScope.onlineMail : nsMsgSearchScope.offlineMail;
357
358 // it's possible one of our search terms may require us to use an online mail scope (such as imap body searches)
359 for (var i = 0; scopeToUse != nsMsgSearchScope.onlineMail && i < aTermsArray.Count(); i++)
360 if (aTermsArray.GetElementAt(i).QueryInterface(Components.interfaces.nsIMsgSearchTerm).attrib == nsMsgSearchAttrib.Body)
361 scopeToUse = nsMsgSearchScope.onlineMail;
362
363 return scopeToUse;
364 }
365
createSearchTerms
366 function createSearchTerms()
367 {
368 var nsMsgSearchScope = Components.interfaces.nsMsgSearchScope;
369 var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
370 var nsMsgSearchOp = Components.interfaces.nsMsgSearchOp;
371
372 // create an i supports array to store our search terms
373 var searchTermsArray = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
374 var selectedFolder = GetThreadPaneFolder();
375
376 var searchAttrib = (IsSpecialFolder(selectedFolder, MSG_FOLDER_FLAG_SENTMAIL | MSG_FOLDER_FLAG_DRAFTS | MSG_FOLDER_FLAG_QUEUE, true)) ? nsMsgSearchAttrib.ToOrCC : nsMsgSearchAttrib.Sender;
377 // implement | for QS
378 // does this break if the user types "foo|bar" expecting to see subjects with that string?
379 // I claim no, since "foo|bar" will be a hit for "foo" || "bar"
380 // they just might get more false positives
381 if (!gSearchInput.showingSearchCriteria) // ignore the text box value if it's just showing the search criteria string
382 {
383 var termList = gSearchInput.value.split("|");
384 for (var i = 0; i < termList.length; i ++)
385 {
386 // if the term is empty, skip it
387 if (termList[i] == "")
388 continue;
389
390 // create, fill, and append the subject term
391 var term;
392 var value;
393
394 // if our search criteria is subject or subject|from then add a term for the subject
395 if (gSearchInput.searchMode == kQuickSearchSubject || gSearchInput.searchMode == kQuickSearchFromOrSubject)
396 {
397 term = gSearchSession.createTerm();
398 value = term.value;
399 value.str = termList[i];
400 term.value = value;
401 term.attrib = nsMsgSearchAttrib.Subject;
402 term.op = nsMsgSearchOp.Contains;
403 term.booleanAnd = false;
404 searchTermsArray.AppendElement(term);
405 }
406
407 if (gSearchInput.searchMode == kQuickSearchBody)
408 {
409 // what do we do for news and imap users that aren't configured for offline use?
410 // in these cases the body search will never return any matches. Should we try to
411 // see if body is a valid search scope in this particular case before doing the search?
412 // should we switch back to a subject/from search behind the scenes?
413 term = gSearchSession.createTerm();
414 value = term.value;
415 value.str = termList[i];
416 term.value = value;
417 term.attrib = nsMsgSearchAttrib.Body;
418 term.op = nsMsgSearchOp.Contains;
419 term.booleanAnd = false;
420 searchTermsArray.AppendElement(term);
421 }
422
423 // create, fill, and append the from (or recipient) term
424 if (gSearchInput.searchMode == kQuickSearchFrom || gSearchInput.searchMode == kQuickSearchFromOrSubject)
425 {
426 term = gSearchSession.createTerm();
427 value = term.value;
428 value.str = termList[i];
429 term.value = value;
430 term.attrib = searchAttrib;
431 term.op = nsMsgSearchOp.Contains;
432 term.booleanAnd = false;
433 searchTermsArray.AppendElement(term);
434 }
435
436 // create, fill, and append the recipient
437 if (gSearchInput.searchMode == kQuickSearchRecipient)
438 {
439 term = gSearchSession.createTerm();
440 value = term.value;
441 value.str = termList[i];
442 term.value = value;
443 term.attrib = nsMsgSearchAttrib.ToOrCC;
444 term.op = nsMsgSearchOp.Contains;
445 term.booleanAnd = false;
446 searchTermsArray.AppendElement(term);
447 }
448 }
449 }
450
451 // now append the default view or virtual folder criteria to the quick search
452 // so we don't lose any default view information
453 viewDebug("gDefaultSearchViewTerms = " + gDefaultSearchViewTerms + "gVirtualFolderTerms = " + gVirtualFolderTerms +
454 "gXFVirtualFolderTerms = " + gXFVirtualFolderTerms + "\n");
455 var defaultSearchTerms = (gDefaultSearchViewTerms || gVirtualFolderTerms || gXFVirtualFolderTerms);
456 if (defaultSearchTerms)
457 {
458 var isupports = null;
459 var searchTerm;
460 var termsArray = defaultSearchTerms.QueryInterface(Components.interfaces.nsISupportsArray);
461 for (i = 0; i < termsArray.Count(); i++)
462 {
463 isupports = termsArray.GetElementAt(i);
464 searchTerm = isupports.QueryInterface(Components.interfaces.nsIMsgSearchTerm);
465 searchTermsArray.AppendElement(searchTerm);
466 }
467 }
468
469 createSearchTermsWithList(searchTermsArray);
470
471 // now that we've added the terms, clear out our input array
472 searchTermsArray.Clear();
473 }
474
onSearchStop
475 function onSearchStop()
476 {
477 gSearchSession.interruptSearch();
478 }
479
onSearchKeyPress
480 function onSearchKeyPress(event)
481 {
482 if (gSearchInput.showingSearchCriteria)
483 gSearchInput.showingSearchCriteria = false;
484
485 // 13 == return
486 if (event && event.keyCode == 13)
487 onSearchInput(true);
488 }
489
onSearchInputFocus
490 function onSearchInputFocus(event)
491 {
492 GetSearchInput();
493 // search bar has focus, ...clear the showing search criteria flag
494 if (gSearchInput.showingSearchCriteria)
495 {
496 gSearchInput.value = "";
497 gSearchInput.showingSearchCriteria = false;
498 }
499
500 if (gIgnoreFocus) // got focus via mouse click, don't need to anything else
501 gIgnoreFocus = false;
502 else
503 {
504 gSearchInput.select();
505 gQuickSearchFocusEl = gSearchInput; // only important that this be non-null
506 }
507 }
508
onSearchInputMousedown
509 function onSearchInputMousedown(event)
510 {
511 GetSearchInput();
512 if (gSearchInput.hasAttribute("focused"))
513 {
514 gIgnoreClick = true;
515
516 // already focused, don't need to restore focus elsewhere (if the Clear button was clicked)
517 // ##HACK## Need to check 'clearButtonHidden' because the field is blurred when it has
518 // focus and the hidden button is clicked, in which case we want to perform the normal
519 // onBlur function.
520 gQuickSearchFocusEl = gSearchInput.clearButtonHidden ? gSearchInput : null;
521 }
522 else
523 {
524 gIgnoreFocus = true;
525 gIgnoreClick = false;
526
527 // save the last focused element so that focus can be restored (if the Clear button was clicked)
528 gQuickSearchFocusEl = gLastFocusedElement;
529 }
530 // (if Clear button was clicked, onClearSearch() is called before onSearchInputClick())
531 }
532
533
onSearchInputClick
534 function onSearchInputClick(event)
535 {
536 if (!gIgnoreClick)
537 {
538 gQuickSearchFocusEl = null; // ##HACK## avoid onSearchInputBlur() side effects
539 gSearchInput.select(); // ## triggers onSearchInputBlur(), but focus returns to field
540 }
541 if (!gQuickSearchFocusEl)
542 gQuickSearchFocusEl = gSearchInput; // mousedown wasn't on Clear button
543 }
544
onSearchInputBlur
545 function onSearchInputBlur(event)
546 {
547 if (!gQuickSearchFocusEl) // ignore the blur if we are in the middle of processing the clear button
548 return;
549
550 gQuickSearchFocusEl = null;
551 if (!gSearchInput.value)
552 gSearchInput.showingSearchCriteria = true;
553
554 if (gSearchInput.showingSearchCriteria)
555 gSearchInput.setSearchCriteriaText();
556 }
557
onSearchInput
558 function onSearchInput(returnKeyHit)
559 {
560 if (gSearchInput.showingSearchCriteria && !(returnKeyHit && gSearchInput.value == ""))
561 return;
562
563 if (gSearchTimer) {
564 clearTimeout(gSearchTimer);
565 gSearchTimer = null;
566 }
567
568 // only select the text when the return key was hit
569 if (returnKeyHit) {
570 gSearchInput.select();
571 onEnterInSearchBar();
572 }
573 else {
574 gSearchTimer = setTimeout("onEnterInSearchBar();", 800);
575 }
576 }
577
578 // temporary global used to make sure we restore focus to the correct element after clearing the quick search box
579 // because clearing quick search means stealing focus.
580 var gQuickSearchFocusEl = null;
581
onClearSearch
582 function onClearSearch()
583 {
584 if (!gSearchInput.showingSearchCriteria) // ignore the text box value if it's just showing the search criteria string
585 {
586 Search("");
587 gIgnoreClick = true;
588 // this needs to be on a timer otherwise we end up messing up the focus while the Search("") is still happening
589 if (gQuickSearchFocusEl) // set in onSearchInputMouseDown
590 setTimeout("restoreSearchFocusAfterClear();", 0);
591 }
592 }
593
restoreSearchFocusAfterClear
594 function restoreSearchFocusAfterClear()
595 {
596 if (gQuickSearchFocusEl)
597 gQuickSearchFocusEl.focus();
598 }
599
600 // called from commandglue.js in cases where the view is being changed and QS
601 // needs to be cleared.
ClearQSIfNecessary
602 function ClearQSIfNecessary()
603 {
604 if (!gSearchInput || gSearchInput.showingSearchCriteria)
605 return;
606 gSearchInput.setSearchCriteriaText();
607 }
608
Search
609 function Search(str)
610 {
611 viewDebug("in Search str = " + str + "gSearchInput.showingSearchCriteria = " + gSearchInput.showingSearchCriteria + "\n");
612 if (gSearchInput.showingSearchCriteria && str != "")
613 return;
614
615 if (str != gSearchInput.value)
616 {
617 gQSViewIsDirty = true;
618 viewDebug("in Search(), setting gQSViewIsDirty true\n");
619 }
620
621 gSearchInput.value = str; //on input does not get fired for some reason
622 onSearchInput(true);
623 }
624
625 // helper methods for the quick search drop down menu
changeQuickSearchMode
626 function changeQuickSearchMode(aMenuItem)
627 {
628 viewDebug("changing quick search mode\n");
629 // extract the label and set the search input to match it
630 var oldSearchMode = gSearchInput.searchMode;
631 gSearchInput.searchMode = aMenuItem.value;
632
633 if (gSearchInput.value == "" || gSearchInput.showingSearchCriteria)
634 {
635 gSearchInput.showingSearchCriteria = true;
636 if (gSearchInput.value) //
637 gSearchInput.setSearchCriteriaText();
638 }
639
640 // if the search box is empty, set showing search criteria to true so it shows up when focus moves out of the box
641 if (!gSearchInput.value)
642 gSearchInput.showingSearchCriteria = true;
643 else if (gSearchInput.showingSearchCriteria) // if we are showing criteria text and the box isn't empty, change the criteria text
644 gSearchInput.setSearchCriteriaText();
645 else if (oldSearchMode != gSearchInput.searchMode) // the search mode just changed so we need to redo the quick search
646 onEnterInSearchBar();
647 }
648
saveViewAsVirtualFolder
649 function saveViewAsVirtualFolder()
650 {
651 openNewVirtualFolderDialogWithArgs(gSearchInput.value, gSearchSession.searchTerms);
652 }
653
654 function InitQuickSearchPopup()
655 {
656 // disable the create virtual folder menu item if the current radio
657 // value is set to Find in message since you can't really create a VF from find
658 // in message
659
660 GetSearchInput();
661 if (!gSearchInput ||gSearchInput.value == "" || gSearchInput.showingSearchCriteria)
662 document.getElementById('quickSearchSaveAsVirtualFolder').setAttribute('disabled', 'true');
663 else
664 document.getElementById('quickSearchSaveAsVirtualFolder').removeAttribute('disabled');
665 }