18 # You should have received a copy of the GNU General Public License |
18 # You should have received a copy of the GNU General Public License |
19 # along with GNU Emacs; see the file COPYING. If not, write to the |
19 # along with GNU Emacs; see the file COPYING. If not, write to the |
20 # Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
20 # Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
21 # Boston, MA 02111-1307, USA. |
21 # Boston, MA 02111-1307, USA. |
22 |
22 |
23 _immsview_version = "$Id: immsview 1692 2004-02-02 15:45:25Z fabien $" |
23 _immsview_version = "$Id: immsview 1693 2004-02-03 18:50:03Z fabien $" |
24 |
24 |
25 # $Log$ |
25 # $Log$ |
|
26 # Revision 1.12 2004/02/03 18:50:03 fabien |
|
27 # Add double click and remove sorting when refreshing data. |
|
28 # |
26 # Revision 1.11 2004/02/02 15:45:25 fabien |
29 # Revision 1.11 2004/02/02 15:45:25 fabien |
27 # Add a comment about the autocommit value in db.connect() |
30 # Add a comment about the autocommit value in db.connect() |
28 # |
31 # |
29 # Revision 1.10 2004/02/02 15:42:43 fabien |
32 # Revision 1.10 2004/02/02 15:42:43 fabien |
30 # OK, reset current after changing song manually... however, I most |
33 # OK, reset current after changing song manually... however, I most |
161 cu.execute('''SELECT Library.uid, Library.sid |
164 cu.execute('''SELECT Library.uid, Library.sid |
162 FROM Library |
165 FROM Library |
163 WHERE Library.path = '%s';''' % (path)) |
166 WHERE Library.path = '%s';''' % (path)) |
164 return cu.fetchone() |
167 return cu.fetchone() |
165 def get_ratings_and_info(self): |
168 def get_ratings_and_info(self): |
|
169 print time.ctime(time.time()) + ": querying" |
166 cu = self.cx.cursor() |
170 cu = self.cx.cursor() |
167 cu.execute('''SELECT Rating.uid, Rating.rating, |
171 cu.execute('''SELECT Rating.uid, Rating.rating, |
168 Library.path, Last.last |
172 Library.path, Last.last |
169 FROM Rating, Library, Last |
173 FROM Rating, Library, Last |
170 WHERE Rating.uid = Library.uid AND |
174 WHERE Rating.uid = Library.uid AND |
171 Library.sid = Last.sid |
175 Library.sid = Last.sid |
172 ORDER BY Rating.rating DESC;''') |
176 ORDER BY Rating.rating DESC;''') |
173 # Better to fetch everything since locking can really mess |
177 # Better to fetch everything since locking can really mess |
174 # things in imms plugin. |
178 # things in imms plugin. |
175 res = cu.fetchall() |
179 print time.ctime(time.time()) + ": mapping" |
176 self.commit() |
180 results = [] |
177 results = [] |
181 tune = cu.fetchone() |
178 for tune in res: |
182 while tune: |
179 try: |
183 try: |
180 tmp = {'rating' : int(tune[1]), |
184 tmp = {'rating' : int(tune[1]), |
181 'path' : tune[2].decode('utf-8', 'replace'), |
185 'path' : tune[2].decode('utf-8', 'replace'), |
182 'last' : int(tune[3])} |
186 'last' : int(tune[3])} |
183 results.append(tmp) |
187 results.append(tmp) |
184 except UnicodeDecodeError: |
188 except UnicodeDecodeError: |
185 print tune[2] |
189 print tune[2] |
|
190 tune = cu.fetchone() |
186 return results |
191 return results |
187 |
192 |
188 class IMMSStore(gtk.ListStore): |
193 class IMMSStore(gtk.ListStore): |
189 COL_RATING = 0 |
194 COL_RATING = 0 |
190 COL_PATH = 1 |
195 COL_PATH = 1 |
197 gobject.TYPE_STRING, |
202 gobject.TYPE_STRING, |
198 gobject.TYPE_STRING, |
203 gobject.TYPE_STRING, |
199 gobject.TYPE_INT, |
204 gobject.TYPE_INT, |
200 gobject.TYPE_BOOLEAN) |
205 gobject.TYPE_BOOLEAN) |
201 self.db = db |
206 self.db = db |
202 self.set_sort_column_id(IMMSStore.COL_RATING, gtk.SORT_DESCENDING) |
207 # self.set_default_sort_func(self.default_sort) |
|
208 def default_sort(self, a, b, dummy): |
|
209 return 0 |
203 def refresh(self): |
210 def refresh(self): |
204 curtime = time.time() |
211 curtime = time.time() |
205 col, order = self.get_sort_column_id() |
212 col, order = self.get_sort_column_id() |
206 self.set_sort_column_id(IMMSStore.COL_RATING, gtk.SORT_DESCENDING) |
213 # This create a GTK-Critical in GTKListStore which, |
|
214 # however, have no consequences AFAIK. |
|
215 # The doc permit it normally, even without default sort, |
|
216 # elsewhere |
|
217 self.set_sort_column_id(-1, 0) |
207 tunes = self.db.get_ratings_and_info() |
218 tunes = self.db.get_ratings_and_info() |
208 self.clear() |
219 self.clear() |
|
220 print time.ctime(time.time()) + ": inserting" |
209 for tune in tunes: |
221 for tune in tunes: |
210 iter = self.append(None) |
222 iter = self.append(None) |
211 self.set(iter, |
223 self.set(iter, |
212 IMMSStore.COL_RATING, tune['rating'], |
224 IMMSStore.COL_RATING, tune['rating'], |
213 IMMSStore.COL_PATH, tune['path'], |
225 IMMSStore.COL_PATH, tune['path'], |
214 IMMSStore.COL_LAST_STR, strtime(curtime-tune['last']), |
226 IMMSStore.COL_LAST_STR, strtime(curtime-tune['last']), |
215 IMMSStore.COL_LAST, tune['last'], |
227 IMMSStore.COL_LAST, tune['last'], |
216 IMMSStore.COL_SELECT, gtk.FALSE) |
228 IMMSStore.COL_SELECT, gtk.FALSE) |
|
229 print time.ctime(time.time()) + ": end insert" |
217 self.set_sort_column_id(col, order) |
230 self.set_sort_column_id(col, order) |
218 def find_selection(self): |
231 def find_selection(self): |
219 giter = self.get_iter_first() |
232 giter = self.get_iter_first() |
220 while giter: |
233 while giter: |
221 if self.get_value(giter, 4): |
234 if self.get_value(giter, 4): |
229 return self.get_path(giter) |
242 return self.get_path(giter) |
230 giter = self.iter_next(giter) |
243 giter = self.iter_next(giter) |
231 return None |
244 return None |
232 |
245 |
233 class IMMSView(gtk.TreeView): |
246 class IMMSView(gtk.TreeView): |
234 def __init__(self, model): |
247 def __init__(self, model, xmms): |
235 gtk.TreeView.__init__(self, model) |
248 gtk.TreeView.__init__(self, model) |
|
249 self.xmms = xmms |
236 self.create_widgets() |
250 self.create_widgets() |
237 def create_widgets(self): |
251 def create_widgets(self): |
238 renderer = gtk.CellRendererText() |
252 renderer = gtk.CellRendererText() |
239 renderer.set_property('weight', 700) |
253 renderer.set_property('weight', 700) |
240 column = gtk.TreeViewColumn(_("Rating"), renderer, |
254 column = gtk.TreeViewColumn(_("Rating"), renderer, |
253 column.set_resizable(gtk.TRUE) |
267 column.set_resizable(gtk.TRUE) |
254 column.set_sort_column_id(IMMSStore.COL_PATH) |
268 column.set_sort_column_id(IMMSStore.COL_PATH) |
255 self.append_column(column) |
269 self.append_column(column) |
256 self.set_search_column(IMMSStore.COL_PATH) |
270 self.set_search_column(IMMSStore.COL_PATH) |
257 self.set_headers_clickable(gtk.TRUE) |
271 self.set_headers_clickable(gtk.TRUE) |
|
272 self.connect('row-activated', self.on_row_activated) |
258 def set_current_song(self, song): |
273 def set_current_song(self, song): |
259 model = self.get_model() |
274 model = self.get_model() |
260 gpath = model.find_selection() |
275 gpath = model.find_selection() |
261 if gpath: |
276 if gpath: |
262 giter = model.get_iter(gpath) |
277 giter = model.get_iter(gpath) |
269 def get_file_selected(self): |
284 def get_file_selected(self): |
270 model, giter = self.get_selection().get_selected() |
285 model, giter = self.get_selection().get_selected() |
271 if giter: |
286 if giter: |
272 return model.get_value(giter, IMMSStore.COL_PATH) |
287 return model.get_value(giter, IMMSStore.COL_PATH) |
273 return None |
288 return None |
|
289 def on_row_activated(self, tview, path, col): |
|
290 model = self.get_model() |
|
291 giter = model.get_iter(path) |
|
292 fn = model.get_value(giter, IMMSStore.COL_PATH) |
|
293 self.xmms.play_file(fn) |
|
294 |
274 |
295 |
275 class IMMSToolbar(gtk.Toolbar): |
296 class IMMSToolbar(gtk.Toolbar): |
276 # _IMMSPLOT_COMMAND = 'immsplot &' |
297 # _IMMSPLOT_COMMAND = 'immsplot &' |
277 _IMMSPLOT_COMMAND = '/home/fabien/bin/immsplot &' |
298 _IMMSPLOT_COMMAND = '/home/fabien/bin/immsplot &' |
278 _SLEEP_TIME = 1 |
299 _SLEEP_TIME = 1 |
313 self.do_get_current(dummy) |
334 self.do_get_current(dummy) |
314 def do_play_next(self, dummy): |
335 def do_play_next(self, dummy): |
315 self.xmms.playlist_next() |
336 self.xmms.playlist_next() |
316 time.sleep(self._SLEEP_TIME) |
337 time.sleep(self._SLEEP_TIME) |
317 self.do_get_current(dummy) |
338 self.do_get_current(dummy) |
318 |
|
319 |
339 |
320 root = gtk.Window() |
340 root = gtk.Window() |
321 root.set_title(_("IMMSView")) |
341 root.set_title(_("IMMSView")) |
322 root.connect('destroy', gtk.mainquit) |
342 root.connect('destroy', gtk.mainquit) |
323 vbox = gtk.VBox(spacing = 3) |
343 vbox = gtk.VBox(spacing = 3) |
324 root.add(vbox) |
344 root.add(vbox) |
325 vbox.show() |
345 vbox.show() |
326 model = IMMSStore(IMMSDb()) |
346 model = IMMSStore(IMMSDb()) |
327 iview = IMMSView(model) |
347 xmms_control = XMMSControl() |
|
348 iview = IMMSView(model,xmms_control) |
328 scroll = gtk.ScrolledWindow() |
349 scroll = gtk.ScrolledWindow() |
329 scroll.add(iview) |
350 scroll.add(iview) |
330 vbox.pack_end(scroll) |
351 vbox.pack_end(scroll) |
331 iview.show() |
352 iview.show() |
332 scroll.show() |
353 scroll.show() |
333 toolbar = IMMSToolbar(iview, XMMSControl()) |
354 toolbar = IMMSToolbar(iview, xmms_control) |
334 vbox.pack_start(toolbar, expand = gtk.FALSE) |
355 vbox.pack_start(toolbar, expand = gtk.FALSE) |
335 toolbar.show() |
356 toolbar.show() |
336 root.show() |
357 root.show() |
337 toolbar.do_refresh(None) |
358 toolbar.do_refresh(None) |
338 toolbar.do_get_current(None) |
359 toolbar.do_get_current(None) |