All pastes #340177 Raw Edit

Mine

public text v1 · immutable
·published 2007-02-04 16:34 UTC
rendered paste body
#!/usr/bin/env python

import dircache
import pygtk
pygtk.require ('2.0')
import gtk
import gobject
import os
import os.path
import stat

def make_stock_menu_item_factory_param (stock_item, path = "", callback = None, param = 0, type = None):
    (stock_id, label, modifier, keyval, translation_domain) = gtk.stock_lookup (stock_item)
    return (path + label, gtk.accelerator_name (keyval, modifier), callback, param, type);

class Player:
    def __init__ (self):
        self.name = 'Unknown'
        self.mount_point = None
        self.subdirectory = ""
        self.replace_illegals = True

class FileSet:
    class Entry:
        def __init__ (self, name):
            self.name = name
        
        def get_name (self):
            return self.name

        def intersect (self, other):
            return None

        def minus (self, other):
            return None
    
    class File (Entry):
        def __init__ (self, name, path):
            super (name)
            self.path = path
            self.size = None
            self.mtime = None
            self.data = None
        
        def do_init (self):
            if self.path:
                stat = stat (path)
                self.size = stat.ST_SIZE
                self.mtime = stat.ST_MTIME
                self.path = None
        
        def get_size (self):
            self.do_init ()
            return self.size

        def get_mtime (self):
            self.do_init ()
            return self.mtime

        def __eq__ (self, other):
            if isinstance (other, File):
                self.do_init ()
                other.do_init ()
                if self.name == other.name and \
                       self.size == other.size and \
                       self.mtime == other.mtime:
                    return True
            return False

        def __ne__ (self, other):
            return not self.__eq__ (other)
        
        def intersect (self, other):
            if self == other:
                return self
            else:
                return None
        
        def minus (self, other):
            if self == other:
                return None
            else:
                return self
    
    class Directory (Entry):
        def __init__ (self, name, path):
            super (name)
            self.path = path
            self.entries = None
            self.data = None
        
        def do_init (self):
            if self.path:
                self.entries = []
                def entry_cmp (x, y):
                    ret = cmp (x, y)
                    if ret == 0:
                        ret = cmp (x.lower (), y.lower ())
                    return ret
                for entry in sorted (dircache.listdir (path, entry_cmp)):
                    self.entries.append (read_entry (entry, os.path.join (path, entry)))
                self.path = None
            
        def get_entries (self):
            self.do_init ()
            return self.entries

        def intersect (self, other):
            if isinstance (other, Directory):
                
                self.do_init ()
                other.do_init ()
                
                ret = Dictionary (self.name, None)
                ret.entries = []

                self_index = 0
                other_index = 0
                while self_start < len (self.entries) and other_start < len (other.entries):
                    cmp_result = cmp (self.entries[self_index].name, other.entries[other_index].name)
                    if cmp_result < 0:
                        self_index = self_index + 1
                    elif cmp_result > 0:
                        other_index = other_index + 1
                    else:
                        ret.entries.append (self.entries[self_index].intersect (other.entries[other_index]))
                return ret
            else:
                return None
        
        def minus (self, other):
            if isinstance (other, Directory):
                
                self.do_init ()
                other.do_init ()
                
                ret = Dictionary (self.name, None)
                ret.entries = []

                self_index = 0
                other_index = 0
                while self_start < len (self.entries) and other_start < len (other.entries):
                    cmp_result = cmp (self.entries[self_index].name, other.entries[other_index].name)
                    if cmp_result != 0:
                        ret.entries.append (self.entries[self_index])
                        if cmp_result < 0:
                            self_index = self_index + 1
                        elif cmp_result > 0:
                            other_index = other_index + 1
                return ret
            else:
                return self
    
    def __init__ (self, root_path):
        self.root_path = root_path
        self.root_entry = None
    
    def read_entry (name, path):
        stat = os.stat (path)
        if stat.S_ISDIR (path):
            return Directory (name, path)
        elif stat.S_ISREG (path):
            return File (name, path)
    
    def refresh (self, callback):
        if self.root_path:
            self.root_entry = read_entry (None, self.root_path)

    def intersect (self, other):
        ret = FileSet (None)
        if self.root_entry and other.root_entry:
            ret.root_entry = self.root_entry.intersect (other.root_entry.intersect)
        return ret
    
    def minus (self, other):
        ret = FileSet (None)
        if self.root_entry:
            if other.root_entry:
                ret.root_entry = self.root_entry.minus (other.root_entry)
            else:
                ret.root_entry = self.root_entry
        return ret

