From 03dd3ab7fa9e593d5d09d3cfb6d775363825b33b Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Sun, 9 Mar 2008 11:54:51 +0000 Subject: [PATCH] Type-ahead and glob matching. --- rox/shell/shell.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/rox/shell/shell.py b/rox/shell/shell.py index 1cf7b15..75528a9 100644 --- a/rox/shell/shell.py +++ b/rox/shell/shell.py @@ -2,7 +2,7 @@ @copyright: (C) 2008, Thomas Leonard @see: U{http://roscidus.com} """ -import os, sys +import os, sys, fnmatch from zeroinstall.support import tasks # tmp import _gio as gio @@ -96,6 +96,7 @@ class ShellView: self.command_area = builder.get_object('command') self.entry = gtk.Entry() + self.entry.connect('changed', self.entry_changed) self.entry.show() self.command_area.pack_start(self.entry, False, True, 0) self.command_area.show_all() @@ -104,6 +105,7 @@ class ShellView: if kev.keyval == gtk.keysyms.Escape: self.iv.grab_focus() self.entry.set_text('') + self.iv.unselect_all() return True if self.iv.flags() & gtk.HAS_FOCUS: @@ -120,6 +122,51 @@ class ShellView: self.iv.grab_focus() # Restore focus to IconView return True + def entry_changed(self, entry): + pattern = entry.get_text() + if not pattern: + return + model = self.iv.get_model() + + pattern_star = pattern + '*' + + # If the user only entered lower-case letters do a case insensitive match + case_insensitive = (pattern == pattern.lower()) + + items = [] + already_selected = [] + to_select = [] + prefix_matches = [] + def match(m, path, iter): + name = m[iter][0] + if case_insensitive: + name = name.lower() + if fnmatch.fnmatch(name, pattern): + to_select.append(path) + elif fnmatch.fnmatch(name, pattern_star): + prefix_matches.append(path) + if self.iv.path_is_selected(path): + already_selected.append(path) + model.foreach(match) + + self.iv.unselect_all() + + cursor_path = (self.iv.get_cursor() or (None, None))[0] + + if to_select == [] and prefix_matches: + # No matches, but put the cursor on the closest + if cursor_path in prefix_matches: + to_select = [cursor_path] + else: + to_select = [prefix_matches[0]] + + if to_select: + for path in to_select: + self.iv.select_path(path) + if cursor_path not in to_select: + self.iv.set_cursor(to_select[0]) + return + @tasks.async def run(self): while True: -- 2.11.4.GIT