Merge lp:~linkinpark342/exaile/352683 into lp:exaile/0.3.3
- 352683
- Merge into exaile-0.3.x
Proposed by
Abhishek Mukherjee
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | not available | ||||
Proposed branch: | lp:~linkinpark342/exaile/352683 | ||||
Merge into: | lp:exaile/0.3.3 | ||||
Diff against target: | None lines | ||||
To merge this branch: | bzr merge lp:~linkinpark342/exaile/352683 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
reacocard (community) | Approve | ||
Review via email: mp+5646@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Abhishek Mukherjee (linkinpark342) wrote : | # |
Revision history for this message
reacocard (reacocard) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/glade/main.glade' | |||
2 | --- data/glade/main.glade 2009-03-28 20:56:12 +0000 | |||
3 | +++ data/glade/main.glade 2009-04-13 02:38:36 +0000 | |||
4 | @@ -151,6 +151,23 @@ | |||
5 | 151 | </widget> | 151 | </widget> |
6 | 152 | </child> | 152 | </child> |
7 | 153 | 153 | ||
8 | 154 | <child> | ||
9 | 155 | <widget class="GtkImageMenuItem" id="queue_manager_item"> | ||
10 | 156 | <property name="label" translatable="yes">_Queue Manager</property> | ||
11 | 157 | <property name="visible">True</property> | ||
12 | 158 | <property name="use_underline">True</property> | ||
13 | 159 | <property name="use_stock">False</property> | ||
14 | 160 | <signal name="activate" handler="on_queue_manager_item_activate"/> | ||
15 | 161 | <child internal-child="image"> | ||
16 | 162 | <widget class="GtkImage" id="queue_manager_icon"> | ||
17 | 163 | <property name="visible">True</property> | ||
18 | 164 | <property name="stock">gtk-add</property> | ||
19 | 165 | <property name="icon-size">1</property> | ||
20 | 166 | </widget> | ||
21 | 167 | </child> | ||
22 | 168 | </widget> | ||
23 | 169 | </child> | ||
24 | 170 | |||
25 | 154 | <child> | 171 | <child> |
26 | 155 | <widget class="GtkImageMenuItem" id="plugins1"> | 172 | <widget class="GtkImageMenuItem" id="plugins1"> |
27 | 156 | <property name="visible">True</property> | 173 | <property name="visible">True</property> |
28 | 157 | 174 | ||
29 | === added file 'data/glade/queue_dialog.glade' | |||
30 | --- data/glade/queue_dialog.glade 1970-01-01 00:00:00 +0000 | |||
31 | +++ data/glade/queue_dialog.glade 2009-04-14 17:10:16 +0000 | |||
32 | @@ -0,0 +1,187 @@ | |||
33 | 1 | <?xml version="1.0"?> | ||
34 | 2 | <glade-interface> | ||
35 | 3 | <!-- interface-requires gtk+ 2.16 --> | ||
36 | 4 | <!-- interface-naming-policy project-wide --> | ||
37 | 5 | <widget class="GtkWindow" id="QueueManagerDialog"> | ||
38 | 6 | <property name="width_request">300</property> | ||
39 | 7 | <property name="height_request">400</property> | ||
40 | 8 | <property name="title" translatable="yes">Queue Manager - Exaile</property> | ||
41 | 9 | <child> | ||
42 | 10 | <widget class="GtkVBox" id="vbox"> | ||
43 | 11 | <property name="visible">True</property> | ||
44 | 12 | <property name="orientation">vertical</property> | ||
45 | 13 | <child> | ||
46 | 14 | <widget class="GtkHBox" id="hbox1"> | ||
47 | 15 | <property name="visible">True</property> | ||
48 | 16 | <child> | ||
49 | 17 | <widget class="GtkScrolledWindow" id="scrolledwindow1"> | ||
50 | 18 | <property name="visible">True</property> | ||
51 | 19 | <property name="can_focus">True</property> | ||
52 | 20 | <property name="hscrollbar_policy">automatic</property> | ||
53 | 21 | <property name="vscrollbar_policy">automatic</property> | ||
54 | 22 | <child> | ||
55 | 23 | <widget class="GtkTreeView" id="queue_tree"> | ||
56 | 24 | <property name="visible">True</property> | ||
57 | 25 | <property name="can_focus">True</property> | ||
58 | 26 | </widget> | ||
59 | 27 | </child> | ||
60 | 28 | </widget> | ||
61 | 29 | <packing> | ||
62 | 30 | <property name="padding">5</property> | ||
63 | 31 | <property name="position">0</property> | ||
64 | 32 | </packing> | ||
65 | 33 | </child> | ||
66 | 34 | <child> | ||
67 | 35 | <widget class="GtkVButtonBox" id="vbuttonbox1"> | ||
68 | 36 | <property name="visible">True</property> | ||
69 | 37 | <property name="layout_style">spread</property> | ||
70 | 38 | <child> | ||
71 | 39 | <widget class="GtkButton" id="top_button"> | ||
72 | 40 | <property name="label" translatable="yes">gtk-goto-top</property> | ||
73 | 41 | <property name="visible">True</property> | ||
74 | 42 | <property name="can_focus">True</property> | ||
75 | 43 | <property name="receives_default">True</property> | ||
76 | 44 | <property name="tooltip" translatable="yes">Move song to top in queue</property> | ||
77 | 45 | <property name="use_stock">True</property> | ||
78 | 46 | <signal name="clicked" handler="on_top_button_clicked"/> | ||
79 | 47 | </widget> | ||
80 | 48 | <packing> | ||
81 | 49 | <property name="expand">False</property> | ||
82 | 50 | <property name="fill">False</property> | ||
83 | 51 | <property name="position">0</property> | ||
84 | 52 | </packing> | ||
85 | 53 | </child> | ||
86 | 54 | <child> | ||
87 | 55 | <widget class="GtkButton" id="up_button"> | ||
88 | 56 | <property name="label" translatable="yes">gtk-go-up</property> | ||
89 | 57 | <property name="visible">True</property> | ||
90 | 58 | <property name="can_focus">True</property> | ||
91 | 59 | <property name="receives_default">True</property> | ||
92 | 60 | <property name="tooltip" translatable="yes">Move song up in queue</property> | ||
93 | 61 | <property name="use_stock">True</property> | ||
94 | 62 | <signal name="clicked" handler="on_up_button_clicked"/> | ||
95 | 63 | </widget> | ||
96 | 64 | <packing> | ||
97 | 65 | <property name="expand">False</property> | ||
98 | 66 | <property name="fill">False</property> | ||
99 | 67 | <property name="position">1</property> | ||
100 | 68 | </packing> | ||
101 | 69 | </child> | ||
102 | 70 | <child> | ||
103 | 71 | <widget class="GtkButton" id="remove_button"> | ||
104 | 72 | <property name="label" translatable="yes">gtk-remove</property> | ||
105 | 73 | <property name="visible">True</property> | ||
106 | 74 | <property name="can_focus">True</property> | ||
107 | 75 | <property name="receives_default">True</property> | ||
108 | 76 | <property name="tooltip" translatable="yes">Remove song from queue</property> | ||
109 | 77 | <property name="use_stock">True</property> | ||
110 | 78 | <signal name="clicked" handler="on_remove_button_clicked"/> | ||
111 | 79 | </widget> | ||
112 | 80 | <packing> | ||
113 | 81 | <property name="expand">False</property> | ||
114 | 82 | <property name="fill">False</property> | ||
115 | 83 | <property name="position">2</property> | ||
116 | 84 | </packing> | ||
117 | 85 | </child> | ||
118 | 86 | <child> | ||
119 | 87 | <widget class="GtkButton" id="down_button"> | ||
120 | 88 | <property name="label" translatable="yes">gtk-go-down</property> | ||
121 | 89 | <property name="visible">True</property> | ||
122 | 90 | <property name="can_focus">True</property> | ||
123 | 91 | <property name="receives_default">True</property> | ||
124 | 92 | <property name="tooltip" translatable="yes">Move song down in queue</property> | ||
125 | 93 | <property name="use_stock">True</property> | ||
126 | 94 | <signal name="clicked" handler="on_down_button_clicked"/> | ||
127 | 95 | </widget> | ||
128 | 96 | <packing> | ||
129 | 97 | <property name="expand">False</property> | ||
130 | 98 | <property name="fill">False</property> | ||
131 | 99 | <property name="position">3</property> | ||
132 | 100 | </packing> | ||
133 | 101 | </child> | ||
134 | 102 | <child> | ||
135 | 103 | <widget class="GtkButton" id="bottom_button"> | ||
136 | 104 | <property name="label" translatable="yes">gtk-goto-bottom</property> | ||
137 | 105 | <property name="visible">True</property> | ||
138 | 106 | <property name="can_focus">True</property> | ||
139 | 107 | <property name="receives_default">True</property> | ||
140 | 108 | <property name="tooltip" translatable="yes">Move song to bottom of queue</property> | ||
141 | 109 | <property name="use_stock">True</property> | ||
142 | 110 | <signal name="clicked" handler="on_bottom_button_clicked"/> | ||
143 | 111 | </widget> | ||
144 | 112 | <packing> | ||
145 | 113 | <property name="expand">False</property> | ||
146 | 114 | <property name="fill">False</property> | ||
147 | 115 | <property name="position">4</property> | ||
148 | 116 | </packing> | ||
149 | 117 | </child> | ||
150 | 118 | </widget> | ||
151 | 119 | <packing> | ||
152 | 120 | <property name="expand">False</property> | ||
153 | 121 | <property name="padding">5</property> | ||
154 | 122 | <property name="position">1</property> | ||
155 | 123 | </packing> | ||
156 | 124 | </child> | ||
157 | 125 | </widget> | ||
158 | 126 | <packing> | ||
159 | 127 | <property name="padding">5</property> | ||
160 | 128 | <property name="position">0</property> | ||
161 | 129 | </packing> | ||
162 | 130 | </child> | ||
163 | 131 | <child> | ||
164 | 132 | <widget class="GtkHSeparator" id="hseparator1"> | ||
165 | 133 | <property name="visible">True</property> | ||
166 | 134 | </widget> | ||
167 | 135 | <packing> | ||
168 | 136 | <property name="expand">False</property> | ||
169 | 137 | <property name="padding">5</property> | ||
170 | 138 | <property name="position">1</property> | ||
171 | 139 | </packing> | ||
172 | 140 | </child> | ||
173 | 141 | <child> | ||
174 | 142 | <widget class="GtkHButtonBox" id="button_box"> | ||
175 | 143 | <property name="visible">True</property> | ||
176 | 144 | <property name="spacing">5</property> | ||
177 | 145 | <property name="layout_style">end</property> | ||
178 | 146 | <child> | ||
179 | 147 | <widget class="GtkButton" id="ok_button"> | ||
180 | 148 | <property name="label" translatable="yes">gtk-ok</property> | ||
181 | 149 | <property name="visible">True</property> | ||
182 | 150 | <property name="can_focus">True</property> | ||
183 | 151 | <property name="receives_default">True</property> | ||
184 | 152 | <property name="tooltip" translatable="yes">Close this dialog</property> | ||
185 | 153 | <property name="use_stock">True</property> | ||
186 | 154 | <signal name="clicked" handler="close_dialog"/> | ||
187 | 155 | </widget> | ||
188 | 156 | <packing> | ||
189 | 157 | <property name="expand">False</property> | ||
190 | 158 | <property name="fill">False</property> | ||
191 | 159 | <property name="position">1</property> | ||
192 | 160 | </packing> | ||
193 | 161 | </child> | ||
194 | 162 | <child> | ||
195 | 163 | <widget class="GtkButton" id="remove_all_button"> | ||
196 | 164 | <property name="label" translatable="yes" comments="Remove all from queue">Remove _All</property> | ||
197 | 165 | <property name="visible">True</property> | ||
198 | 166 | <property name="can_focus">True</property> | ||
199 | 167 | <property name="receives_default">True</property> | ||
200 | 168 | <property name="use_underline">True</property> | ||
201 | 169 | <signal name="clicked" handler="on_remove_all_button_clicked"/> | ||
202 | 170 | </widget> | ||
203 | 171 | <packing> | ||
204 | 172 | <property name="expand">False</property> | ||
205 | 173 | <property name="fill">False</property> | ||
206 | 174 | <property name="position">0</property> | ||
207 | 175 | </packing> | ||
208 | 176 | </child> | ||
209 | 177 | </widget> | ||
210 | 178 | <packing> | ||
211 | 179 | <property name="expand">False</property> | ||
212 | 180 | <property name="padding">5</property> | ||
213 | 181 | <property name="position">2</property> | ||
214 | 182 | </packing> | ||
215 | 183 | </child> | ||
216 | 184 | </widget> | ||
217 | 185 | </child> | ||
218 | 186 | </widget> | ||
219 | 187 | </glade-interface> | ||
220 | 0 | 188 | ||
221 | === modified file 'xlgui/__init__.py' | |||
222 | --- xlgui/__init__.py 2009-03-15 04:05:49 +0000 | |||
223 | +++ xlgui/__init__.py 2009-04-13 02:38:36 +0000 | |||
224 | @@ -18,7 +18,7 @@ | |||
225 | 18 | import gtk, gtk.glade, gobject, logging | 18 | import gtk, gtk.glade, gobject, logging |
226 | 19 | from xl import xdg, common, event, metadata | 19 | from xl import xdg, common, event, metadata |
227 | 20 | 20 | ||
229 | 21 | from xlgui import guiutil, prefs, plugins, cover, commondialogs | 21 | from xlgui import guiutil, prefs, plugins, cover, commondialogs, queue |
230 | 22 | 22 | ||
231 | 23 | gtk.window_set_default_icon_from_file(xdg.get_data_path("images/icon.png")) | 23 | gtk.window_set_default_icon_from_file(xdg.get_data_path("images/icon.png")) |
232 | 24 | logger = logging.getLogger(__name__) | 24 | logger = logging.getLogger(__name__) |
233 | @@ -84,6 +84,7 @@ | |||
234 | 84 | 'on_about_item_activate': self.show_about_dialog, | 84 | 'on_about_item_activate': self.show_about_dialog, |
235 | 85 | 'on_scan_collection_item_activate': self.on_rescan_collection, | 85 | 'on_scan_collection_item_activate': self.on_rescan_collection, |
236 | 86 | 'on_collection_manager_item_activate': self.collection_manager, | 86 | 'on_collection_manager_item_activate': self.collection_manager, |
237 | 87 | 'on_queue_manager_item_activate': self.queue_manager, | ||
238 | 87 | 'on_preferences_item_activate': lambda *e: self.show_preferences(), | 88 | 'on_preferences_item_activate': lambda *e: self.show_preferences(), |
239 | 88 | 'on_plugins_item_activate': self.show_plugins, | 89 | 'on_plugins_item_activate': self.show_plugins, |
240 | 89 | 'on_album_art_item_activate': self.show_cover_manager, | 90 | 'on_album_art_item_activate': self.show_cover_manager, |
241 | @@ -199,6 +200,10 @@ | |||
242 | 199 | plugin_page=plugin_page) | 200 | plugin_page=plugin_page) |
243 | 200 | dialog.run() | 201 | dialog.run() |
244 | 201 | 202 | ||
245 | 203 | def queue_manager(self, *e): | ||
246 | 204 | dialog = queue.QueueManager(self.exaile.queue) | ||
247 | 205 | dialog.show() | ||
248 | 206 | |||
249 | 202 | def collection_manager(self, *e): | 207 | def collection_manager(self, *e): |
250 | 203 | """ | 208 | """ |
251 | 204 | Invokes the collection manager dialog | 209 | Invokes the collection manager dialog |
252 | 205 | 210 | ||
253 | === added file 'xlgui/queue.py' | |||
254 | --- xlgui/queue.py 1970-01-01 00:00:00 +0000 | |||
255 | +++ xlgui/queue.py 2009-04-16 20:54:18 +0000 | |||
256 | @@ -0,0 +1,200 @@ | |||
257 | 1 | """ | ||
258 | 2 | Queue manager dialog | ||
259 | 3 | """ | ||
260 | 4 | |||
261 | 5 | from xl import xdg | ||
262 | 6 | from xl.nls import gettext as _ | ||
263 | 7 | from operator import itemgetter | ||
264 | 8 | from copy import copy | ||
265 | 9 | import xl.event | ||
266 | 10 | import os | ||
267 | 11 | import gtk | ||
268 | 12 | import gtk.glade | ||
269 | 13 | import logging | ||
270 | 14 | |||
271 | 15 | LOG = logging.getLogger('exaile.xlgui.queue') | ||
272 | 16 | |||
273 | 17 | class QueueManager(object): | ||
274 | 18 | |||
275 | 19 | """ | ||
276 | 20 | GUI to manage a queue | ||
277 | 21 | """ | ||
278 | 22 | |||
279 | 23 | def __init__(self, queue): | ||
280 | 24 | self._queue = queue | ||
281 | 25 | |||
282 | 26 | self._xml = gtk.glade.XML( | ||
283 | 27 | xdg.get_data_path(os.path.join('glade', 'queue_dialog.glade')), | ||
284 | 28 | 'QueueManagerDialog', 'exaile') | ||
285 | 29 | self._xml.get_widget('remove_all_button').set_image( | ||
286 | 30 | gtk.image_new_from_stock(gtk.STOCK_REMOVE, gtk.ICON_SIZE_BUTTON)) | ||
287 | 31 | |||
288 | 32 | self._dialog = self._xml.get_widget('QueueManagerDialog') | ||
289 | 33 | self._dialog.connect('destroy', self.destroy) | ||
290 | 34 | self._xml.signal_autoconnect({ | ||
291 | 35 | 'close_dialog': self.destroy, | ||
292 | 36 | 'on_top_button_clicked': self.selected_to_top, | ||
293 | 37 | 'on_up_button_clicked': self.selected_up, | ||
294 | 38 | 'on_remove_button_clicked': self.remove_selected, | ||
295 | 39 | 'on_down_button_clicked': self.selected_down, | ||
296 | 40 | 'on_bottom_button_clicked': self.selected_to_bottom, | ||
297 | 41 | 'on_remove_all_button_clicked': self.remove_all, | ||
298 | 42 | }) | ||
299 | 43 | |||
300 | 44 | self.__setup_callbacks() | ||
301 | 45 | |||
302 | 46 | self._model = gtk.ListStore(int, str, object) | ||
303 | 47 | self._queue_view = self._xml.get_widget('queue_tree') | ||
304 | 48 | self._queue_view.set_model(self._model) | ||
305 | 49 | self.__last_tracks = [] | ||
306 | 50 | self.__populate_queue() | ||
307 | 51 | self.__setup_queue() | ||
308 | 52 | |||
309 | 53 | def __setup_callbacks(self): | ||
310 | 54 | for callback in self.__callbacks(): | ||
311 | 55 | xl.event.add_callback(*callback) | ||
312 | 56 | |||
313 | 57 | def __teardown_callbacks(self): | ||
314 | 58 | for callback in self.__callbacks(): | ||
315 | 59 | xl.event.remove_callback(*callback) | ||
316 | 60 | |||
317 | 61 | def __populate_queue_cb(self, *e): | ||
318 | 62 | self.__populate_queue() | ||
319 | 63 | |||
320 | 64 | def __callbacks(self): | ||
321 | 65 | yield (self.__populate_queue_cb, 'playback_start') | ||
322 | 66 | yield (self.__populate_queue_cb, 'tracks_added', self._queue) | ||
323 | 67 | |||
324 | 68 | def __setup_queue(self): | ||
325 | 69 | """Adds columns to _queue_view""" | ||
326 | 70 | renderer = gtk.CellRendererText() | ||
327 | 71 | col = gtk.TreeViewColumn(_('#'), renderer, text=0) | ||
328 | 72 | col.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) | ||
329 | 73 | self._queue_view.append_column(col) | ||
330 | 74 | |||
331 | 75 | renderer = gtk.CellRendererText() | ||
332 | 76 | col = gtk.TreeViewColumn(_('Title'), renderer, text=1) | ||
333 | 77 | col.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) | ||
334 | 78 | self._queue_view.append_column(col) | ||
335 | 79 | |||
336 | 80 | def __populate_queue(self): | ||
337 | 81 | """Populates the _model with tracks""" | ||
338 | 82 | tracks = self._queue.get_ordered_tracks() | ||
339 | 83 | if tracks == self.__last_tracks: | ||
340 | 84 | LOG.debug(_("Tracks did not change, no need to update")) | ||
341 | 85 | return | ||
342 | 86 | # Find the row that will be selected | ||
343 | 87 | |||
344 | 88 | if self._queue_view is not None: | ||
345 | 89 | model, iter = self._queue_view.get_selection().get_selected() | ||
346 | 90 | if iter: | ||
347 | 91 | target = model.get_value(iter, 2) | ||
348 | 92 | try: | ||
349 | 93 | new_cursor_pos = tracks.index(target) | ||
350 | 94 | except ValueError: | ||
351 | 95 | pass | ||
352 | 96 | if 'new_cursor_pos' not in locals(): | ||
353 | 97 | new_cursor_pos = None | ||
354 | 98 | self.__last_tracks = copy(tracks) | ||
355 | 99 | self._model.clear() | ||
356 | 100 | # Add the rows | ||
357 | 101 | for i, track in zip(xrange(1, len(tracks) + 1), tracks): | ||
358 | 102 | self._model.append((i, unicode(track), track)) | ||
359 | 103 | # Select new row | ||
360 | 104 | if new_cursor_pos is not None and hasattr(self, '_queue_view'): | ||
361 | 105 | self._queue_view.set_cursor((new_cursor_pos,)) | ||
362 | 106 | |||
363 | 107 | def show(self): | ||
364 | 108 | """ | ||
365 | 109 | Displays this window | ||
366 | 110 | """ | ||
367 | 111 | self._dialog.show_all() | ||
368 | 112 | |||
369 | 113 | def destroy(self, *e): | ||
370 | 114 | """ | ||
371 | 115 | Destroys this window | ||
372 | 116 | """ | ||
373 | 117 | self._dialog.destroy() | ||
374 | 118 | self.__teardown_callbacks() | ||
375 | 119 | |||
376 | 120 | # removing items | ||
377 | 121 | def remove_selected(self, button, *userparams): | ||
378 | 122 | model, iter = self._queue_view.get_selection().get_selected() | ||
379 | 123 | if not iter: | ||
380 | 124 | return | ||
381 | 125 | i = model.get_value(iter, 0) - 1 | ||
382 | 126 | self.remove(i) | ||
383 | 127 | |||
384 | 128 | def remove_all(self, button, *userparams): | ||
385 | 129 | while len(self._queue.get_ordered_tracks()): | ||
386 | 130 | self.remove(0) | ||
387 | 131 | |||
388 | 132 | def remove(self, i): | ||
389 | 133 | """Removes the ith item from the queue, 0-indexed""" | ||
390 | 134 | cur_queue = self._queue.get_ordered_tracks() | ||
391 | 135 | if i < 0 or i >= len(cur_queue): | ||
392 | 136 | LOG.error(_("Gave an invalid number to remove")) | ||
393 | 137 | return | ||
394 | 138 | cur_queue.pop(i) | ||
395 | 139 | self.__populate_queue() | ||
396 | 140 | |||
397 | 141 | # Moving callbacks | ||
398 | 142 | def selected_to_top(self, button, *userparams): | ||
399 | 143 | self.reorder(lambda x, l: 0) | ||
400 | 144 | |||
401 | 145 | def selected_up(self, button, *userparams): | ||
402 | 146 | self.reorder(lambda x, l: x - 1) | ||
403 | 147 | |||
404 | 148 | def selected_down(self, button, *userparams): | ||
405 | 149 | self.reorder(lambda x, l: x + 1) | ||
406 | 150 | |||
407 | 151 | def selected_to_bottom(self, button, *userparams): | ||
408 | 152 | self.reorder(lambda x, l: l - 1) | ||
409 | 153 | |||
410 | 154 | def reorder(self, new_loc): | ||
411 | 155 | """Reorders the tracks in the queue. | ||
412 | 156 | |||
413 | 157 | new_loc is a function that takes two variables, x and l. x will be the | ||
414 | 158 | the index of the currently selected item. l will be the size of the | ||
415 | 159 | queue. The function need not bounds check. | ||
416 | 160 | |||
417 | 161 | """ | ||
418 | 162 | model, iter = self._queue_view.get_selection().get_selected() | ||
419 | 163 | if not iter: | ||
420 | 164 | return | ||
421 | 165 | |||
422 | 166 | i = model.get_value(iter, 0) - 1 | ||
423 | 167 | tracks = self._queue.get_ordered_tracks() | ||
424 | 168 | if callable(new_loc): | ||
425 | 169 | new_loc = new_loc(i, len(tracks)) | ||
426 | 170 | if new_loc < 0 or new_loc >= len(tracks): | ||
427 | 171 | new_loc = i | ||
428 | 172 | |||
429 | 173 | new_order = list(zip(range(len(tracks)), tracks)) | ||
430 | 174 | new_order[new_loc], new_order[i] = new_order[i], new_order[new_loc] | ||
431 | 175 | |||
432 | 176 | self._queue.set_ordered_tracks(list(map(itemgetter(1), new_order))) | ||
433 | 177 | self.__populate_queue() | ||
434 | 178 | |||
435 | 179 | def main(): | ||
436 | 180 | class Track(object): | ||
437 | 181 | def __init__(self, title): | ||
438 | 182 | self.tags = {'title': title} | ||
439 | 183 | def __unicode__(self): | ||
440 | 184 | return self.tags['title'] | ||
441 | 185 | def __str(self): | ||
442 | 186 | return str(unicode(self)) | ||
443 | 187 | class Foo(object): | ||
444 | 188 | ordered_tracks = [Track('Track Foo by bar on baz'), Track('bar')] | ||
445 | 189 | get_ordered_tracks = lambda self: self.ordered_tracks | ||
446 | 190 | def set_ordered_tracks(self, v): | ||
447 | 191 | self.ordered_tracks = v | ||
448 | 192 | dialog = QueueManager(Foo()) | ||
449 | 193 | dialog.show() | ||
450 | 194 | try: | ||
451 | 195 | gtk.main() | ||
452 | 196 | except KeyboardInterrupt: | ||
453 | 197 | pass | ||
454 | 198 | |||
455 | 199 | if __name__ == "__main__": | ||
456 | 200 | main() |
Adds queue managing functionality as a popup. This could later be extended to include Queue Manager as a pane if enough support is gathered.