!import
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1 //@line 41 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/mail/components/addrbook/content/abCommon.js"
2
3 var dirTree = 0;
4 var abList = 0;
5 var gAbResultsTree = null;
6 var gAbView = null;
7 var gAddressBookBundle;
8 var gCurDirectory;
9
10 var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
11 var gPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
12 var gHeaderParser = Components.classes["@mozilla.org/messenger/headerparser;1"].getService(Components.interfaces.nsIMsgHeaderParser);
13
14 const kDefaultSortColumn = "GeneratedName";
15 const kDefaultAscending = "ascending";
16 const kDefaultDescending = "descending";
17 const kPersonalAddressbookURI = "moz-abmdbdirectory://abook.mab";
18 const kCollectedAddressbookURI = "moz-abmdbdirectory://history.mab";
19
20 // List/card selections in the results pane.
21 const kNothingSelected = 0;
22 const kListsAndCards = 1;
23 const kMultipleListsOnly = 2;
24 const kSingleListOnly = 3;
25 const kCardsOnly = 4;
26
27 // Controller object for Results Pane
28 var ResultsPaneController =
29 {
supportsCommand
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
30 supportsCommand: function(command)
31 {
32 switch (command) {
33 case "cmd_selectAll":
34 case "cmd_delete":
35 case "button_delete":
36 case "button_edit":
37 case "cmd_printcard":
38 case "cmd_printcardpreview":
39 case "cmd_newlist":
40 return true;
41 default:
42 return false;
43 }
44 },
45
isCommandEnabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
46 isCommandEnabled: function(command)
47 {
48 switch (command) {
49 case "cmd_selectAll":
50 return true;
51
52 case "cmd_delete":
53 case "button_delete":
54 var numSelected;
55 var enabled = false;
56 if (gAbView && gAbView.selection) {
57 if (gAbView.directory)
58 enabled = gAbView.directory.operations & gAbView.directory.opWrite;
59 numSelected = gAbView.selection.count;
60 }
61 else
62 numSelected = 0;
63
64 // fix me, don't update on isCommandEnabled
65 if (command == "cmd_delete") {
66 if (numSelected < 2)
67 goSetMenuValue(command, "valueCard");
68 else
69 goSetMenuValue(command, "valueCards");
70 }
71 return (enabled && (numSelected > 0));
72 case "cmd_printcard":
73 case "cmd_printcardpreview":
74 case "button_edit":
75 return (GetSelectedCardIndex() != -1);
76 case "cmd_newlist":
77 var selectedDir = GetSelectedDirectory();
78 if (selectedDir) {
79 var abDir = GetDirectoryFromURI(selectedDir);
80 if (abDir) {
81 return abDir.supportsMailingLists;
82 }
83 }
84 return false;
85 default:
86 return false;
87 }
88 },
89
doCommand
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
90 doCommand: function(command)
91 {
92 switch (command) {
93 case "cmd_selectAll":
94 if (gAbView)
95 gAbView.selectAll();
96 break;
97 case "cmd_delete":
98 case "button_delete":
99 AbDelete();
100 break;
101 case "button_edit":
102 AbEditSelectedCard();
103 break;
104 case "cmd_printcard":
105 AbPrintCard();
106 break;
107 case "cmd_printcardpreview":
108 AbPrintPreviewCard();
109 break;
110 case "cmd_newlist":
111 AbNewList();
112 break;
113 }
114 },
115
onEvent
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
116 onEvent: function(event)
117 {
118 // on blur events set the menu item texts back to the normal values
119 if (event == "blur")
120 goSetMenuValue("cmd_delete", "valueDefault");
121 }
122 };
123
124
125 // Controller object for Dir Pane
126 var DirPaneController =
127 {
supportsCommand
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
128 supportsCommand: function(command)
129 {
130 switch (command) {
131 case "cmd_selectAll":
132 case "cmd_delete":
133 case "button_delete":
134 case "button_edit":
135 case "cmd_printcard":
136 case "cmd_printcardpreview":
137 case "cmd_newlist":
138 return true;
139 default:
140 return false;
141 }
142 },
143
isCommandEnabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
144 isCommandEnabled: function(command)
145 {
146 var selectedDir;
147
148 switch (command) {
149 case "cmd_selectAll":
150 // the dirTree pane
151 // only handles single selection
152 // so we forward select all to the results pane
153 // but if there is no gAbView
154 // don't bother sending to the results pane
155 return (gAbView != null);
156 case "cmd_delete":
157 case "button_delete":
158 if (command == "cmd_delete")
159 goSetMenuValue(command, "valueAddressBook");
160
161 selectedDir = GetSelectedDirectory();
162
163 if (selectedDir == kPersonalAddressbookURI || selectedDir == kCollectedAddressbookURI)
164 return false;
165
166 if (selectedDir) {
167 // If the selected directory is an ldap directory
168 // and if the prefs for this directory are locked
169 // disable the delete button.
170 var ldapUrlPrefix = "moz-abldapdirectory://";
171 if ((selectedDir.indexOf(ldapUrlPrefix, 0)) == 0)
172 {
173 var disable = false;
174 try {
175 var prefName = selectedDir.substr(ldapUrlPrefix.length);
176 disable = gPrefs.getBoolPref(prefName + ".disable_delete");
177 }
178 catch(ex) {
179 // if this preference is not set its ok.
180 }
181 if (disable)
182 return false;
183 }
184 return true;
185 }
186 else
187 return false;
188 case "cmd_printcard":
189 case "cmd_printcardpreview":
190 return (GetSelectedCardIndex() != -1);
191 case "button_edit":
192 return (GetSelectedDirectory() != null);
193 case "cmd_newlist":
194 selectedDir = GetSelectedDirectory();
195 if (selectedDir) {
196 var abDir = GetDirectoryFromURI(selectedDir);
197 if (abDir) {
198 return abDir.supportsMailingLists;
199 }
200 }
201 return false;
202 default:
203 return false;
204 }
205 },
206
doCommand
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
207 doCommand: function(command)
208 {
209 switch (command) {
210 case "cmd_printcard":
211 case "cmd_printcardpreview":
212 case "cmd_selectAll":
213 SendCommandToResultsPane(command);
214 break;
215 case "cmd_delete":
216 case "button_delete":
217 if (dirTree)
218 AbDeleteSelectedDirectory();
219 break;
220 case "button_edit":
221 AbEditSelectedDirectory();
222 break;
223 case "cmd_newlist":
224 AbNewList();
225 break;
226 }
227 },
228
onEvent
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
229 onEvent: function(event)
230 {
231 // on blur events set the menu item texts back to the normal values
232 if (event == "blur")
233 goSetMenuValue("cmd_delete", "valueDefault");
234 }
235 };
236
SendCommandToResultsPane
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
237 function SendCommandToResultsPane(command)
238 {
239 ResultsPaneController.doCommand(command);
240
241 // if we are sending the command so the results pane
242 // we should focus the results pane
243 gAbResultsTree.focus();
244 }
245
AbNewLDAPDirectory
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
246 function AbNewLDAPDirectory()
247 {
248 window.openDialog("chrome://messenger/content/addressbook/pref-directory-add.xul",
249 "",
250 "chrome,modal=yes,resizable=no,centerscreen",
251 null);
252 }
253
AbNewAddressBook
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
254 function AbNewAddressBook()
255 {
256 window.openDialog(
257 "chrome://messenger/content/addressbook/abAddressBookNameDialog.xul",
258 "", "chrome,modal=yes,resizable=no,centerscreen", null);
259 }
260
AbEditSelectedDirectory
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
261 function AbEditSelectedDirectory()
262 {
263 if (dirTree.view.selection.count == 1) {
264 var selecteduri = GetSelectedDirectory();
265 var directory = GetDirectoryFromURI(selecteduri);
266 if (directory.isMailList) {
267 var dirUri = GetParentDirectoryFromMailingListURI(selecteduri);
268 goEditListDialog(null, selecteduri, UpdateCardView);
269 }
270 else {
271 window.openDialog(directory.propertiesChromeURI,
272 "editDirectory", "chrome,modal=yes,resizable=no",
273 {selectedDirectory: directory});
274 }
275 }
276 }
277
AbDeleteSelectedDirectory
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
278 function AbDeleteSelectedDirectory()
279 {
280 var selectedABURI = GetSelectedDirectory();
281 if (!selectedABURI)
282 return;
283
284 AbDeleteDirectory(selectedABURI);
285 }
286
AbDeleteDirectory
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
287 function AbDeleteDirectory(aURI)
288 {
289 var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
290
291 var directory = GetDirectoryFromURI(aURI);
292 var confirmDeleteMessage;
293 var clearPrefsRequired = false;
294
295 if (directory.isMailList)
296 confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteMailingList");
297 else {
298 // Check if this address book is being used for collection
299 if (gPrefs.getCharPref("mail.collect_addressbook") == aURI &&
300 (gPrefs.getBoolPref("mail.collect_email_address_outgoing") ||
301 gPrefs.getBoolPref("mail.collect_email_address_incoming") ||
302 gPrefs.getBoolPref("mail.collect_email_address_newsgroup"))) {
303 var brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
304
305 confirmDeleteMessage = gAddressBookBundle.getFormattedString("confirmDeleteCollectionAddressbook", [brandShortName]);
306 clearPrefsRequired = true;
307 }
308 else {
309 confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteAddressbook");
310 }
311 }
312
313 if (!promptService.confirm(window,
314 gAddressBookBundle.getString(
315 directory.isMailList ?
316 "confirmDeleteMailingListTitle" :
317 "confirmDeleteAddressbookTitle"),
318 confirmDeleteMessage))
319 return;
320
321 // First clear all the prefs if required
322 if (clearPrefsRequired) {
323 gPrefs.setBoolPref("mail.collect_email_address_outgoing", false);
324 gPrefs.setBoolPref("mail.collect_email_address_incoming", false);
325 gPrefs.setBoolPref("mail.collect_email_address_newsgroup", false);
326
327 // Also reset the displayed value so that we don't get a blank item in the
328 // prefs dialog if it gets enabled.
329 gPrefs.setCharPref("mail.collect_addressbook", kPersonalAddressbookURI);
330 }
331
332 Components.classes["@mozilla.org/abmanager;1"]
333 .getService(Components.interfaces.nsIAbManager)
334 .deleteAddressBook(aURI);
335 }
336
GetParentRow
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
337 function GetParentRow(aTree, aRow)
338 {
339 var row = aRow;
340 var level = aTree.view.getLevel(row);
341 var parentLevel = level;
342 while (parentLevel >= level) {
343 row--;
344 if (row == -1)
345 return row;
346 parentLevel = aTree.view.getLevel(row);
347 }
348 return row;
349 }
350
InitCommonJS
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
351 function InitCommonJS()
352 {
353 dirTree = document.getElementById("dirTree");
354 abList = document.getElementById("addressbookList");
355 gAbResultsTree = document.getElementById("abResultsTree");
356 gAddressBookBundle = document.getElementById("bundle_addressBook");
357 }
358
SetupAbCommandUpdateHandlers
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
359 function SetupAbCommandUpdateHandlers()
360 {
361 // dir pane
362 if (dirTree)
363 dirTree.controllers.appendController(DirPaneController);
364
365 // results pane
366 if (gAbResultsTree)
367 gAbResultsTree.controllers.appendController(ResultsPaneController);
368 }
369
GetSelectedCardTypes
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
370 function GetSelectedCardTypes()
371 {
372 var cards = GetSelectedAbCards();
373 if (!cards)
374 return kNothingSelected; // no view
375
376 var count = cards.length;
377 if (count == 0)
378 return kNothingSelected; // nothing selected
379
380 var mailingListCnt = 0;
381 var cardCnt = 0;
382 for (var i = 0; i < count; i++) {
383 if (cards[i].isMailList)
384 mailingListCnt++;
385 else
386 cardCnt++;
387 }
388 if (mailingListCnt && cardCnt)
389 return kListsAndCards; // lists and cards selected
390 else if (mailingListCnt && !cardCnt) {
391 if (mailingListCnt > 1)
392 return kMultipleListsOnly; // only multiple mailing lists selected
393 else
394 return kSingleListOnly; // only single mailing list
395 }
396 else if (!mailingListCnt && cardCnt)
397 return kCardsOnly; // only card(s) selected
398
399 // Fallback just in case.
400 return kNothingSelected;
401 }
402
AbDelete
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
403 function AbDelete()
404 {
405 var types = GetSelectedCardTypes();
406 if (types == kNothingSelected)
407 return;
408
409 var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
410 // If at least one mailing list is selected then prompt users for deletion.
411 if (types != kCardsOnly)
412 {
413 var confirmDeleteMessage;
414 if (types == kListsAndCards)
415 confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteListsAndCards");
416 else if (types == kMultipleListsOnly)
417 confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteMailingLists");
418 else
419 confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteMailingList");
420 if (!promptService.confirm(window, null, confirmDeleteMessage))
421 return;
422 }
423
424 gAbView.deleteSelectedCards();
425 }
426
AbNewCard
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
427 function AbNewCard()
428 {
429 goNewCardDialog(GetSelectedDirectory());
430 }
431
432 // NOTE, will return -1 if more than one card selected, or no cards selected.
GetSelectedCardIndex
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
433 function GetSelectedCardIndex()
434 {
435 if (!gAbView)
436 return -1;
437
438 var treeSelection = gAbView.selection;
439 if (treeSelection.getRangeCount() == 1) {
440 var start = new Object;
441 var end = new Object;
442 treeSelection.getRangeAt(0,start,end);
443 if (start.value == end.value)
444 return start.value;
445 }
446
447 return -1;
448 }
449
450 // NOTE, returns the card if exactly one card is selected, null otherwise
GetSelectedCard
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
451 function GetSelectedCard()
452 {
453 var index = GetSelectedCardIndex();
454 return (index == -1) ? null : gAbView.getCardFromRow(index);
455 }
456
AbEditSelectedCard
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
457 function AbEditSelectedCard()
458 {
459 AbEditCard(GetSelectedCard());
460 }
461
AbEditCard
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
462 function AbEditCard(card)
463 {
464 // Need a card,
465 // but not allowing AOL special groups to be edited.
466 if (!card)
467 return;
468
469 if (card.isMailList) {
470 goEditListDialog(card, card.mailListURI, UpdateCardView);
471 }
472 else {
473 goEditCardDialog(GetSelectedDirectory(), card, UpdateCardView);
474 }
475 }
476
AbNewMessage
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
477 function AbNewMessage()
478 {
479 var msgComposeType = Components.interfaces.nsIMsgCompType;
480 var msgComposFormat = Components.interfaces.nsIMsgCompFormat;
481 var msgComposeService = Components.classes["@mozilla.org/messengercompose;1"].getService();
482 msgComposeService = msgComposeService.QueryInterface(Components.interfaces.nsIMsgComposeService);
483
484 var params = Components.classes["@mozilla.org/messengercompose/composeparams;1"].createInstance(Components.interfaces.nsIMsgComposeParams);
485 if (params)
486 {
487 params.type = msgComposeType.New;
488 params.format = msgComposFormat.Default;
489 var composeFields = Components.classes["@mozilla.org/messengercompose/composefields;1"].createInstance(Components.interfaces.nsIMsgCompFields);
490 if (composeFields)
491 {
492 if (DirPaneHasFocus())
493 composeFields.to = GetSelectedAddressesFromDirTree();
494 else
495 composeFields.to = GetSelectedAddresses();
496 params.composeFields = composeFields;
497 msgComposeService.OpenComposeWindowWithParams(null, params);
498 }
499 }
500 }
501
GetOneOrMoreCardsSelected
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
502 function GetOneOrMoreCardsSelected()
503 {
504 if (!gAbView)
505 return false;
506
507 return (gAbView.selection.getRangeCount() > 0);
508 }
509
510 // XXX todo
511 // could this be moved into utilityOverlay.js?
goToggleSplitter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
512 function goToggleSplitter( id, elementID )
513 {
514 var splitter = document.getElementById( id );
515 var element = document.getElementById( elementID );
516 if ( splitter )
517 {
518 var attribValue = splitter.getAttribute("state") ;
519 if ( attribValue == "collapsed" )
520 {
521 splitter.setAttribute("state", "open" );
522 if ( element )
523 element.setAttribute("checked","true")
524 }
525 else
526 {
527 splitter.setAttribute("state", "collapsed");
528 if ( element )
529 element.setAttribute("checked","false")
530 }
531 document.persist(id, 'state');
532 document.persist(elementID, 'checked');
533 }
534 }
535
536 // Generate a list of cards from the selected mailing list
537 // and get a comma separated list of card addresses. If the
538 // item selected in the directory pane is not a mailing list,
539 // an empty string is returned.
GetSelectedAddressesFromDirTree
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
540 function GetSelectedAddressesFromDirTree()
541 {
542 var addresses = "";
543
544 if (dirTree.currentIndex >= 0) {
545 var selectedResource = dirTree.builderView.getResourceAtIndex(dirTree.currentIndex);
546 var directory = GetDirectoryFromURI(selectedResource.Value);
547 if (directory.isMailList) {
548 var listCardsCount = directory.addressLists.Count();
549 var cards = new Array(listCardsCount);
550 for (var i = 0; i < listCardsCount; ++i)
551 cards[i] = directory.addressLists.QueryElementAt(
552 i, Components.interfaces.nsIAbCard);
553 addresses = GetAddressesForCards(cards);
554 }
555 }
556 return addresses;
557 }
558
GetSelectedAddresses
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
559 function GetSelectedAddresses()
560 {
561 return GetAddressesForCards(GetSelectedAbCards());
562 }
563
564 // Generate a comma separated list of addresses from a given
565 // set of cards.
GetAddressesForCards
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
566 function GetAddressesForCards(cards)
567 {
568 var addresses = "";
569
570 if (!cards)
571 return addresses;
572
573 var count = cards.length;
574 if (count > 0)
575 addresses += GenerateAddressFromCard(cards[0]);
576
577 for (var i = 1; i < count; i++) {
578 var generatedAddress = GenerateAddressFromCard(cards[i]);
579
580 if (generatedAddress)
581 addresses += "," + generatedAddress;
582 }
583 return addresses;
584 }
585
GetNumSelectedCards
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
586 function GetNumSelectedCards()
587 {
588 try {
589 return gAbView.selection.count;
590 }
591 catch (ex) {
592 }
593
594 // if something went wrong, return 0 for the count.
595 return 0;
596 }
597
598 // XXX todo
599 // an optimization might be to make this return
600 // the selected ranges, which would be faster
601 // when the user does large selections, but for now, let's keep it simple.
GetSelectedRows
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
602 function GetSelectedRows()
603 {
604 var selectedRows = "";
605
606 if (!gAbView)
607 return selectedRows;
608
609 var i,j;
610 var rangeCount = gAbView.selection.getRangeCount();
611 var current = 0;
612
613 for (i=0; i < rangeCount; i++) {
614 var start = new Object;
615 var end = new Object;
616 gAbView.selection.getRangeAt(i,start,end);
617 for (j=start.value;j<=end.value;j++) {
618 if (selectedRows)
619 selectedRows += ",";
620 selectedRows += j;
621 }
622 }
623 return selectedRows;
624 }
625
GetSelectedAbCards
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
626 function GetSelectedAbCards()
627 {
628 var abView = gAbView;
629
630 // if sidebar is open, and addressbook panel is open and focused,
631 // then use the ab view from sidebar (gCurFrame is from sidebarOverlay.js)
632 const abPanelUrl = "chrome://messenger/content/addressbook/addressbook-panel.xul";
633 if (document.getElementById("sidebar-box")) {
634 if (gCurFrame &&
635 gCurFrame.getAttribute("src") == abPanelUrl &&
636 document.commandDispatcher.focusedWindow == gCurFrame.contentDocument.defaultView)
637 {
638 abView = gCurFrame.contentDocument.defaultView.gAbView;
639 }
640 }
641
642 if (!abView)
643 return null;
644
645 var cards = new Array(abView.selection.count);
646 var i,j;
647 var count = abView.selection.getRangeCount();
648
649 var current = 0;
650
651 for (i=0; i < count; i++) {
652 var start = new Object;
653 var end = new Object;
654 abView.selection.getRangeAt(i,start,end);
655 for (j = start.value; j <= end.value; ++j)
656 cards[current++] = abView.getCardFromRow(j);
657 }
658 return cards;
659 }
660
SelectFirstAddressBook
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
661 function SelectFirstAddressBook()
662 {
663 dirTree.view.selection.select(0);
664
665 ChangeDirectoryByURI(GetSelectedDirectory());
666 gAbResultsTree.focus();
667 }
668
SelectFirstCard
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
669 function SelectFirstCard()
670 {
671 if (gAbView && gAbView.selection) {
672 gAbView.selection.select(0);
673 }
674 }
675
DirPaneClick
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
676 function DirPaneClick(event)
677 {
678 // we only care about left button events
679 if (event.button != 0)
680 return;
681
682 // if the user clicks on the header / trecol, do nothing
683 if (event.originalTarget.localName == "treecol") {
684 event.stopPropagation();
685 return;
686 }
687 }
688
DirPaneDoubleClick
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
689 function DirPaneDoubleClick(event)
690 {
691 // we only care about left button events
692 if (event.button != 0)
693 return;
694
695 var row = dirTree.treeBoxObject.getRowAt(event.clientX, event.clientY);
696 if (row == -1 || row > dirTree.view.rowCount-1) {
697 // double clicking on a non valid row should not open the dir properties dialog
698 return;
699 }
700
701 if (dirTree && dirTree.view.selection && dirTree.view.selection.count == 1)
702 AbEditSelectedDirectory();
703 }
704
DirPaneSelectionChange
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
705 function DirPaneSelectionChange()
706 {
707 // clear out the search box when changing folders...
708 onClearSearch();
709 if (dirTree && dirTree.view.selection && dirTree.view.selection.count == 1) {
710 gPreviousDirTreeIndex = dirTree.currentIndex;
711 ChangeDirectoryByURI(GetSelectedDirectory());
712 }
713 goUpdateCommand('cmd_newlist');
714 }
715
GetAbResultsBoxObject
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
716 function GetAbResultsBoxObject()
717 {
718 if (!gAbResultsTree)
719 gAbResultsTree = document.getElementById('abResultsTree');
720
721 return gAbResultsTree.treeBoxObject;
722 }
723
CloseAbView
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
724 function CloseAbView()
725 {
726 var boxObject = GetAbResultsBoxObject();
727 boxObject.view = null;
728
729 if (gAbView) {
730 gAbView.close();
731 gAbView = null;
732 }
733 }
734
SetAbView
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
735 function SetAbView(uri, searchView, sortColumn, sortDirection)
736 {
737 var actualSortColumn;
738
739 // make sure sortColumn and sortDirection have non null values before calling gAbView.init
740 if (!sortColumn)
741 sortColumn = kDefaultSortColumn;
742
743 if (!sortDirection)
744 sortDirection = kDefaultAscending;
745
746 if (gAbView && gCurDirectory == GetSelectedDirectory())
747 {
748 // re-init the view
749 actualSortColumn = gAbView.init(uri, searchView, GetAbViewListener(), sortColumn, sortDirection);
750 }
751 else
752 {
753 CloseAbView();
754
755 gCurDirectory = GetSelectedDirectory();
756 gAbView = Components.classes["@mozilla.org/addressbook/abview;1"].createInstance(Components.interfaces.nsIAbView);
757
758 actualSortColumn = gAbView.init(uri, searchView, GetAbViewListener(), sortColumn, sortDirection);
759 }
760
761 var boxObject = GetAbResultsBoxObject();
762 boxObject.view = gAbView.QueryInterface(Components.interfaces.nsITreeView);
763
764 UpdateSortIndicators(sortColumn, sortDirection);
765
766 return actualSortColumn;
767 }
768
GetAbView
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
769 function GetAbView()
770 {
771 return gAbView;
772 }
773
ChangeDirectoryByURI
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
774 function ChangeDirectoryByURI(uri)
775 {
776 if (!uri)
777 uri = kPersonalAddressbookURI;
778
779 if (gAbView && gAbView.URI == uri)
780 return;
781
782 var sortColumn = gAbResultsTree.getAttribute("sortCol");
783 var sortDirection = document.getElementById(sortColumn).getAttribute("sortDirection");
784
785 var actualSortColumn = SetAbView(uri, false, sortColumn, sortDirection);
786
787 UpdateSortIndicators(actualSortColumn, sortDirection);
788
789 // only select the first card if there is a first card
790 if (gAbView && gAbView.getCardFromRow(0)) {
791 SelectFirstCard();
792 }
793 else {
794 // the selection changes if we were switching directories.
795 ResultsPaneSelectionChanged()
796 }
797 return;
798 }
799
AbSortAscending
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
800 function AbSortAscending()
801 {
802 var sortColumn = gAbResultsTree.getAttribute("sortCol");
803 SortAndUpdateIndicators(sortColumn, kDefaultAscending);
804 }
805
AbSortDescending
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
806 function AbSortDescending()
807 {
808 var sortColumn = gAbResultsTree.getAttribute("sortCol");
809 SortAndUpdateIndicators(sortColumn, kDefaultDescending);
810 }
811
SortResultPane
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
812 function SortResultPane(sortColumn)
813 {
814 var sortDirection = kDefaultAscending;
815
816 if (gAbView) {
817 sortDirection = gAbView.sortDirection;
818 }
819
820 SortAndUpdateIndicators(sortColumn, sortDirection);
821 }
822
SortAndUpdateIndicators
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
823 function SortAndUpdateIndicators(sortColumn, sortDirection)
824 {
825 // XXX todo remove once #116341 is fixed
826 if (!sortColumn)
827 return;
828
829 UpdateSortIndicators(sortColumn, sortDirection);
830
831 if (gAbView)
832 gAbView.sortBy(sortColumn, sortDirection);
833 }
834
UpdateSortIndicators
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
835 function UpdateSortIndicators(colID, sortDirection)
836 {
837 var sortedColumn;
838 // set the sort indicator on the column we are sorted by
839 if (colID) {
840 sortedColumn = document.getElementById(colID);
841 if (sortedColumn) {
842 sortedColumn.setAttribute("sortDirection",sortDirection);
843 gAbResultsTree.setAttribute("sortCol", colID);
844 }
845 }
846
847 // remove the sort indicator from all the columns
848 // except the one we are sorted by
849 var currCol = gAbResultsTree.firstChild.firstChild;
850 while (currCol) {
851 if (currCol != sortedColumn && currCol.localName == "treecol")
852 currCol.removeAttribute("sortDirection");
853 currCol = currCol.nextSibling;
854 }
855 }
856
InvalidateResultsPane
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
857 function InvalidateResultsPane()
858 {
859 if (gAbResultsTree)
860 gAbResultsTree.treeBoxObject.invalidate();
861 }
862
AbNewList
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
863 function AbNewList()
864 {
865 goNewListDialog(GetSelectedDirectory());
866 }
867
goNewListDialog
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
868 function goNewListDialog(selectedAB)
869 {
870 window.openDialog("chrome://messenger/content/addressbook/abMailListDialog.xul",
871 "",
872 "chrome,resizable=no,titlebar,modal,centerscreen",
873 {selectedAB:selectedAB});
874 }
875
goEditListDialog
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
876 function goEditListDialog(abCard, listURI, okCallback)
877 {
878 window.openDialog("chrome://messenger/content/addressbook/abEditListDialog.xul",
879 "",
880 "chrome,resizable=no,titlebar,modal,centerscreen",
881 {abCard:abCard, listURI:listURI, okCallback:okCallback});
882 }
883
goNewCardDialog
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
884 function goNewCardDialog(selectedAB)
885 {
886 window.openDialog("chrome://messenger/content/addressbook/abNewCardDialog.xul",
887 "",
888 "chrome,resizable=no,titlebar,modal,centerscreen",
889 {selectedAB:selectedAB});
890 }
891
goEditCardDialog
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
892 function goEditCardDialog(abURI, card, okCallback)
893 {
894 window.openDialog("chrome://messenger/content/addressbook/abEditCardDialog.xul",
895 "",
896 "chrome,resizable=no,modal,titlebar,centerscreen",
897 {abURI:abURI, card:card, okCallback:okCallback});
898 }
899
900
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
901 function setSortByMenuItemCheckState(id, value)
902 {
903 var menuitem = document.getElementById(id);
904 if (menuitem) {
905 menuitem.setAttribute("checked", value);
906 }
907 }
908
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
909 function InitViewSortByMenu()
910 {
911 var sortColumn = kDefaultSortColumn;
912 var sortDirection = kDefaultAscending;
913
914 if (gAbView) {
915 sortColumn = gAbView.sortColumn;
916 sortDirection = gAbView.sortDirection;
917 }
918
919 // this approach is necessary to support generic columns that get overlayed.
920 var elements = document.getElementsByAttribute("name","sortas");
921 for (var i=0; i<elements.length; i++) {
922 var cmd = elements[i].getAttribute("id");
923 var columnForCmd = cmd.split("cmd_SortBy")[1];
924 setSortByMenuItemCheckState(cmd, (sortColumn == columnForCmd));
925 }
926
927 setSortByMenuItemCheckState("sortAscending", (sortDirection == kDefaultAscending));
928 setSortByMenuItemCheckState("sortDescending", (sortDirection == kDefaultDescending));
929 }
930
GenerateAddressFromCard
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
931 function GenerateAddressFromCard(card)
932 {
933 if (!card)
934 return "";
935
936 var email;
937
938 if (card.isMailList)
939 {
940 var directory = GetDirectoryFromURI(card.mailListURI);
941 email = directory.description || card.displayName;
942 }
943 else
944 email = card.primaryEmail;
945
946 return gHeaderParser.makeFullAddressWString(card.displayName, email);
947 }
948
GetDirectoryFromURI
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
949 function GetDirectoryFromURI(uri)
950 {
951 return rdf.GetResource(uri).QueryInterface(Components.interfaces.nsIAbDirectory);
952 }
953
954 // returns null if abURI is not a mailing list URI
GetParentDirectoryFromMailingListURI
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
955 function GetParentDirectoryFromMailingListURI(abURI)
956 {
957 var abURIArr = abURI.split("/");
958 /*
959 turn turn "moz-abmdbdirectory://abook.mab/MailList6"
960 into ["moz-abmdbdirectory:","","abook.mab","MailList6"]
961 then, turn ["moz-abmdbdirectory:","","abook.mab","MailList6"]
962 into "moz-abmdbdirectory://abook.mab"
963 */
964 if (abURIArr.length == 4 && abURIArr[0] == "moz-abmdbdirectory:" && abURIArr[3] != "") {
965 return abURIArr[0] + "/" + abURIArr[1] + "/" + abURIArr[2];
966 }
967
968 return null;
969 }
970
DirPaneHasFocus
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
971 function DirPaneHasFocus()
972 {
973 // returns true if diectory pane has the focus. Returns false, otherwise.
974 return (top.document.commandDispatcher.focusedElement == dirTree)
975 }
976
GetSelectedDirectory
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
977 function GetSelectedDirectory()
978 {
979 if (abList)
980 return abList.selectedItem.id;
981 else {
982 if (dirTree.currentIndex < 0)
983 return null;
984 var selected = dirTree.builderView.getResourceAtIndex(dirTree.currentIndex)
985 return selected.Value;
986 }
987 }
988
onAbSearchKeyPress
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
989 function onAbSearchKeyPress(event)
990 {
991 // 13 == return
992 if (event && event.keyCode == 13)
993 onAbSearchInput(true);
994 }
995
onAbSearchInput
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
996 function onAbSearchInput(returnKeyHit)
997 {
998 if (gSearchInput.showingSearchCriteria && !(returnKeyHit && gSearchInput.value == ""))
999 return;
1000
1001 SearchInputChanged();
1002
1003 if (gSearchTimer) {
1004 clearTimeout(gSearchTimer);
1005 gSearchTimer = null;
1006 }
1007
1008 if (returnKeyHit) {
1009 gSearchInput.select();
1010 onEnterInSearchBar();
1011 }
1012 else {
1013 gSearchTimer = setTimeout("onEnterInSearchBar();", 800);
1014 }
1015 }
1016
SearchInputChanged
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1017 function SearchInputChanged()
1018 {
1019 var clearButton = document.getElementById("clear");
1020 if (clearButton) {
1021 if (gSearchInput.value && (gSearchInput.value != ""))
1022 clearButton.removeAttribute("disabled");
1023 else
1024 clearButton.setAttribute("disabled", "true");
1025 }
1026 }
1027
onAbClearSearch
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1028 function onAbClearSearch()
1029 {
1030 if (gSearchInput)
1031 gSearchInput.value =""; //on input does not get fired for some reason
1032 onAbSearchInput(true);
1033 }
1034
AbSwapFirstNameLastName
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1035 function AbSwapFirstNameLastName()
1036 {
1037 if (gAbView)
1038 gAbView.swapFirstNameLastName();
1039 }
1040
1041
onSearchInputFocus
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1042 function onSearchInputFocus(event)
1043 {
1044 // search bar has focus, ...clear the showing search criteria flag
1045 if (gSearchInput.showingSearchCriteria)
1046 {
1047 gSearchInput.value = "";
1048 gSearchInput.showingSearchCriteria = false;
1049 }
1050
1051 gSearchInput.select();
1052 }
1053
1054 // sets focus into the quick search box
QuickSearchFocus
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1055 function QuickSearchFocus()
1056 {
1057 gSearchInput.focus();
1058 }
1059
onSearchInputBlur
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1060 function onSearchInputBlur(event)
1061 {
1062 // if (gQuickSearchFocusEl && gQuickSearchFocusEl.id == 'searchInput') // ignore the blur if we are in the middle of processing the clear button
1063 // return;
1064
1065 if (!gSearchInput.value)
1066 gSearchInput.showingSearchCriteria = true;
1067
1068 if (gSearchInput.showingSearchCriteria)
1069 gSearchInput.setSearchCriteriaText();
1070 }
1071
1072 var gQuickSearchFocusEl = null;
1073
onClearSearch
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1074 function onClearSearch()
1075 {
1076 if (gSearchInput && !gSearchInput.showingSearchCriteria) // ignore the text box value if it's just showing the search criteria string
1077 {
1078 onAbClearSearch();
1079 // this needs to be on a timer otherwise we end up messing up the focus while the Search("") is still happening
1080 setTimeout("restoreSearchFocusAfterClear();", 0);
1081 }
1082 }
1083
restoreSearchFocusAfterClear
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1084 function restoreSearchFocusAfterClear()
1085 {
1086 // gQuickSearchFocusEl.focus();
1087 gSearchInput.clearButtonHidden = 'true';
1088 gQuickSearchFocusEl = null;
1089 }
1090
1091 var gIsOffline;
1092 var gSessionAdded;
1093 var gCurrentAutocompleteDirectory;
1094 var gAutocompleteSession;
1095 var gSetupLdapAutocomplete;
1096 var gLDAPSession;
1097
setupLdapAutocompleteSession
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1098 function setupLdapAutocompleteSession()
1099 {
1100 var autocompleteLdap = false;
1101 var autocompleteDirectory = null;
1102 var prevAutocompleteDirectory = gCurrentAutocompleteDirectory;
1103 var i;
1104
1105 autocompleteLdap = gPrefs.getBoolPref("ldap_2.autoComplete.useDirectory");
1106 if (autocompleteLdap)
1107 autocompleteDirectory = gPrefs.getCharPref(
1108 "ldap_2.autoComplete.directoryServer");
1109
1110
1111 // use a temporary to do the setup so that we don't overwrite the
1112 // global, then have some problem and throw an exception, and leave the
1113 // global with a partially setup session. we'll assign the temp
1114 // into the global after we're done setting up the session
1115 //
1116 var LDAPSession;
1117 if (gLDAPSession) {
1118 LDAPSession = gLDAPSession;
1119 } else {
1120 LDAPSession = Components.classes[
1121 "@mozilla.org/autocompleteSession;1?type=ldap"].createInstance()
1122 .QueryInterface(Components.interfaces.nsILDAPAutoCompleteSession);
1123 }
1124
1125 if (autocompleteDirectory && !gIsOffline) {
1126 // the compose window code adds an observer on the directory server
1127 // prefs, but I don't think we need this here.
1128 gCurrentAutocompleteDirectory = autocompleteDirectory;
1129
1130 // fill in the session params if there is a session
1131 //
1132 if (LDAPSession) {
1133 var serverURL = Components.classes[
1134 "@mozilla.org/network/ldap-url;1"].
1135 createInstance().QueryInterface(
1136 Components.interfaces.nsILDAPURL);
1137
1138 try {
1139 serverURL.spec = gPrefs.getComplexValue(autocompleteDirectory +".uri",
1140 Components.interfaces.nsISupportsString).data;
1141 } catch (ex) {
1142 dump("ERROR: " + ex + "\n");
1143 }
1144 LDAPSession.serverURL = serverURL;
1145
1146 // get the login to authenticate as, if there is one
1147 //
1148 var login = "";
1149 try {
1150 login = gPrefs.getComplexValue(
1151 autocompleteDirectory + ".auth.dn",
1152 Components.interfaces.nsISupportsString).data;
1153 } catch (ex) {
1154 // if we don't have this pref, no big deal
1155 }
1156
1157 // don't search on non-CJK strings shorter than this
1158 //
1159 try {
1160 LDAPSession.minStringLength = gPrefs.getIntPref(
1161 autocompleteDirectory + ".autoComplete.minStringLength");
1162 } catch (ex) {
1163 // if this pref isn't there, no big deal. just let
1164 // nsLDAPAutoCompleteSession use its default.
1165 }
1166
1167 // don't search on CJK strings shorter than this
1168 //
1169 try {
1170 LDAPSession.cjkMinStringLength = gPrefs.getIntPref(
1171 autocompleteDirectory + ".autoComplete.cjkMinStringLength");
1172 } catch (ex) {
1173 // if this pref isn't there, no big deal. just let
1174 // nsLDAPAutoCompleteSession use its default.
1175 }
1176
1177 // we don't try/catch here, because if this fails, we're outta luck
1178 //
1179 var ldapFormatter = Components.classes[
1180 "@mozilla.org/ldap-autocomplete-formatter;1?type=addrbook"]
1181 .createInstance().QueryInterface(
1182 Components.interfaces.nsIAbLDAPAutoCompFormatter);
1183
1184 // override autocomplete name format?
1185 //
1186 try {
1187 ldapFormatter.nameFormat =
1188 gPrefs.getComplexValue(autocompleteDirectory +
1189 ".autoComplete.nameFormat",
1190 Components.interfaces.nsISupportsString).data;
1191 } catch (ex) {
1192 // if this pref isn't there, no big deal. just let
1193 // nsAbLDAPAutoCompFormatter use its default.
1194 }
1195
1196 // override autocomplete mail address format?
1197 //
1198 try {
1199 ldapFormatter.addressFormat =
1200 gPrefs.getComplexValue(autocompleteDirectory +
1201 ".autoComplete.addressFormat",
1202 Components.interfaces.nsISupportsString).data;
1203 } catch (ex) {
1204 // if this pref isn't there, no big deal. just let
1205 // nsAbLDAPAutoCompFormatter use its default.
1206 }
1207
1208 try {
1209 // figure out what goes in the comment column, if anything
1210 //
1211 // 0 = none
1212 // 1 = name of addressbook this card came from
1213 // 2 = other per-addressbook format
1214 //
1215 var showComments = 0;
1216 showComments = gPrefs.getIntPref(
1217 "mail.autoComplete.commentColumn");
1218
1219 switch (showComments) {
1220
1221 case 1:
1222 // use the name of this directory
1223 //
1224 ldapFormatter.commentFormat = gPrefs.getComplexValue(
1225 autocompleteDirectory + ".description",
1226 Components.interfaces.nsISupportsString).data;
1227 break;
1228
1229 case 2:
1230 // override ldap-specific autocomplete entry?
1231 //
1232 try {
1233 ldapFormatter.commentFormat =
1234 gPrefs.getComplexValue(autocompleteDirectory +
1235 ".autoComplete.commentFormat",
1236 Components.interfaces.nsISupportsString).data;
1237 } catch (innerException) {
1238 // if nothing has been specified, use the ldap
1239 // organization field
1240 ldapFormatter.commentFormat = "[o]";
1241 }
1242 break;
1243
1244 case 0:
1245 default:
1246 // do nothing
1247 }
1248 } catch (ex) {
1249 // if something went wrong while setting up comments, try and
1250 // proceed anyway
1251 }
1252
1253 // set the session's formatter, which also happens to
1254 // force a call to the formatter's getAttributes() method
1255 // -- which is why this needs to happen after we've set the
1256 // various formats
1257 //
1258 LDAPSession.formatter = ldapFormatter;
1259
1260 // override autocomplete entry formatting?
1261 //
1262 try {
1263 LDAPSession.outputFormat =
1264 gPrefs.getComplexValue(autocompleteDirectory +
1265 ".autoComplete.outputFormat",
1266 Components.interfaces.nsISupportsString).data;
1267
1268 } catch (ex) {
1269 // if this pref isn't there, no big deal. just let
1270 // nsLDAPAutoCompleteSession use its default.
1271 }
1272
1273 // override default search filter template?
1274 //
1275 try {
1276 LDAPSession.filterTemplate = gPrefs.getComplexValue(
1277 autocompleteDirectory + ".autoComplete.filterTemplate",
1278 Components.interfaces.nsISupportsString).data;
1279
1280 } catch (ex) {
1281 // if this pref isn't there, no big deal. just let
1282 // nsLDAPAutoCompleteSession use its default
1283 }
1284
1285 // override default maxHits (currently 100)
1286 //
1287 try {
1288 // XXXdmose should really use .autocomplete.maxHits,
1289 // but there's no UI for that yet
1290 //
1291 LDAPSession.maxHits =
1292 gPrefs.getIntPref(autocompleteDirectory + ".maxHits");
1293 } catch (ex) {
1294 // if this pref isn't there, or is out of range, no big deal.
1295 // just let nsLDAPAutoCompleteSession use its default.
1296 }
1297
1298 if (!gSessionAdded) {
1299 // if we make it here, we know that session initialization has
1300 // succeeded; add the session for all recipients, and
1301 // remember that we've done so
1302 var autoCompleteWidget;
1303 for (i=1; i <= awGetMaxRecipients(); i++)
1304 {
1305 autoCompleteWidget = document.getElementById("addressCol1#" + i);
1306 if (autoCompleteWidget)
1307 {
1308 autoCompleteWidget.addSession(LDAPSession);
1309 // ldap searches don't insert a default entry with the default domain appended to it
1310 // so reduce the minimum results for a popup to 2 in this case.
1311 autoCompleteWidget.minResultsForPopup = 2;
1312
1313 }
1314 }
1315 gSessionAdded = true;
1316 }
1317 }
1318 } else {
1319 if (gCurrentAutocompleteDirectory) {
1320 gCurrentAutocompleteDirectory = null;
1321 }
1322 if (gLDAPSession && gSessionAdded) {
1323 for (i=1; i <= awGetMaxRecipients(); i++)
1324 document.getElementById("addressCol1#" + i).
1325 removeSession(gLDAPSession);
1326 gSessionAdded = false;
1327 }
1328 }
1329
1330 gLDAPSession = LDAPSession;
1331 gSetupLdapAutocomplete = true;
1332 }