# HG changeset patch # User fabien # Date 1075697495 18000 # Node ID ad5b932e411dfee5856ce56fb7fab882e57aa25a # Parent c51b96c1690e625a1db759bd5103c9774396f44d [svn] Switch to GTK2. diff -r c51b96c1690e -r ad5b932e411d immsview --- a/immsview Sun Feb 01 12:21:02 2004 -0500 +++ b/immsview Sun Feb 01 23:51:35 2004 -0500 @@ -1,6 +1,6 @@ #!/usr/bin/python -_immsview_version = "$Id: immsview 1687 2004-02-01 17:21:02Z fabien $" +_immsview_version = "$Id: immsview 1688 2004-02-02 04:51:35Z fabien $" # Copyright (C) 2004 by Fabien Ninoles @@ -38,21 +38,23 @@ # - adding, deleting, suppressing a file (including updating other # interface). +import pygtk +pygtk.require('2.0') + import sys import os import sqlite -import Tkinter -import ScrolledText +import gobject +import gtk +import gtk.glade import gettext import xmms.control import time -gettext.bindtextdomain('immsview', '/usr/share/immsview/LANG') -gettext.textdomain('immsview') +gtk.glade.bindtextdomain('immsview', '/usr/share/immsview/LANG') +gtk.glade.textdomain('immsview') _ = gettext.gettext -_dbname = os.environ['HOME'] + '/.imms/imms.db' - def strtime(seconds): secs = abs(round(seconds)) minutes = secs / 60; @@ -89,134 +91,166 @@ return -1 def play_file(self, filename): idx = self.find_in_playlist(filename) - print idx if idx == -1: self.enqueue_and_play((filename,)) else: self.set_playlist_pos(idx) class IMMSDb: + _dbname = os.environ['HOME'] + '/.imms/imms.db' + # _dbname = os.environ['HOME'] + '/.imms/imms.backup.db' + def __init__(self): + self.cx = sqlite.connect(IMMSDb._dbname) + def commit(self): + self.cx.commit() + def _get_ratings(self, min = 0, max = 250): + cu = self.cx.cursor() + cu.execute('''SELECT Rating.uid, Rating.rating + FROM Rating + WHERE Rating.rating >= %d + AND Rating.rating <= %d + ORDER BY Rating.rating;''' % (min, max)) + return cu.fetchall() + def _get_library_uid(self, uid): + cu = self.cx.cursor() + cu.execute('''SELECT Library.path + FROM Library + WHERE Library.uid = %d;''' % (uid,)) + return cu.fetchone() + def _get_library_by_path(self, path): + cu = self.cx.cursor() + cu.execute('''SELECT Library.uid, Library.sid + FROM Library + WHERE Library.path = '%s';''' % (path)) + return cu.fetchone() + def get_ratings_and_info(self): + cu = self.cx.cursor() + cu.execute('''SELECT Rating.uid, Rating.rating, + Library.path, Last.last + FROM Rating, Library, Last + WHERE Rating.uid = Library.uid AND + Library.sid = Last.sid + ORDER BY Rating.rating DESC;''') + # Better to fetch everything since locking can really mess + # things in imms plugin. + res = cu.fetchall() + self.commit() + results = [] + for tune in res: + try: + tmp = {'rating' : tune[1], + 'path' : tune[2].decode('latin_1', 'replace'), + 'last' : int(tune[3])} + results.append(tmp) + except UnicodeDecodeError: + print tune[2] + return results + +class IMMSStore(gtk.ListStore): + COL_RATING = 0 + COL_PATH = 1 + COL_LAST_STR = 2 + COL_LAST = 3 + COL_SELECT = 4 + def __init__(self, db, xmms): + gtk.ListStore.__init__(self, + gobject.TYPE_INT, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_INT, + gobject.TYPE_BOOLEAN) + self.db = db + self.xmms = xmms + def refresh(self): + curtime = time.time() + tunes = self.db.get_ratings_and_info() + self.clear() + for tune in tunes: + iter = self.append(None) + self.set(iter, + IMMSStore.COL_RATING, tune['rating'], + IMMSStore.COL_PATH, tune['path'], + IMMSStore.COL_LAST_STR, strtime(curtime-tune['last']), + IMMSStore.COL_LAST, tune['last'], + IMMSStore.COL_SELECT, gtk.FALSE) + def _check_song_path(self, path, giter, song): + self.set(giter, 4, self.get_value(giter, 1) == song) + def set_current_song(self): + self.foreach(IMMSStore._check_song_path, self.xmms.get_current_file()) + +class IMMSView(gtk.TreeView): + def __init__(self, model, xmms): + gtk.TreeView.__init__(self, model) + self.create_widgets() + def create_widgets(self): + renderer = gtk.CellRendererText() + renderer.set_property('weight', 700) + # renderer.connect('double-clicked', on_clicked) + column = gtk.TreeViewColumn(_("Rating"), renderer, + weight_set = IMMSStore.COL_SELECT, + text = IMMSStore.COL_RATING) + column.set_sort_column_id(IMMSStore.COL_RATING) + self.append_column(column) + column = gtk.TreeViewColumn(_("File"), renderer, + weight_set = IMMSStore.COL_SELECT, + text = IMMSStore.COL_PATH) + column.set_resizable(gtk.TRUE) + column.set_sort_column_id(IMMSStore.COL_PATH) + column.set_clickable(gtk.TRUE) + self.append_column(column) + column = gtk.TreeViewColumn(_("Last"), renderer, + weight_set = IMMSStore.COL_SELECT, + text = IMMSStore.COL_LAST_STR) + column.set_sort_column_id(IMMSStore.COL_LAST) + self.append_column(column) + self.set_search_column(IMMSStore.COL_PATH) + self.set_headers_clickable(gtk.TRUE) + def get_selected(self): + model, giter = self.get_selection().get_selected() + return model.get_value(giter, IMMSStore.COL_PATH) + +class IMMSToolbar(gtk.Toolbar): def __init__(self): - self.cx = sqlite.connect(_dbname) - def commit(self): - self.cx.commit() - def _get_ratings(self, min = 0, max = 250): - cu = self.cx.cursor() - cu.execute('''SELECT Rating.uid, Rating.rating - FROM Rating - WHERE Rating.rating >= %d - AND Rating.rating <= %d - ORDER BY Rating.rating;''' % (min, max)) - return cu.fetchall() - def _get_library_uid(self, uid): - cu = self.cx.cursor() - cu.execute('''SELECT Library.path - FROM Library - WHERE Library.uid = %d;''' % (uid,)) - return cu.fetchone() - def _get_library_by_path(self, path): - cu = self.cx.cursor() - cu.execute('''SELECT Library.uid, Library.sid - FROM Library - WHERE Library.path = '%s';''' % (path)) - def get_ratings_and_info(self): - cu = self.cx.cursor() - cu.execute('''SELECT Rating.uid, Rating.rating, - Library.path, Last.last - FROM Rating, Library, Last - WHERE Rating.uid = Library.uid AND - Library.sid = Last.sid - ORDER BY Rating.rating DESC;''') - # Better to fetch everything since locking can really mess - # things in imms plugin. - res = cu.fetchall() - self.commit() - results = [] - for tune in res: - tmp = {'rating' : tune[1], - 'path' : tune[2], - 'last' : int(tune[3])} - results.append(tmp) - return results - -class IMMSView(Tkinter.Frame): - def __init__(self, xmms, db, master = None): - Tkinter.Frame.__init__(self, master) - self.db = db - self.xmms = xmms + gtk.Toolbar.__init__(self) + self.refresh_command = None + self.select_command = None self.create_widgets() def create_widgets(self): - lf = Tkinter.Frame(self) - lf.pack(expand = 1, fill = Tkinter.BOTH, side = Tkinter.LEFT) - self.lb = Tkinter.Listbox(lf, relief = Tkinter.RAISED) - self.lb.pack(expand = 1, side = Tkinter.TOP, fill = Tkinter.BOTH) - xsb = Tkinter.Scrollbar(lf, orient = Tkinter.HORIZONTAL) - xsb.pack({'fill' : Tkinter.X, 'side' : Tkinter.BOTTOM}) - ysb = Tkinter.Scrollbar(self) - ysb.pack({'fill' : Tkinter.Y, 'side' : Tkinter.RIGHT}) - - ysb['command'] = self.lb.yview - xsb['command'] = self.lb.xview - self.lb['yscrollcommand'] = ysb.set - self.lb['xscrollcommand'] = xsb.set - self.lb.bind("", self.play_selection) - - self.refresh() - - def refresh(self): - curtime = time.time() - self.tunes = self.db.get_ratings_and_info() - self.lb.delete(0,self.lb.size()) - l = [] - for tune in self.tunes: - l.append("%4d: %s [%s]" % - (tune['rating'], tune['path'], - strtime(curtime - tune['last']))) - apply(self.lb.insert, [0]+ l) - self.select_current() - def select_current(self): - fn = self.xmms.get_current_file() - tune = filter(lambda x: x['path'] == fn, self.tunes) - if len(tune): - idx = self.tunes.index(tune[0]) - self.lb.see(idx) - self.lb.select_set(idx) - def play_selection(self, event): - sel = self.lb.curselection() - if len(sel) > 0: - fn = self.tunes[int(sel[0])]['path'] - self.xmms.play_file(fn) - -class IMMSToolbar(Tkinter.Frame): - def __init__(self, master = None): - Tkinter.Frame.__init__(self, master) - self.refresh_command = None - self.create_widgets() - def create_widgets(self): - button = Tkinter.Button(self, text = _('Refresh'), - command = self.do_refresh) - button.pack(side = Tkinter.LEFT) - button = Tkinter.Button(self, text = _('Plot'), - command = self.plot) - button.pack(side = Tkinter.LEFT) - button = Tkinter.Button(self, text = _('Current'), - command = self.do_get_current) - button.pack(side = Tkinter.LEFT) - def plot(self): - os.system('exec immsplot &') - def do_refresh(self): + self.append_item(_('Refresh'), _('Refresh list'), + None, None, self.do_refresh) + self.append_item(_('Plot'), _('Show graph of rates'), + None, None, self.plot) + self.append_item(_('Current'), _('Get current song'), + None, None, self.do_get_current) + def plot(self, data): + os.system('/home/fabien/bin/immsplot &') + def do_refresh(self, data): if (self.refresh_command): self.refresh_command() - def do_get_current(self): + def do_get_current(self, data): if (self.get_current): self.get_current() -root = Tkinter.Tk() -root.wm_title(_("IMMSview")) -iview = IMMSView(XMMSControl(), IMMSDb(), root) -iview.pack(side = Tkinter.BOTTOM, expand = 1, fill = Tkinter.BOTH) +root = gtk.Window() +root.set_name(_("IMMSview")) +root.connect('destroy', gtk.mainquit) +vbox = gtk.VBox(spacing = 3) +root.add(vbox) +vbox.show() +xmms_control = XMMSControl() +model = IMMSStore(IMMSDb(), xmms_control) +iview = IMMSView(model, xmms_control) +scroll = gtk.ScrolledWindow() +scroll.add(iview) +vbox.pack_end(scroll) +iview.show() +scroll.show() toolbar = IMMSToolbar() -toolbar.refresh_command = iview.refresh -toolbar.get_current = iview.select_current -toolbar.pack(side = Tkinter.TOP, fill = Tkinter.X) -root.mainloop() +toolbar.refresh_command = model.refresh +toolbar.get_current = model.set_current_song +vbox.pack_start(toolbar, expand = gtk.FALSE) +toolbar.show() +root.show() +model.refresh() +model.set_current_song() +gtk.main()