Backspace changes to parent.
[rox-shell.git] / rox / shell / shell.py
blob63d700fc9214ab7221c505d73f69627e51819ab4
1 """
2 @copyright: (C) 2008, Thomas Leonard
3 @see: U{http://roscidus.com}
4 """
5 import os, sys
6 from zeroinstall.support import tasks # tmp
8 import _gio as gio
9 import gobject
10 import gtk
12 icon_size = 48
14 gtk_theme = gtk.icon_theme_get_default()
15 icon_text_plain = gtk_theme.load_icon('text-x-generic', icon_size, 0)
16 icon_dir = gtk_theme.load_icon('folder', icon_size, 0)
18 class DirUpdated(tasks.Blocker):
19 changes = []
21 class ShellController:
22 def __init__(self, file):
23 self.file = file
24 self.updated = None
25 self.build_contents()
27 def build_contents(self):
28 contents = []
29 e = self.file.enumerate_children('standard::*', 0)
30 if e:
31 while True:
32 info = e.next_file()
33 if not info:
34 break
35 contents.append(info)
36 self.contents = contents
38 if self.updated:
39 self.updated.trigger()
40 self.updated = DirUpdated("Updates for " + self.file.get_uri())
42 def item_activated(self, name):
43 old_dir = self.file
44 self.file = old_dir.get_child(name)
45 self.build_contents()
47 def cd_parent(self):
48 parent = self.file.get_parent()
49 if parent:
50 self.file = parent
51 self.build_contents()
53 def gtk_tree_model(contents):
54 tm = gtk.ListStore(str, gtk.gdk.Pixbuf)
55 tm.set_sort_column_id(0, gtk.SORT_ASCENDING)
56 for info in contents:
57 name = info.get_name()
58 if not name.startswith('.'):
59 new = tm.append(None)
60 if info.get_file_type() == gio.FILE_TYPE_DIRECTORY:
61 icon = icon_dir
62 else:
63 icon = icon_text_plain
64 tm[new] = [info.get_name(), icon]
65 return tm
67 class ShellView:
68 def __init__(self, shell):
69 self.shell = shell
71 builder = gtk.Builder()
72 builder.add_from_file(os.path.join(os.path.dirname(__file__), "ui.xml"))
73 self.window = builder.get_object('directory')
75 cd_parent = builder.get_object('cd-parent')
76 cd_parent.connect('activate', lambda a: self.shell.cd_parent())
78 # Must show window before adding icons, or we randomly get:
79 # The error was 'BadAlloc (insufficient resources for operation)'
80 self.window.show()
82 self.window_destroyed = tasks.Blocker('Window destroyed')
83 self.window.connect('destroy', lambda w: self.window_destroyed.trigger())
85 self.window.connect('key-press-event', self.key_press_event)
87 self.iv = builder.get_object('iconview')
88 self.iv.set_text_column(0)
89 self.iv.set_pixbuf_column(1)
90 self.iv.set_selection_mode(gtk.SELECTION_MULTIPLE)
92 self.iv.connect('item-activated', self.item_activated)
94 self.window.show_all()
95 self.iv.grab_focus()
97 def key_press_event(self, window, kev):
98 if kev.keyval == gtk.keysyms.BackSpace:
99 self.shell.cd_parent()
101 @tasks.async
102 def run(self):
103 while True:
104 tree_model = gtk_tree_model(self.shell.contents)
105 self.iv.set_model(tree_model)
106 self.window.set_title(self.shell.file.get_uri())
107 yield [self.shell.updated, self.window_destroyed]
108 if self.window_destroyed.happened:
109 break
111 def item_activated(self, iv, path):
112 tm = iv.get_model()
113 name = tm[tm.get_iter(path)][0]
114 self.shell.item_activated(name)