!import
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is Mozilla Communicator client code, released
16 * March 31, 1998.
17 *
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998-1999
21 * the Initial Developer. All Rights Reserved.
22 *
23 * Contributor(s):
24 * Mark Banner <mark@standard8.demon.co.uk>
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40 const MSG_FOLDER_FLAG_INBOX = 0x1000
41
42 var gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
43
44 var gEditButton;
45 var gDeleteButton;
46 var gReorderUpButton;
47 var gReorderDownButton;
48 var gRunFiltersFolderPickerLabel;
49 var gRunFiltersFolderPicker;
50 var gRunFiltersButton;
51 var gFilterBundle;
52 var gPromptService = GetPromptService();
53 var gFilterListMsgWindow = null;
54 var gFilterTree;
55 var gStatusBar;
56 var gStatusText;
57 var gCurrentServerURI = null;
58
59 var gStatusFeedback = {
60 progressMeterVisible : false,
61
showStatusString
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
62 showStatusString: function(status)
63 {
64 gStatusText.setAttribute("value", status);
65 },
startMeteors
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
66 startMeteors: function()
67 {
68 // change run button to be a stop button
69 gRunFiltersButton.setAttribute("label", gRunFiltersButton.getAttribute("stoplabel"));
70 gRunFiltersButton.setAttribute("accesskey", gRunFiltersButton.getAttribute("stopaccesskey"));
71
72 if (!this.progressMeterVisible)
73 {
74 document.getElementById('statusbar-progresspanel').removeAttribute('collapsed');
75 this.progressMeterVisible = true;
76 }
77
78 gStatusBar.setAttribute("mode", "undetermined");
79 },
stopMeteors
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
80 stopMeteors: function()
81 {
82 try {
83 // change run button to be a stop button
84 gRunFiltersButton.setAttribute("label", gRunFiltersButton.getAttribute("runlabel"));
85 gRunFiltersButton.setAttribute("accesskey", gRunFiltersButton.getAttribute("runaccesskey"));
86 gStatusBar.setAttribute("mode", "normal");
87
88 if (this.progressMeterVisible)
89 {
90 document.getElementById('statusbar-progresspanel').collapsed = true;
91 this.progressMeterVisible = true;
92 }
93 }
94 catch (ex) {
95 // can get here if closing window when running filters
96 }
97 },
showProgress
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
98 showProgress: function(percentage)
99 {
100 //dump("XXX progress" + percentage + "\n");
101 },
closeWindow
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
102 closeWindow: function()
103 {
104 }
105 };
106
107 const nsMsgFilterMotion = Components.interfaces.nsMsgFilterMotion;
108
onLoad
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
109 function onLoad()
110 {
111 gFilterListMsgWindow = Components.classes["@mozilla.org/messenger/msgwindow;1"].createInstance(Components.interfaces.nsIMsgWindow);
112 gFilterListMsgWindow.domWindow = window;
113 gFilterListMsgWindow.rootDocShell.appType = Components.interfaces.nsIDocShell.APP_TYPE_MAIL;
114 gFilterListMsgWindow.statusFeedback = gStatusFeedback;
115
116 gFilterBundle = document.getElementById("bundle_filter");
117 gFilterTree = document.getElementById("filterTree");
118
119 gEditButton = document.getElementById("editButton");
120 gDeleteButton = document.getElementById("deleteButton");
121 gReorderUpButton = document.getElementById("reorderUpButton");
122 gReorderDownButton = document.getElementById("reorderDownButton");
123 gRunFiltersFolderPickerLabel = document.getElementById("folderPickerPrefix");
124 gRunFiltersFolderPicker = document.getElementById("runFiltersFolder");
125 gRunFiltersButton = document.getElementById("runFiltersButton");
126 gStatusBar = document.getElementById("statusbar-icon");
127 gStatusText = document.getElementById("statusText");
128
129 updateButtons();
130
131 // get the selected server if it can have filters.
132 var firstItem = getSelectedServerForFilters();
133
134 // if the selected server cannot have filters, get the default server
135 // if the default server cannot have filters, check all accounts
136 // and get a server that can have filters.
137 if (!firstItem)
138 firstItem = getServerThatCanHaveFilters();
139
140 if (firstItem) {
141 selectServer(firstItem);
142 }
143
144 gFilterTree.addEventListener("click",onFilterClick,true);
145 }
146
147 /*
148 function onCancel()
149 {
150 var firstItem = getSelectedServerForFilters();
151 if (!firstItem)
152 firstItem = getServerThatCanHaveFilters();
153
154 if (firstItem) {
155 var resource = gRDF.GetResource(firstItem);
156 var msgFolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
157 if (msgFolder)
158 {
159 msgFolder.ReleaseDelegate("filter");
160 msgFolder.setFilterList(null);
161 try
162 {
163 //now find Inbox
164 var outNumFolders = new Object();
165 var inboxFolder = msgFolder.getFoldersWithFlag(0x1000, 1, outNumFolders);
166 inboxFolder.setFilterList(null);
167 }
168 catch(ex)
169 {
170 dump ("ex " +ex + "\n");
171 }
172 }
173 }
174 window.close();
175 }
176 */
177
178 /**
179 * Called when a user selects a server in the list, so we can update the filters
180 * that are displayed
181 *
182 * @param aURI the uri of the server that was selected
183 */
onFilterServerClick
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
184 function onFilterServerClick(aURI)
185 {
186 if (!aURI || aURI == gCurrentServerURI)
187 return;
188
189 // Save the current filters to disk before switching because
190 // the dialog may be closed and we'll lose current filters.
191 var filterList = currentFilterList();
192 if (filterList)
193 filterList.saveToDefaultFile();
194
195 selectServer(aURI);
196 }
197
CanRunFiltersAfterTheFact
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
198 function CanRunFiltersAfterTheFact(aServer)
199 {
200 // can't manually run news filters yet
201 if (aServer.type == "nntp")
202 return false;
203
204 // filter after the fact is implement using search
205 // so if you can't search, you can't filter after the fact
206 return aServer.canSearchMessages;
207 }
208
209 // roots the tree at the specified server
setServer
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
210 function setServer(uri)
211 {
212 if (uri == gCurrentServerURI)
213 return;
214
215 var resource = gRDF.GetResource(uri);
216 var msgFolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
217
218 //Calling getFilterList will detect any errors in rules.dat, backup the file, and alert the user
219 //we need to do this because gFilterTree.setAttribute will cause rdf to call getFilterList and there is
220 //no way to pass msgWindow in that case.
221
222 if (msgFolder)
223 msgFolder.getFilterList(gFilterListMsgWindow);
224
225 // this will get the deferred to account root folder, if server is deferred
226 msgFolder = msgFolder.server.rootMsgFolder;
227 var rootFolderUri = msgFolder.URI;
228 rebuildFilterTree(uri);
229
230 // root the folder picker to this server
231 gRunFiltersFolderPicker.setAttribute("ref", rootFolderUri);
232
233 // run filters after the fact not supported by news
234 if (CanRunFiltersAfterTheFact(msgFolder.server)) {
235 gRunFiltersFolderPicker.removeAttribute("hidden");
236 gRunFiltersButton.removeAttribute("hidden");
237 gRunFiltersFolderPickerLabel.removeAttribute("hidden");
238
239 // for POP3 and IMAP, select the first folder, which is the INBOX
240 gRunFiltersFolderPicker.selectedIndex = 0;
241 }
242 else {
243 gRunFiltersFolderPicker.setAttribute("hidden", "true");
244 gRunFiltersButton.setAttribute("hidden", "true");
245 gRunFiltersFolderPickerLabel.setAttribute("hidden", "true");
246 }
247
248 // Get the first folder uri for this server. INBOX for
249 // imap and pop accts and 1st news group for news.
250 var firstFolderURI = getFirstFolderURI(msgFolder);
251 SetFolderPicker(firstFolderURI, "runFiltersFolder");
252 updateButtons();
253
254 gCurrentServerURI = uri;
255 }
256
toggleFilter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
257 function toggleFilter(aResource)
258 {
259 var filter = aResource.GetDelegate("filter",
260 Components.interfaces.nsIMsgFilter);
261 if (filter.unparseable)
262 {
263 if (gPromptService)
264 gPromptService.alert(window, null,
265 gFilterBundle.getString("cannotEnableFilter"));
266 return;
267 }
268 filter.enabled = !filter.enabled;
269 refresh();
270 }
271
272 // sets up the menulist and the gFilterTree
selectServer
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
273 function selectServer(uri)
274 {
275 // update the server menu
276 var serverMenu = document.getElementById("serverMenu");
277
278 var resource = gRDF.GetResource(uri);
279 var msgFolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
280
281 // XXX todo
282 // See msgFolderPickerOverlay.js, SetFolderPicker()
283 // why do we have to do this? seems like a hack to work around a bug.
284 // the bug is that the (deep) content isn't there
285 // and so this won't work:
286 //
287 // var menuitems = serverMenu.getElementsByAttribute("id", uri);
288 // serverMenu.selectedItem = menuitems[0];
289 //
290 // we might need help from a XUL template expert to help out here.
291 // see bug #XXXXXX
292 serverMenu.setAttribute("label", msgFolder.name);
293 serverMenu.setAttribute("uri",uri);
294
295 setServer(uri);
296 }
297
getFilter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
298 function getFilter(index)
299 {
300 var filter = gFilterTree.builderView.getResourceAtIndex(index);
301 filter = filter.GetDelegate("filter", Components.interfaces.nsIMsgFilter);
302 return filter;
303 }
304
currentFilter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
305 function currentFilter()
306 {
307 var currentIndex = gFilterTree.currentIndex;
308 if (currentIndex == -1)
309 return null;
310
311 var filter;
312
313 try {
314 filter = getFilter(currentIndex);
315 } catch (ex) {
316 filter = null;
317 }
318 return filter;
319 }
320
currentFilterList
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
321 function currentFilterList()
322 {
323 // note, serverUri might be a newsgroup
324 var serverUri = document.getElementById("serverMenu").getAttribute("uri");
325 var filterList = gRDF.GetResource(serverUri).GetDelegate("filter", Components.interfaces.nsIMsgFilterList);
326 return filterList;
327 }
328
onFilterSelect
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
329 function onFilterSelect(event)
330 {
331 updateButtons();
332 }
333
onEditFilter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
334 function onEditFilter()
335 {
336 var selectedFilter = currentFilter();
337 var curFilterList = currentFilterList();
338 var args = {filter: selectedFilter, filterList: curFilterList};
339
340 window.openDialog("chrome://messenger/content/FilterEditor.xul", "FilterEditor", "chrome,modal,titlebar,resizable,centerscreen", args);
341
342 if ("refresh" in args && args.refresh)
343 refresh();
344 }
345
onNewFilter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
346 function onNewFilter(emailAddress)
347 {
348 var curFilterList = currentFilterList();
349 var args = {filterList: curFilterList};
350
351 window.openDialog("chrome://messenger/content/FilterEditor.xul", "FilterEditor", "chrome,modal,titlebar,resizable,centerscreen", args);
352
353 if ("refresh" in args && args.refresh)
354 refresh();
355 }
356
onDeleteFilter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
357 function onDeleteFilter()
358 {
359 var filterList = currentFilterList();
360 if (!filterList)
361 return;
362
363 var sel = gFilterTree.view.selection, selCount = sel.getRangeCount();
364 if (!selCount ||
365 gPromptService.confirmEx(window, null,
366 gFilterBundle.getString("deleteFilterConfirmation"),
367 gPromptService.STD_YES_NO_BUTTONS,
368 '', '', '', '', {}))
369 return;
370
371 for (var i = selCount - 1; i >= 0; --i) {
372 var start = {}, end = {};
373 sel.getRangeAt(i, start, end);
374 for (var j = end.value; j >= start.value; --j) {
375 var curFilter = getFilter(j);
376 if (curFilter)
377 filterList.removeFilter(curFilter);
378 }
379 }
380 refresh();
381 }
382
onUp
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
383 function onUp(event)
384 {
385 moveCurrentFilter(nsMsgFilterMotion.up);
386 }
387
onDown
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
388 function onDown(event)
389 {
390 moveCurrentFilter(nsMsgFilterMotion.down);
391 }
392
viewLog
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
393 function viewLog()
394 {
395 var uri = gFilterTree.getAttribute("ref");
396 var server = gRDF.GetResource(uri).QueryInterface(Components.interfaces.nsIMsgFolder).server;
397
398 var filterList = currentFilterList();
399 var args = {filterList: filterList};
400
401 window.openDialog("chrome://messenger/content/viewLog.xul", "FilterLog", "chrome,modal,titlebar,resizable,centerscreen", args);
402 }
403
onFilterClose
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
404 function onFilterClose()
405 {
406 // make sure to save the filter to disk
407 var filterList = currentFilterList();
408 if (filterList)
409 filterList.saveToDefaultFile();
410
411 if (gRunFiltersButton.getAttribute("label") == gRunFiltersButton.getAttribute("stoplabel")) {
412 var promptTitle = gFilterBundle.getString("promptTitle");
413 var promptMsg = gFilterBundle.getString("promptMsg");
414 var stopButtonLabel = gFilterBundle.getString("stopButtonLabel");
415 var continueButtonLabel = gFilterBundle.getString("continueButtonLabel");
416 var result = false;
417
418 if (gPromptService)
419 result = gPromptService.confirmEx(window, promptTitle, promptMsg,
420 (gPromptService.BUTTON_TITLE_IS_STRING*gPromptService.BUTTON_POS_0) +
421 (gPromptService.BUTTON_TITLE_IS_STRING*gPromptService.BUTTON_POS_1),
422 continueButtonLabel, stopButtonLabel, null, null, {value:0});
423
424 if (result)
425 gFilterListMsgWindow.StopUrls();
426 else
427 return false;
428 }
429
430 window.close();
431 return true;
432 }
433
runSelectedFilters
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
434 function runSelectedFilters()
435 {
436 // if run button has "stop" label, do stop.
437 if (gRunFiltersButton.getAttribute("label") == gRunFiltersButton.getAttribute("stoplabel")) {
438 gFilterListMsgWindow.StopUrls();
439 return;
440 }
441
442 var folderURI = gRunFiltersFolderPicker.getAttribute("uri");
443 var resource = gRDF.GetResource(folderURI);
444 var msgFolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
445 var filterService = Components.classes["@mozilla.org/messenger/services/filters;1"].getService(Components.interfaces.nsIMsgFilterService);
446 var filterList = filterService.getTempFilterList(msgFolder);
447 var folders = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
448 folders.AppendElement(msgFolder);
449
450 // make sure the tmp filter list uses the real filter list log stream
451 filterList.logStream = currentFilterList().logStream;
452 filterList.loggingEnabled = currentFilterList().loggingEnabled;
453 var index = 0, sel = gFilterTree.view.selection;
454 for (var i = 0; i < sel.getRangeCount(); i++) {
455 var start = {}, end = {};
456 sel.getRangeAt(i, start, end);
457 for (var j = start.value; j <= end.value; j++) {
458 var curFilter = getFilter(j);
459 if (curFilter)
460 filterList.insertFilterAt(index++, curFilter);
461 }
462 }
463
464 filterService.applyFiltersToFolders(filterList, folders, gFilterListMsgWindow);
465 }
466
moveCurrentFilter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
467 function moveCurrentFilter(motion)
468 {
469 var filterList = currentFilterList();
470 var filter = currentFilter();
471 if (!filterList || !filter)
472 return;
473
474 filterList.moveFilter(filter, motion);
475 refresh();
476 }
477
rebuildFilterTree
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
478 function rebuildFilterTree(uri)
479 {
480 gFilterTree.view.selection.clearSelection();
481 gFilterTree.removeAttribute("ref");
482 gFilterTree.setAttribute("ref", uri);
483 }
484
refresh
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
485 function refresh()
486 {
487 if (!gFilterTree)
488 return;
489
490 var selectedRes;
491
492 // store the selected resource before we rebuild the tree
493 try {
494 selectedRes = gFilterTree.currentIndex >= 0 ? gFilterTree.builderView.getResourceAtIndex(gFilterTree.currentIndex) : null;
495 }
496 catch (ex) {
497 dump("ex = " + ex + "\n");
498 selectedRes = null;
499 }
500
501 rebuildFilterTree(gCurrentServerURI);
502
503 // restore selection to the previous selected resource
504 if (selectedRes) {
505 var previousSel = gFilterTree.builderView.getIndexOfResource(selectedRes);
506 if (previousSel >= 0) {
507 // sometimes the selected element is gone.
508 gFilterTree.view.selection.select(previousSel);
509 gFilterTree.treeBoxObject.ensureRowIsVisible(previousSel);
510 }
511 }
512 }
513
updateButtons
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
514 function updateButtons()
515 {
516 var numFiltersSelected = gFilterTree.view.selection.count;
517 var oneFilterSelected = (numFiltersSelected == 1);
518
519 var filter = currentFilter();
520 // "edit" only enabled when one filter selected or if we couldn't parse the filter
521 gEditButton.disabled = !oneFilterSelected || filter.unparseable;
522
523 // "delete" only disabled when no filters are selected
524 gDeleteButton.disabled = !numFiltersSelected;
525
526 // we can run multiple filters on a folder
527 // so only disable this UI if no filters are selected
528 gRunFiltersFolderPickerLabel.disabled = !numFiltersSelected;
529 gRunFiltersFolderPicker.disabled = !numFiltersSelected;
530 gRunFiltersButton.disabled = !numFiltersSelected;
531
532 // "up" enabled only if one filter selected, and it's not the first
533 gReorderUpButton.disabled = !(oneFilterSelected && gFilterTree.currentIndex > 0);
534 // "down" enabled only if one filter selected, and it's not the last
535 gReorderDownButton.disabled = !(oneFilterSelected && gFilterTree.currentIndex < gFilterTree.view.rowCount-1);
536 }
537
538 /**
539 * get the selected server if it can have filters
540 */
getSelectedServerForFilters
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
541 function getSelectedServerForFilters()
542 {
543 var firstItem = null;
544 var args = window.arguments;
545 var selectedFolder = args[0].folder;
546
547 if (args && args[0] && selectedFolder)
548 {
549 var msgFolder = selectedFolder.QueryInterface(Components.interfaces.nsIMsgFolder);
550 try
551 {
552 var rootFolder = msgFolder.server.rootFolder;
553 if (rootFolder.isServer)
554 {
555 var server = rootFolder.server;
556
557 if (server.canHaveFilters)
558 {
559 // for news, select the news folder
560 // for everything else, select the folder's server
561 firstItem = (server.type == "nntp") ? msgFolder.URI : rootFolder.URI;
562 }
563 }
564 }
565 catch (ex)
566 {
567 }
568 }
569
570 return firstItem;
571 }
572
573 /** if the selected server cannot have filters, get the default server
574 * if the default server cannot have filters, check all accounts
575 * and get a server that can have filters.
576 */
getServerThatCanHaveFilters
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
577 function getServerThatCanHaveFilters()
578 {
579 var firstItem = null;
580
581 var accountManager
582 = Components.classes["@mozilla.org/messenger/account-manager;1"].
583 getService(Components.interfaces.nsIMsgAccountManager);
584
585 var defaultAccount = accountManager.defaultAccount;
586 var defaultIncomingServer = defaultAccount.incomingServer;
587
588 // check to see if default server can have filters
589 if (defaultIncomingServer.canHaveFilters) {
590 firstItem = defaultIncomingServer.serverURI;
591 }
592 // if it cannot, check all accounts to find a server
593 // that can have filters
594 else
595 {
596 var allServers = accountManager.allServers;
597 var numServers = allServers.Count();
598 var index = 0;
599 for (index = 0; index < numServers; index++)
600 {
601 var currentServer
602 = allServers.GetElementAt(index).QueryInterface(Components.interfaces.nsIMsgIncomingServer);
603
604 if (currentServer.canHaveFilters)
605 {
606 firstItem = currentServer.serverURI;
607 break;
608 }
609 }
610 }
611
612 return firstItem;
613 }
614
onFilterClick
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
615 function onFilterClick(event)
616 {
617 // we only care about button 0 (left click) events
618 if (event.button != 0)
619 return;
620
621 var row = {}, col = {}, childElt = {};
622 var filterTree = document.getElementById("filterTree");
623 filterTree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, childElt);
624 if (row.value == -1 || row.value > filterTree.view.rowCount-1 || event.originalTarget.localName != "treechildren") {
625 if (event.originalTarget.localName == "treecol") {
626 // clicking on the name column in the filter list should not sort
627 event.stopPropagation();
628 }
629 return;
630 }
631
632 if (col.value.id == "activeColumn") {
633 toggleFilter(filterTree.builderView.getResourceAtIndex(row.value));
634 }
635 }
636
onFilterDoubleClick
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
637 function onFilterDoubleClick(event)
638 {
639 // we only care about button 0 (left click) events
640 if (event.button != 0)
641 return;
642
643 var row = {}, col = {}, childElt = {};
644 var filterTree = document.getElementById("filterTree");
645 filterTree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, childElt);
646 if (row.value == -1 || row.value > filterTree.view.rowCount-1 || event.originalTarget.localName != "treechildren") {
647 // double clicking on a non valid row should not open the edit filter dialog
648 return;
649 }
650
651 // if the cell is in a "cycler" column (the enabled column)
652 // don't open the edit filter dialog with the selected filter
653 if (!col.value.cycler)
654 onEditFilter();
655 }
656
onFilterTreeKeyPress
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
657 function onFilterTreeKeyPress(event)
658 {
659 // for now, only do something on space key
660 if (event.charCode != KeyEvent.DOM_VK_SPACE)
661 return;
662
663 var rangeCount = gFilterTree.view.selection.getRangeCount();
664 for (var i = 0; i < rangeCount; ++i) {
665 var start = {}, end = {};
666 gFilterTree.view.selection.getRangeAt(i, start, end);
667 for (var k = start.value; k <= end.value; ++k) {
668 toggleFilter(gFilterTree.builderView.getResourceAtIndex(k));
669 }
670 }
671 }
672
doHelpButton
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
673 function doHelpButton()
674 {
675 openHelp("mail-filters");
676 }
677
678 /**
679 * For a given server folder, get the uri for the first folder. For imap
680 * and pop it's INBOX and it's the very first group for news accounts.
681 */
getFirstFolderURI
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
682 function getFirstFolderURI(msgFolder)
683 {
684 // Sanity check.
685 if (! msgFolder.isServer)
686 return msgFolder.URI;
687
688 try {
689 // Find Inbox for imap and pop
690 if (msgFolder.server.type != "nntp")
691 {
692 var outNumFolders = new Object();
693 var inboxFolder = msgFolder.getFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, 1, outNumFolders);
694 if (inboxFolder)
695 return inboxFolder.URI;
696 else
697 // If inbox does not exist then use the server uri as default.
698 return msgFolder.URI;
699 }
700 else
701 // XXX TODO: For news, we should find the 1st group/folder off the news groups. For now use server uri.
702 return msgFolder.URI;
703 }
704 catch (ex) {
705 dump(ex + "\n");
706 }
707 return msgFolder.URI;
708 }
709
GetPromptService
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
710 function GetPromptService()
711 {
712 try {
713 return Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
714 .getService(Components.interfaces.nsIPromptService);
715 }
716 catch (e) {
717 return null;
718 }
719 }