playQueue.js
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2011 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
30 if (typeof(Cc) == "undefined")
31  var Cc = Components.classes;
32 if (typeof(Ci) == "undefined")
33  var Ci = Components.interfaces;
34 if (typeof(Cr) == "undefined")
35  var Cr = Components.results;
36 if (typeof(Cu) == "undefined")
37  var Cu = Components.utils;
38 
39 Cu.import("resource://app/jsmodules/DebugUtils.jsm");
40 Cu.import("resource://app/jsmodules/kPlaylistCommands.jsm");
41 Cu.import("resource://app/jsmodules/PlayQueueUtils.jsm");
42 Cu.import("resource://app/jsmodules/SBDataRemoteUtils.jsm");
43 Cu.import("resource://app/jsmodules/sbLibraryUtils.jsm");
44 
45 var playQueue = {
46 
47  _LOG: DebugUtils.generateLogFunction("sbPlayQueue", 5),
48 
52  onLoad: function playQueue_onLoad() {
53  this._LOG(arguments.callee.name);
54 
55  this._playlist = document.getElementById("playqueue-playlist");
56  this._playlistBox = document.getElementById("playqueue-playlist-box");
57  this._innerMessageBox =
58  document.getElementById("playqueue-message-layer-inner-box");
59  this._messageLayer =
60  document.getElementById("playqueue-message-layer-outer-box");
61  this._inProgressLayer =
62  document.getElementById("playqueue-in-progress-layer-outer-box");
63  this._innerInProgressBox =
64  document.getElementById("playqueue-in-progress-layer-inner-box");
65 
66  var playQueueService = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
67  .getService(Ci.sbIPlayQueueService);
68 
69  // Show the empty queue messaging if the queue is empty
70  if (playQueueService.mediaList.isEmpty) {
71  this._showEmptyQueueLayer();
72  } else {
73  this._hideEmptyQueueLayer();
74  }
75 
76  // Listen to underlying medialist to enable/disable empty queue messaging
77  var self = this;
78  this._listListener = {
79  onItemAdded: function(aList, aItem, aIndex) {
80  if (self._listEmpty) {
81  self._hideEmptyQueueLayer();
82  }
83  },
84  onAfterItemRemoved: function(aList, aItem, aIndex) {
85  if (aList.isEmpty) {
86  self._showEmptyQueueLayer();
87  }
88  },
89  onListCleared: function(aList) {
90  self._showEmptyQueueLayer();
91  }
92  };
93 
94  playQueueService.mediaList.addListener(this._listListener,
95  false,
96  Ci.sbIMediaList.LISTENER_FLAGS_ITEMADDED |
97  Ci.sbIMediaList.LISTENER_FLAGS_AFTERITEMREMOVED |
98  Ci.sbIMediaList.LISTENER_FLAGS_LISTCLEARED);
99 
100  // Listen to the queue service index updates, for auto-scroll
101  this._playQueueServiceListener = {
102  onIndexUpdated: function(aToIndex) {
103  PlayQueueUtils.view.treeView.selection.tree.ensureRowIsVisible(aToIndex);
104  },
105 
106  onQueueOperationStarted: function() {
107  self._playlistBox.setAttribute("disabled", "true");
108  self._messageLayer.setAttribute("hidden", "true");
109  self._inProgressLayer.removeAttribute("hidden");
110  },
111 
112  onQueueOperationCompleted: function() {
113  self._playlistBox.removeAttribute("disabled");
114  self._messageLayer.setAttribute("hidden", "true");
115  self._inProgressLayer.setAttribute("hidden", "true");
116  }
117  };
118 
119  playQueueService.addListener(this._playQueueServiceListener);
120 
121  // Attach our listener to the ShowCurrentTrack event issued by the
122  // faceplate. We're in a display pane, so we need to get the main window.
123  var sbWindow = Cc["@mozilla.org/appshell/window-mediator;1"]
124  .getService(Ci.nsIWindowMediator)
125  .getMostRecentWindow("Songbird:Main").window;
126  sbWindow.addEventListener("ShowCurrentTrack", this.onShowCurrentTrack, true);
127 
128  // Bind the playlist to a a view.
129  this._playlist.bind(PlayQueueUtils.view);
130 
131  var mediacoreManager = Cc["@songbirdnest.com/Songbird/Mediacore/Manager;1"]
132  .getService(Ci.sbIMediacoreManager);
133  // Disable the shuffle button when playing from the queue.
134  this._remoteShuffleDisabled =
135  SB_NewDataRemote( "playlist.shuffle.disabled", null );
136 
137  this._mediacoreListener = {
138  onMediacoreEvent: function (ev) {
139  if (ev.type == Ci.sbIMediacoreEvent.VIEW_CHANGE &&
140  mediacoreManager.sequencer.view == PlayQueueUtils.view) {
141  // we're entering the view, disable shuffle
142  mediacoreManager.sequencer.mode =
143  Ci.sbIMediacoreSequencer.MODE_FORWARD;
144  self._remoteShuffleDisabled.boolValue = true;
145  }
146  }
147  };
148 
149  mediacoreManager.addListener(this._mediacoreListener);
150  },
151 
155  onUnload: function playQueue_onUnload() {
156  this._LOG(arguments.callee.name);
157 
158  var playQueueService = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
159  .getService(Ci.sbIPlayQueueService);
160 
161  if (this._listListener) {
162  playQueueService.mediaList.removeListener(this._listListener);
163  this._listListener = null;
164  }
165  if (this._playQueueServiceListener) {
166  playQueueService.removeListener(this._playQueueServiceListener);
167  this._playQueueServiceListener = null;
168  }
169  if (this._playlist) {
170  this._playlist.destroy();
171  this._playlist = null;
172  }
173 
174  // Remove the ShowCurrentTrack event listener.
175  var sbWindow = Cc["@mozilla.org/appshell/window-mediator;1"]
176  .getService(Ci.nsIWindowMediator)
177  .getMostRecentWindow("Songbird:Main").window;
178  if (sbWindow)
179  sbWindow.removeEventListener("ShowCurrentTrack",
180  this.onShowCurrentTrack,
181  true);
182 
183  if (this._mediacoreListener) {
184  var mediacoreManager = Cc["@songbirdnest.com/Songbird/Mediacore/Manager;1"]
185  .getService(Ci.sbIMediacoreManager);
186 
187  mediacoreManager.removeListener(this._mediacoreListener);
188  this._mediacoreListener = null;
189  }
190 
191  if(this._remoteShuffleDisabled) {
192  this._remoteShuffleDisabled.unbind();
193  this._remoteShuffleDisabled = null;
194  }
195  },
196 
201  _showEmptyQueueLayer: function playQueue__showEmptyQueueLayer() {
202  this._LOG(arguments.callee.name);
203  this._playlistBox.setAttribute("disabled", "true");
204  this._listEmpty = true;
205  this._messageLayer.removeAttribute("hidden");
206  this._inProgressLayer.setAttribute("hidden", "true");
207  },
208 
212  _hideEmptyQueueLayer: function playQueue__hideEmptyQueueLayer() {
213  this._LOG(arguments.callee.name);
214  this._playlistBox.removeAttribute("disabled");
215  this._messageLayer.setAttribute("hidden", "true");
216  this._inProgressLayer.setAttribute("hidden", "true");
217  this._listEmpty = false;
218  },
219 
228  onEmptyQueueDragEnter:
229  function playQueue_onEmptyQueueDragEnter(aEvent) {
230 
231  this._LOG(arguments.callee.name);
232  if (this._playlist._canDrop(aEvent)) {
233  this._playlistBox.removeAttribute("disabled");
234  this._innerMessageBox.setAttribute("hidden", "true");
235  }
236  },
237 
238  /*
239  * xxx slloyd This handler is not hooked up to the box due to Bug 13018. Also
240  * see comments in Bug 21874.
241  *
242  * Event handler for dragexit on the messaging layer. Show the message box and
243  * dim the playlist.
244  */
245  onEmptyQueueDragExit:
246  function playQueue_onEmptyQueueDragExit(aEvent) {
247 
248  this._LOG(arguments.callee.name);
249  this._playlistBox.setAttribute("disabled", "true");
250  this._innerMessageBox.removeAttribute("hidden");
251  },
252 
257  onEmptyQueueDragDrop:
258  function playQueue_onEmptyQueueDragDrop(aEvent) {
259 
260  this._LOG(arguments.callee.name);
261  var dragService = Cc["@mozilla.org/widget/dragservice;1"]
262  .getService(Ci.nsIDragService);
263  var session = dragService.getCurrentSession();
264 
265  // The play queue does not accept all drops, so ensure the drop is permitted
266  // before executing the drop.
267  if (this._playlist._canDrop()) {
268  this._playlist._dropOnTree(this._playlist.mediaListView.length,
269  Ci.sbIMediaListViewTreeViewObserver.DROP_AFTER,
270  session);
271  }
272 
273  // Stop propagation so the default drag and drop handler doesn't try to
274  // handle a drop that we already handled with _dropOnTree
275  aEvent.stopPropagation();
276  },
277 
281  onQueueInProgressDragOver:
282  function playQueue_onQueueInProgressDragOver(aEvent) {
283  this._LOG(arguments.callee.name);
284  aEvent.dataTransfer.effectAllowed = "none";
285  aEvent.stopPropagation();
286  },
287 
292  onShowCurrentTrack:
293  function playQueue_onShowCurrentTrack(aEvent) {
294  var mediacoreManager = Cc['@songbirdnest.com/Songbird/Mediacore/Manager;1']
295  .getService(Ci.sbIMediacoreManager);
296  var item = mediacoreManager.sequencer.currentItem;
297 
298  var playQueueService = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
299  .getService(Ci.sbIPlayQueueService);
300 
301  // The queue has its own library, so items contained in the media list are
302  // unique to the queue.
303  if (playQueueService.mediaList.contains(item)) {
304  PlayQueueUtils.openPlayQueue();
305 
306  var view = mediacoreManager.sequencer.view;
307  var row = mediacoreManager.sequencer.viewPosition;
308  view.selection.selectOnly(row);
309  view.treeView.selection.tree.ensureRowIsVisible(row);
310  aEvent.preventDefault();
311  aEvent.stopPropagation();
312  }
313  }
314 
315 };
const Cu
const Cc
var playQueue
Definition: playQueue.js:45
const SB_NewDataRemote
Lastfm onLoad
Definition: mini.js:36
return null
Definition: FeedWriter.js:1143
return!aWindow arguments!aWindow arguments[0]
oState session
const Cr
const Ci
function onUnload()
onUnload - called when the cover preview window unloads.
Definition: coverPreview.js:36
var PlayQueueUtils