deviceVolumeSelector.js
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 :miv */
3 /*
4  *=BEGIN SONGBIRD GPL
5  *
6  * This file is part of the Songbird web player.
7  *
8  * Copyright(c) 2005-2010 POTI, Inc.
9  * http://www.songbirdnest.com
10  *
11  * This file may be licensed under the terms of of the
12  * GNU General Public License Version 2 (the ``GPL'').
13  *
14  * Software distributed under the License is distributed
15  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
16  * express or implied. See the GPL for the specific language
17  * governing rights and limitations.
18  *
19  * You should have received a copy of the GPL along with this
20  * program. If not, go to http://www.gnu.org/licenses/gpl.html
21  * or write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  *=END SONGBIRD GPL
25  */
26 
32 //------------------------------------------------------------------------------
33 //------------------------------------------------------------------------------
34 //
35 // Device volume selector widget.
36 //
37 //------------------------------------------------------------------------------
38 //------------------------------------------------------------------------------
39 
40 //------------------------------------------------------------------------------
41 //
42 // Device volume selector imported services.
43 //
44 //------------------------------------------------------------------------------
45 
46 // Component manager defs.
47 var Cc = Components.classes;
48 var Ci = Components.interfaces;
49 var Cr = Components.results;
50 var Cu = Components.utils;
51 
52 // Songbird imports.
53 Cu.import("resource://app/jsmodules/DOMUtils.jsm");
54 Cu.import("resource://app/jsmodules/StringUtils.jsm");
55 
56 
57 //------------------------------------------------------------------------------
58 //
59 // Device volume selector defs.
60 //
61 //------------------------------------------------------------------------------
62 
63 // XUL XML namespace.
64 var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
65 
66 
67 //------------------------------------------------------------------------------
68 //
69 // Device volume selector services.
70 //
71 //------------------------------------------------------------------------------
72 
74  //
75  // Device volume selector object fields.
76  //
77  // _widget Device volume selector widget.
78  // _device Widget device.
79  // _volumeSelectorDeck Volume selector deck element.
80  //
81 
82  _widget: null,
83  _device: null,
84  _volumeSelectorDeck: null,
85 
86 
94  initialize: function deviceVolumeSelectorSvc_initialize(aWidget) {
95  // Get the device volume selector widget and widget device.
96  this._widget = aWidget;
97  this._device = this._widget.device;
98 
99  // Get the volume selector deck element.
100  this._volumeSelectorDeck = this._getElement("volume_selector_deck");
101 
102  // Listen to device events.
103  var deviceEventTarget =
104  this._device.QueryInterface(Ci.sbIDeviceEventTarget);
105  deviceEventTarget.addEventListener(this);
106 
107  // Update UI.
108  this._update();
109  },
110 
111 
116  finalize: function deviceVolumeSelectorSvc_finalize() {
117  // Stop listening to device events.
118  if (this._device) {
119  var deviceEventTarget =
120  this._device.QueryInterface(Ci.sbIDeviceEventTarget);
121  deviceEventTarget.removeEventListener(this);
122  }
123 
124  // Clear object fields.
125  this._widget = null;
126  this._device = null;
127  this._volumeSelectorDeck = null;
128  },
129 
130 
131  //----------------------------------------------------------------------------
132  //
133  // Device volume selector sbIDeviceEventListener services.
134  //
135  //----------------------------------------------------------------------------
136 
143  onDeviceEvent: function deviceVolumeSelectorSvc_onDeviceEvent(aEvent) {
144  // Dispatch processing of event.
145  switch (aEvent.type)
146  {
147  case Ci.sbIDeviceEvent.EVENT_DEVICE_LIBRARY_ADDED :
148  case Ci.sbIDeviceEvent.EVENT_DEVICE_LIBRARY_REMOVED :
149  case Ci.sbIDeviceEvent.EVENT_DEVICE_DEFAULT_LIBRARY_CHANGED :
150  this._update();
151  break;
152 
153  default :
154  break;
155  }
156  },
157 
158 
159  //----------------------------------------------------------------------------
160  //
161  // Internal volume selector sbIDeviceEventListener services.
162  //
163  //----------------------------------------------------------------------------
164 
169  _update: function deviceVolumeSelectorSvc__update() {
170  // Dispatch update depending upon how many device volumes are available.
171  var content = this._device.content;
172  var libraries = content.libraries;
173  if (libraries.length == 0)
174  this._updateNoVolumes();
175  else if (libraries.length == 1)
176  this._updateSingleVolume();
177  else
178  this._updateMultipleVolumes();
179  },
180 
181 
186  _updateNoVolumes: function deviceVolumeSelectorSvc__updateNoVolumes() {
187  // Set the volume selector deck to display a single volume label element.
188  var volumeLabel = this._getElement("volume_label");
189  this._volumeSelectorDeck.selectedPanel = volumeLabel;
190 
191  // Indicate that no device volumes are available.
192  volumeLabel.value = SBString("device.volume_selector.label.no_volumes");
193  },
194 
195 
200  _updateSingleVolume: function deviceVolumeSelectorSvc__updateSingleVolume() {
201  // Set the volume selector deck to display a single volume label element.
202  var volumeLabel = this._getElement("volume_label");
203  this._volumeSelectorDeck.selectedPanel = volumeLabel;
204 
205  // Get the device volume library.
206  var content = this._device.content;
207  var libraries = content.libraries;
208  var library = libraries.queryElementAt(0, Ci.sbIDeviceLibrary);
209 
210  // Set the volume label to the volume library name.
211  volumeLabel.value = library.name;
212  },
213 
214 
219  _updateMultipleVolumes:
220  function deviceVolumeSelectorSvc__updateMultipleVolumes() {
221  // Set the volume selector deck to display a volume selector menu list.
222  var volumeMenuList = this._getElement("volume_menulist");
223  this._volumeSelectorDeck.selectedPanel = volumeMenuList;
224 
225  // Set the selected volume to the device default library volume.
226  var defaultLibrary = this._device.defaultLibrary;
227  if (defaultLibrary)
228  volumeMenuList.value = defaultLibrary.guid;
229  else
230  volumeMenuList.selectedIndex = 0;
231  },
232 
233 
234  //----------------------------------------------------------------------------
235  //
236  // Device volume selector XUL services.
237  //
238  //----------------------------------------------------------------------------
239 
249  _getElement: function deviceVolumeSelectorSvc__getElement(aElementID) {
250  return document.getAnonymousElementByAttribute(this._widget,
251  "sbid",
252  aElementID);
253  }
254 };
255 
256 
257 //------------------------------------------------------------------------------
258 //
259 // Device volume menuitems services.
260 //
261 //------------------------------------------------------------------------------
262 
264  //
265  // Device volume menuitems object fields.
266  //
267  // _widget Device volume menuitems widget.
268  // _device Widget device.
269  // _addedElementList List of UI elements added by this widget.
270  // _addedElementListenerSet Set of listeners added to UI elements.
271  //
272 
273  _widget: null,
274  _device: null,
275  _addedElementList: null,
276  _addedElementListenerSet: null,
277 
278 
286  initialize: function deviceVolumeMenuItemsSvc_initialize(aWidget) {
287  // Do nothing if widget is not yet bound to a device.
288  if (!aWidget.device)
289  return;
290 
291  // Get the device volume menuitems widget and widget device.
292  this._widget = aWidget;
293  this._device = this._widget.device;
294 
295  // Listen to device events.
296  var deviceEventTarget =
297  this._device.QueryInterface(Ci.sbIDeviceEventTarget);
298  deviceEventTarget.addEventListener(this);
299 
300  // Update UI.
301  this._update();
302  },
303 
304 
309  finalize: function deviceVolumeMenuItemsSvc_finalize() {
310  // Stop listening to device events.
311  if (this._device) {
312  var deviceEventTarget =
313  this._device.QueryInterface(Ci.sbIDeviceEventTarget);
314  deviceEventTarget.removeEventListener(this);
315  }
316 
317  // Remove all added elements.
318  this._removeAddedElements();
319 
320  // Clear object fields.
321  this._widget = null;
322  this._device = null;
323  },
324 
325 
326  //----------------------------------------------------------------------------
327  //
328  // Device volume menuitems sbIDeviceEventListener services.
329  //
330  //----------------------------------------------------------------------------
331 
338  onDeviceEvent: function deviceVolumeMenuItemsSvc_onDeviceEvent(aEvent) {
339  // Dispatch processing of event.
340  switch (aEvent.type)
341  {
342  case Ci.sbIDeviceEvent.EVENT_DEVICE_LIBRARY_ADDED :
343  case Ci.sbIDeviceEvent.EVENT_DEVICE_LIBRARY_REMOVED :
344  case Ci.sbIDeviceEvent.EVENT_DEVICE_DEFAULT_LIBRARY_CHANGED :
345  this._update();
346  break;
347 
348  default :
349  break;
350  }
351  },
352 
353 
354  //----------------------------------------------------------------------------
355  //
356  // Internal volume menuitems sbIDeviceEventListener services.
357  //
358  //----------------------------------------------------------------------------
359 
364  _update: function deviceVolumeMenuItemsSvc__update() {
365  // Remove all added elements.
366  this._removeAddedElements();
367 
368  // Get the minimum number of volumes to add any UI elements.
369  var minVolumeCount = 1;
370  if (this._widget.hasAttribute("minvolumes"))
371  minVolumeCount = parseInt(this._widget.getAttribute("minvolumes"));
372 
373  // Get the list of device volume libraries. Don't add any UI elements if
374  // not enough volumes are present.
375  var libraries = this._device.content.libraries;
376  var libraryCount = libraries.length;
377  if (libraryCount < minVolumeCount)
378  return;
379 
380  // Check if the default volume menuitem should be checked.
381  var checkDefault = this._widget.getAttribute("checkdefault") == "true";
382 
383  // Create a list of added elements.
384  this._addedElementList = [];
385  this._addedElementListenerSet = new DOMEventListenerSet();
386 
387  // If specified, add a menu separator before menuitems.
388  if (this._widget.getAttribute("addseparatorbefore") == "true") {
389  var separator = document.createElementNS(XUL_NS, "menuseparator");
390  this._widget.parentNode.insertBefore(separator, this._widget);
391  this._addedElementList.push(separator);
392  }
393 
394  // Add a menu item for each device volume.
395  for (var i = 0; i < libraryCount; i++) {
396  // Get the next volume library.
397  var library = libraries.queryElementAt(i, Ci.sbIDeviceLibrary);
398 
399  // Create a volume menuitem.
400  var menuItem = document.createElementNS(XUL_NS, "menuitem");
401  menuItem.setAttribute("label", library.name);
402  menuItem.setAttribute("value", library.guid);
403 
404  // If specified, check the default volume menuitem.
405  if (checkDefault && (library.guid == this._device.defaultLibrary.guid))
406  menuItem.setAttribute("checked", "true");
407 
408  // Add a command listener to the menuitem.
409  var _this = this;
410  var func = function(aEvent) { return _this._onVolumeChange(aEvent); };
411  this._addedElementListenerSet.add(menuItem, "command", func, false);
412 
413  // Add the volume menuitem.
414  this._widget.parentNode.insertBefore(menuItem, this._widget);
415  this._addedElementList.push(menuItem);
416  }
417 
418  // If specified, add a menu separator after menuitems.
419  if (this._widget.getAttribute("addseparatorafter") == "true") {
420  var separator = document.createElementNS(XUL_NS, "menuseparator");
421  this._widget.parentNode.insertBefore(separator, this._widget);
422  this._addedElementList.push(separator);
423  }
424  },
425 
426 
431  _removeAddedElements:
432  function deviceVolumeMenuItemsSvc__removeAddedElements() {
433  // Remove all added element listeners.
434  if (this._AddedElementListenerSet) {
435  this._addedElementListenerSet.removeAll();
436  this._addedElementListenerSet = null;
437  }
438 
439  // Remove all added elements.
440  if (this._addedElementList) {
441  for (var i = 0; i < this._addedElementList.length; i++) {
442  var element = this._addedElementList[i];
443  if (element.parentNode)
444  element.parentNode.removeChild(element);
445  }
446  this._addedElementList = null;
447  }
448  },
449 
450 
457  _onVolumeChange: function deviceVolumeMenuItemsSvc__onVolumeChange(aEvent) {
458  // Get the selected volume library GUID.
459  var libraryGUID = aEvent.target.value;
460 
461  // Set the device default library to the selected volume library.
462  var content = this._device.content;
463  var libraries = content.libraries;
464  libraryCount = libraries.length;
465  for (var i = 0; i < libraryCount; i++) {
466  // Get the next library.
467  var library = libraries.queryElementAt(i, Ci.sbIDeviceLibrary);
468 
469  // If library is the selected library, set it as the default.
470  if (library.guid == libraryGUID) {
471  this._device.defaultLibrary = library;
472  break;
473  }
474  }
475  }
476 };
477 
var deviceVolumeMenuItemsSvc
function Fx prototype initialize
var deviceVolumeSelectorSvc
var menuItem
Definition: FeedWriter.js:970
function DOMEventListenerSet()
Definition: DOMUtils.jsm:766
function SBString(aKey, aDefault, aStringBundle)
Definition: StringUtils.jsm:93
var _this
return null
Definition: FeedWriter.js:1143
var XUL_NS
_getSelectedPageStyle s i