class TreeModel (gtk.GenericTreeModel):
    column_types = (str, gobject.TYPE_BOOLEAN, object)
    
    def __init__ (self, fileset = None):
        self.fileset = fileset
        self.marked = set ()
    
    def on_get_flags (self):
        return gtk.TREE_MODEL_ITERS_PERSIST
    
    def on_get_n_columns (self):
        return len (self.column_types);
    
    def on_get_column_type (self, index):
        return self.column_types[index]
    
    def on_get_iter (self, path):
        ret = []
        current_entry = self.fileset.root_entry
        for index in path:
            current_entry = current_entry.entries[index]
            ret.append (current_entry.name)
        return ret
    
    def follow_rowref (self, rowref, proc):
        
        dir_entry = self.fileset.root_entry
        
        for rowref_index in range (0, len (rowref)):
            
            index = 0
            
            while index < len (dir_entry.entries):
                
                test_entry = dir_entry.entries[index]
                
                if test_entry.name == rowref[rowref_index]:
                    proc (dir_entry.entries, index, rowref_index)
                    dir_entry = test_entry
                    break
                
                index = index + 1
            
            if index == len (dir_entry.entries):
                return False
        
        return True
    
    def on_get_path (self, rowref):
        class on_get_path_follow_rowref_proc:
            def __init__ (self):
                ret = []

            def __call__ (self, entries, index, rowref_index):
                self.ret.append (index)
        
        proc = on_get_path_follow_rowref_proc ()
        
        if self.follow_rowref (rowref, proc):
            return tuple (proc.ret)
        else:
            return None
    
    def on_get_value (self, rowref, column):
        if column == 0:
            if len (rowref) == 0:
                return None
            else:
                return rowref[-1]
        
        elif column == 1:
            return rowref in self.marks
        
        elif column == 2:
            class on_get_value_follow_rowref_proc:
                def __init__ (self, rowref):
                    self.ret = None
                    self.rowref_len = len (rowref)
                
                def __call__ (self, entries, index, rowref_index):
                    if rowref_index == (self.rowref_len - 1):
                        self.ret = entries[index]

            if rowref == None:
                return self.root_entry
            
            proc = on_get_value_follow_rowref_proc (rowref)
            
            if self.follow_rowref (rowref, proc):
                return proc.ret
            else:
                return None
            
        else:
            return None
    
    def on_iter_next (self, rowref):

        class on_iter_next_follow_rowref_proc:
            def __init__ (self, rowref):
                self.rowref_len = len (rowref)
                self.ret = []
            
            def __call__ (self, entries, index, rowref_index):
                if rowref_index == (self.rowref_len - 1):
                    if (index < (len (entries) - 1)):
                        self.ret.append (entries[index + 1].name)
                    else:
                        self.ret = None
                else:
                    self.ret.append (entries[index])
                
        proc = on_iter_next_follow_rowref_proc (rowref)
            
        if self.follow_rowref (rowref, proc):
            return tuple (proc.ret)
        else:
            return None
    
    def on_iter_children (self, parent):
        entry = self.on_iter_get_value (parent, 2)
        if isinstance (entry, Directory):
            return entry.entries[0]
        else:
            return None
    
    def on_iter_has_child (self, rowref):
        entry = self.on_iter_get_value (rowref, 2)
        if isinstance (entry, Directory):
            return len (entry.entries) != 0
        else:
            return False
    
    def on_iter_n_children (self, rowref):
        entry = self.on_iter_get_value (rowref, 2)
        if isinstance (entry, Directory):
            return len (entry.entries)
        else:
            return 0
    
    def on_iter_nth_child (self, parent, n):
        if parent == None:
            return self.root_entry.entries[n]
        else:
            entry = self.on_iter_get_value (rowref, 2)
            if isinstance (entry, Directory) and \
               (n < len (entry.entries)):
                    return entry.entries[n]
            else:
                return None
    
    def on_iter_parent (self, child):
        if child == None:
            return None
        elif len (child) < 2:
            return None
        else:
            return child[0:-1]

class MainWindow (gtk.Window):
    def __init__ (self):
        gtk.Window.__init__ (self, gtk.WINDOW_TOPLEVEL)

        self.accel_group = gtk.AccelGroup ()
        self.add_accel_group (self.accel_group)
        
        self.item_factory = gtk.ItemFactory (gtk.MenuBar, "<main>", self.accel_group)
        menu_items = ( ("/_File", None, None, 0, "<Branch>", ),
                       make_stock_menu_item_factory_param (gtk.STOCK_APPLY, "/_Apply/", self.apply_clicked),
                       make_stock_menu_item_factory_param (gtk.STOCK_QUIT, "/_Quit/", self.quit),
                       ("/_Help", None, None, 0, "<Branch>", ),
                       make_stock_menu_item_factory_param (gtk.STOCK_ABOUT, "/_About/", self.about_clicked) )
        self.item_factory.create_items (menu_items)
        menubar = self.item_factory.get_widget ("<main>")
        
        vbox = gtk.VBox (False, 0)
        
        vbox.pack_start (menubar, False, True, 0)
        menubar.show ()
        
        self.treemodel = TreeModel (FileSet ("."))
        self.treeview = gtk.TreeView (self.treemodel)
        
        self.toggle_renderer = gtk.CellRendererToggle ()
        self.text_renderer = gtk.CellRendererText ()
        self.treeview_column = gtk.TreeViewColumn.pack_start (self.toggle_renderer, False)
        self.treeview_column = gtk.TreeViewColumn.pack_start (self.text_renderer, True)
        self.treeview_column.add_attribute (self.toggle_renderer, "active", 2)
        self.treeview_column.add_attribute (self.text_renderer, "text", 1)
        
        vbox.pack_start (self.treeview, True, True)
        self.treeview.show ()
        
        self.add (vbox)
        vbox.show ()
        
        self.show ()
    
    def apply_clicked (self, widget, data):
        pass

    def quit (self, widget, data):
        pass

    def about_clicked (self, widget, data):
        pass

main_window = MainWindow ()