!import
1 /* -*- Mode: Java; 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 * Paul Hangas <hangas@netscape.com>
25 * Alec Flett <alecf@netscape.com>
26 * Seth Spitzer <sspitzer@netscape.com>
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * either of the GNU General Public License Version 2 or later (the "GPL"),
30 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
39 *
40 * ***** END LICENSE BLOCK ***** */
41
42 var addressbook = 0;
43 var composeWindow = 0;
44 var msgCompFields = 0;
45 var editCardCallback = 0;
46
47 var gPromptService = GetPromptService();
48
49 var gSearchInput;
50 var gSearchTimer = null;
51 var gQueryURIFormat = null;
52
53 // localization strings
54 var prefixTo;
55 var prefixCc;
56 var prefixBcc;
57
58 var gToButton;
59 var gCcButton;
60 var gBccButton;
61
62 var gActivatedButton;
63
64 var gDragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService();
65 gDragService = gDragService.QueryInterface(Components.interfaces.nsIDragService);
66
67 var gSelectAddressesAbViewListener = {
onSelectionChanged
68 onSelectionChanged: function() {
69 ResultsPaneSelectionChanged();
70 },
onCountChanged
71 onCountChanged: function(total) {
72 // do nothing
73 }
74 };
75
GetAbViewListener
76 function GetAbViewListener()
77 {
78 return gSelectAddressesAbViewListener;
79 }
80
OnLoadSelectAddress
81 function OnLoadSelectAddress()
82 {
83 InitCommonJS();
84
85 prefixTo = gAddressBookBundle.getString("prefixTo") + ": ";
86 prefixCc = gAddressBookBundle.getString("prefixCc") + ": ";
87 prefixBcc = gAddressBookBundle.getString("prefixBcc") + ": ";
88
89 UpgradeAddressBookResultsPaneUI("mailnews.ui.select_addresses_results.version");
90
91 var toAddress="", ccAddress="", bccAddress="";
92
93 doSetOKCancel(SelectAddressOKButton, 0);
94
95 // look in arguments[0] for parameters
96 if (window.arguments && window.arguments[0])
97 {
98 // keep parameters in global for later
99 if ( window.arguments[0].composeWindow )
100 top.composeWindow = window.arguments[0].composeWindow;
101 if ( window.arguments[0].msgCompFields )
102 top.msgCompFields = window.arguments[0].msgCompFields;
103 if ( window.arguments[0].toAddress )
104 toAddress = window.arguments[0].toAddress;
105 if ( window.arguments[0].ccAddress )
106 ccAddress = window.arguments[0].ccAddress;
107 if ( window.arguments[0].bccAddress )
108 bccAddress = window.arguments[0].bccAddress;
109
110 // put the addresses into the bucket
111 AddAddressFromComposeWindow(toAddress, prefixTo);
112 AddAddressFromComposeWindow(ccAddress, prefixCc);
113 AddAddressFromComposeWindow(bccAddress, prefixBcc);
114 }
115
116 gSearchInput = document.getElementById("searchInput");
117 SearchInputChanged();
118
119 SelectFirstAddressBookMenulist();
120
121 DialogBucketPaneSelectionChanged();
122
123 var workPhoneCol = document.getElementById("WorkPhone");
124 workPhoneCol.setAttribute("hidden", "true");
125
126 var companyCol = document.getElementById("Company");
127 companyCol.setAttribute("hidden", "true");
128
129 gToButton = document.getElementById("toButton");
130 gCcButton = document.getElementById("ccButton");
131 gBccButton = document.getElementById("bccButton");
132
133 var abResultsTree = document.getElementById("abResultsTree");
134 abResultsTree.focus();
135
136 gActivatedButton = gToButton;
137
138 document.documentElement.addEventListener("keypress", OnReturnHit, true);
139 }
140
OnUnloadSelectAddress
141 function OnUnloadSelectAddress()
142 {
143 CloseAbView();
144 }
145
AddAddressFromComposeWindow
146 function AddAddressFromComposeWindow(addresses, prefix)
147 {
148 if ( addresses )
149 {
150 var emails = {};
151 var names = {};
152 var fullNames = {};
153 var numAddresses = gHeaderParser.parseHeadersWithArray(addresses, emails, names, fullNames);
154
155 for ( var index = 0; index < numAddresses; index++ )
156 {
157 AddAddressIntoBucket(prefix, fullNames.value[index], emails.value[index]);
158 }
159 }
160 }
161
SelectAddressOKButton
162 function SelectAddressOKButton()
163 {
164 // Empty email checks are now done in AddAddressIntoBucket below.
165 var body = document.getElementById('bucketBody');
166 var item, row, cell, prefix, address, email;
167 var toAddress="", ccAddress="", bccAddress="", emptyEmail="";
168
169 for ( var index = 0; index < body.childNodes.length; index++ )
170 {
171 item = body.childNodes[index];
172 if ( item.childNodes && item.childNodes.length )
173 {
174 row = item.childNodes[0];
175 if ( row.childNodes && row.childNodes.length )
176 {
177 cell = row.childNodes[0];
178 prefix = cell.getAttribute('prefix');
179 address = cell.getAttribute('address');
180 email = cell.getAttribute('email');
181 if ( prefix )
182 {
183 switch ( prefix )
184 {
185 case prefixTo:
186 if ( toAddress )
187 toAddress += ", ";
188 toAddress += address;
189 break;
190 case prefixCc:
191 if ( ccAddress )
192 ccAddress += ", ";
193 ccAddress += address;
194 break;
195 case prefixBcc:
196 if ( bccAddress )
197 bccAddress += ", ";
198 bccAddress += address;
199 break;
200 }
201 }
202 }
203 }
204 }
205 // reset the UI in compose window
206 msgCompFields.to = toAddress;
207 msgCompFields.cc = ccAddress;
208 msgCompFields.bcc = bccAddress;
209 top.composeWindow.CompFields2Recipients(top.msgCompFields);
210
211 return true;
212 }
213
SelectAddressToButton
214 function SelectAddressToButton()
215 {
216 AddSelectedAddressesIntoBucket(prefixTo);
217 gActivatedButton = gToButton;
218 }
219
SelectAddressCcButton
220 function SelectAddressCcButton()
221 {
222 AddSelectedAddressesIntoBucket(prefixCc);
223 gActivatedButton = gCcButton;
224 }
225
SelectAddressBccButton
226 function SelectAddressBccButton()
227 {
228 AddSelectedAddressesIntoBucket(prefixBcc);
229 gActivatedButton = gBccButton;
230 }
231
AddSelectedAddressesIntoBucket
232 function AddSelectedAddressesIntoBucket(prefix)
233 {
234 var cards = GetSelectedAbCards();
235 var count = cards.length;
236
237 for (var i = 0; i < count; i++) {
238 AddCardIntoBucket(prefix, cards[i]);
239 }
240 }
241
AddCardIntoBucket
242 function AddCardIntoBucket(prefix, card)
243 {
244 var address = GenerateAddressFromCard(card);
245 if (card.isMailList) {
246 AddAddressIntoBucket(prefix, address, card.displayName);
247 }
248 else {
249 AddAddressIntoBucket(prefix, address, card.primaryEmail);
250 }
251 }
252
AddAddressIntoBucket
253 function AddAddressIntoBucket(prefix, address, email)
254 {
255 if (email == "")
256 {
257 if (gPromptService)
258 gPromptService.alert(window,
259 gAddressBookBundle.getString("emptyEmailAddCardTitle"),
260 gAddressBookBundle.getString("emptyEmailAddCard"));
261 }
262 else
263 {
264 var body = document.getElementById("bucketBody");
265
266 var item = document.createElement('treeitem');
267 var row = document.createElement('treerow');
268 var cell = document.createElement('treecell');
269 cell.setAttribute('label', prefix + address);
270 cell.setAttribute('prefix', prefix);
271 cell.setAttribute('address', address);
272 cell.setAttribute('email', email);
273
274 row.appendChild(cell);
275 item.appendChild(row);
276 body.appendChild(item);
277 }
278 }
279
RemoveSelectedFromBucket
280 function RemoveSelectedFromBucket()
281 {
282 var bucketTree = document.getElementById("addressBucket");
283 if ( bucketTree )
284 {
285 var body = document.getElementById("bucketBody");
286 var selection = bucketTree.view.selection;
287 var rangeCount = selection.getRangeCount();
288
289 for (var i = rangeCount-1; i >= 0; --i)
290 {
291 var start = {}, end = {};
292 selection.getRangeAt(i,start,end);
293 for (var j = end.value; j >= start.value; --j)
294 {
295 var item = bucketTree.contentView.getItemAtIndex(j);
296 body.removeChild(item);
297 }
298 }
299 }
300 }
301
302 /* Function: ResultsPaneSelectionChanged()
303 * Callers : OnLoadSelectAddress(), abCommon.js:ResultsPaneSelectionChanged()
304 * -------------------------------------------------------------------------
305 * This function is used to grab the selection state of the results tree to maintain
306 * the appropriate enabled/disabled states of the "Edit", "To:", "CC:", and "Bcc:" buttons.
307 * If an entry is selected in the results Tree, then the "disabled" attribute is removed.
308 * Otherwise, if nothing is selected, "disabled" is set to true.
309 */
310
ResultsPaneSelectionChanged
311 function ResultsPaneSelectionChanged()
312 {;
313 var editButton = document.getElementById("edit");
314 var toButton = document.getElementById("toButton");
315 var ccButton = document.getElementById("ccButton");
316 var bccButton = document.getElementById("bccButton");
317
318 var numSelected = GetNumSelectedCards();
319 if (numSelected > 0)
320 {
321 if (numSelected == 1)
322 editButton.removeAttribute("disabled");
323 else
324 editButton.setAttribute("disabled", "true");
325
326 toButton.removeAttribute("disabled");
327 ccButton.removeAttribute("disabled");
328 bccButton.removeAttribute("disabled");
329 }
330 else
331 {
332 editButton.setAttribute("disabled", "true");
333 toButton.setAttribute("disabled", "true");
334 ccButton.setAttribute("disabled", "true");
335 bccButton.setAttribute("disabled", "true");
336 }
337 }
338
339 /* Function: DialogBucketPaneSelectionChanged()
340 * Callers : OnLoadSelectAddress(), abSelectAddressesDialog.xul:id="addressBucket"
341 * -------------------------------------------------------------------------------
342 * This function is used to grab the selection state of the bucket tree to maintain
343 * the appropriate enabled/disabled states of the "Remove" button.
344 * If an entry is selected in the bucket Tree, then the "disabled" attribute is removed.
345 * Otherwise, if nothing is selected, "disabled" is set to true.
346 */
347
DialogBucketPaneSelectionChanged
348 function DialogBucketPaneSelectionChanged()
349 {
350 var bucketTree = document.getElementById("addressBucket");
351 var removeButton = document.getElementById("remove");
352
353 removeButton.disabled = bucketTree.view.selection.count == 0;
354 }
355
AbResultsPaneDoubleClick
356 function AbResultsPaneDoubleClick(card)
357 {
358 AddCardIntoBucket(prefixTo, card);
359 }
360
OnClickedCard
361 function OnClickedCard(card)
362 {
363 // in the select address dialog, do nothing on click
364 }
365
UpdateCardView
366 function UpdateCardView()
367 {
368 // in the select address dialog, do nothing
369 }
370
DropRecipient
371 function DropRecipient(address)
372 {
373 AddAddressIntoBucket(prefixTo, address, address);
374 }
375
OnReturnHit
376 function OnReturnHit(event)
377 {
378 if (event.keyCode == 13) {
379 var focusedElement = document.commandDispatcher.focusedElement;
380 if (focusedElement && (focusedElement.id == "addressBucket"))
381 return;
382 event.stopPropagation();
383 if (focusedElement && (focusedElement.id == "abResultsTree"))
384 gActivatedButton.doCommand();
385 }
386 }
387
388
onEnterInSearchBar
389 function onEnterInSearchBar()
390 {
391 var selectedNode = abList.selectedItem;
392
393 if (!selectedNode)
394 return;
395
396 if (!gQueryURIFormat) {
397 gQueryURIFormat = gPrefs.getComplexValue("mail.addr_book.quicksearchquery.format",
398 Components.interfaces.nsIPrefLocalizedString).data;
399 }
400
401 var searchURI = selectedNode.getAttribute("id");
402
403 if (gSearchInput.value != "") {
404 searchURI += gQueryURIFormat.replace(/@V/g, encodeURIComponent(gSearchInput.value));
405 }
406
407 SetAbView(searchURI, true);
408
409 SelectFirstCard();
410 }
411
412 function SelectFirstAddressBookMenulist()
413 {
414 ChangeDirectoryByURI(abList.selectedItem.id);
415 return;
416 }
417
418 function DirPaneSelectionChangeMenulist()
419 {
420 if (abList && abList.selectedItem) {
421 if (gSearchInput.value && (gSearchInput.value != ""))
422 onEnterInSearchBar();
423 else
424 ChangeDirectoryByURI(abList.selectedItem.id);
425 }
426 }
427
GetPromptService
428 function GetPromptService()
429 {
430 try {
431 return Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
432 .getService(Components.interfaces.nsIPromptService);
433 }
434 catch (e) {
435 return null;
436 }
437 }