[svn] Switch to GTK2. immsview
authorfabien
Sun, 01 Feb 2004 23:51:35 -0500
branchimmsview
changeset 6 ad5b932e411d
parent 5 c51b96c1690e
child 7 c5c0a84bb15b
[svn] Switch to GTK2.
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("<Double-Button-1>", 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()