Hi, I'm writing a gedit plugin to mimic the Ctrl+Shift+R behaviour of Eclipse. I have managed to get this to work fine with a hard coded path to search under. I could easily use a settings page to set this but I'd rather use the root path of the file browser pane and was wondering if there's an easy way to retrieve this from my plugin? Alternatively is there already a plugin to do this? I looked but couldn't find one so I thought I'd have a go. What I've done is attached. I'll do a proper release for this once I get it working properly ;-) Thanks, James -- James Pharaoh Pharaoh Systems Consulting Ltd http://phsys.co.uk/contact
Attachment:
findfile.gedit-plugin
Description: Binary data
# Find File Gedit Plugin
# Copyright (c) 2010 James Pharaoh <james phsys co uk>
from gettext import gettext as _
import gedit
import gtk
import gobject
import os
ui_str = """
<ui>
<menubar name="MenuBar">
<menu name="FileMenu" action="File">
<placeholder name="FileOps_2">
<menuitem name="FindFilePy" action="FindFilePy"/>
</placeholder>
</menu>
</menubar>
</ui>
"""
max_entries = 1000
search_dir = "/home/james/projects"
class FindFileDialog (gtk.Dialog):
def __init__ (self, window):
gtk.Dialog.__init__ (self)
self._window = window
self.connect ("destroy", self.quit)
self.connect ("delete-event", self.quit)
self.set_title (_ ("Find file"))
self.resize (600, 500)
self._model = gtk.ListStore (str)
self._scroll = gtk.ScrolledWindow ()
self._scroll.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.vbox.pack_start (self._scroll, True)
self._scroll.show ()
self._tree = gtk.TreeView (self._model)
cell = gtk.CellRendererText ()
column = gtk.TreeViewColumn ("Filename")
column.pack_start (cell, True)
column.set_attributes (cell, text = 0)
self._tree.append_column (column)
self._tree.set_headers_visible (False)
self._scroll.add (self._tree)
self._tree.show ()
self._entry = gtk.Entry ()
self.vbox.pack_start (self._entry, False)
self._entry.set_activates_default (True)
self._entry.show ()
self._entry.grab_focus ()
self._entry.connect ("changed", self.changed)
self._entry.connect ("key-press-event", self.pressed)
self._cancel = gtk.Button ("Cancel")
self._cancel.connect ("clicked", self.quit)
self.action_area.pack_start (self._cancel)
self._cancel.show ()
self._ok = gtk.Button ("Ok")
self._ok.connect ("clicked", self.ok)
self._ok.set_flags (gtk.CAN_DEFAULT)
#self._ok.grab_default ()
self.action_area.pack_start (self._ok)
self._ok.show ()
self.set_default (self._ok)
self.scan ()
self.update ()
sel = self._tree.get_selection ()
sel.select_path (0)
def scan (self):
self._files = []
os.path.walk (search_dir, self.scan_one, None)
self._files.sort ()
def scan_one (self, arg, dirname, names):
for name in names:
path = dirname + "/" + name
if not os.path.isfile (path): continue
self._files.append (path)
def changed (self, entry):
self.update ()
sel = self._tree.get_selection ()
sel.select_path (0)
def pressed (self, entry, event):
if event.keyval in [
gtk.keysyms.Up,
gtk.keysyms.Down,
gtk.keysyms.Page_Up,
gtk.keysyms.Page_Down,
gtk.keysyms.Home,
gtk.keysyms.End,
]:
sel = self._tree.get_selection ()
(model, paths) = sel.get_selected_rows ()
sel_index = paths [0] [0]
first, last = self._tree.get_visible_range ()
page_size = max (1, last [0] - first [0] - 1)
if event.keyval == gtk.keysyms.Up: sel_index -= 1
if event.keyval == gtk.keysyms.Down: sel_index += 1
if event.keyval == gtk.keysyms.Page_Up: sel_index -= page_size
if event.keyval == gtk.keysyms.Page_Down: sel_index += page_size
if event.keyval == gtk.keysyms.Home: sel_index = 0
if event.keyval == gtk.keysyms.End: sel_index = len (model) - 1
if sel_index < 0: sel_index = 0
if sel_index >= len (model): sel_index = len (model) - 1
sel_index %= len (model)
sel.select_path (sel_index)
self._tree.scroll_to_cell (sel_index)
return True
def update (self):
model = self._model.clear ()
text = self._entry.get_text ()
num = 0
for file in self._files:
dir_name, sep, file_name = file.rpartition ("/")
if file_name.find (text) == -1:
continue
self._model.append ([ file [(len (search_dir) + 1):] ])
num += 1
if num == max_entries:
break
def quit (self, *args):
self.hide ()
self.destroy ()
def ok (self, button):
sel = self._tree.get_selection ()
model, sel_iter = sel.get_selected ()
uri = "file://" + search_dir + "/" + model.get_value (sel_iter, 0)
tab = None
for doc in self._window.get_documents ():
if doc.get_uri () != uri: continue
tab = gedit.tab_get_from_document (doc)
break
if tab:
self._window.set_active_tab (tab)
else:
self._window.create_tab_from_uri (uri, None, 0, False, True)
self.hide ()
self.destroy ()
class FindFileWindowHelper:
def __init__ (self, plugin, window):
self._window = window
self._plugin = plugin
self._insert_menu ()
def deactivate (self):
self._remove_menu ()
self._window = None
self._plugin = None
def _insert_menu (self):
manager = self._window.get_ui_manager ()
self._action_group = gtk.ActionGroup ("FindFilePyPluginActions")
self._action_group.add_actions ( [
( "FindFilePy", None, _("Find..."), "<Control><Shift>R", _("Find a file by name"), self.on_find_file_activate )
] )
manager.insert_action_group (self._action_group, -1)
self._ui_id = manager.add_ui_from_string (ui_str)
def _remove_menu (self):
manager = self._window.get_ui_manager ()
manager.remove_ui (self._ui_id)
manager.remove_action_group (self._action_group)
manager.ensure_update ()
def update_ui (self):
pass
def on_find_file_activate (self, action):
dialog = FindFileDialog (self._window)
dialog.run ()
class FindFilePyPlugin (gedit.Plugin):
def __init__ (self):
gedit.Plugin.__init__ (self)
self._instances = {}
def activate (self, window):
self._instances [window] = FindFileWindowHelper (self, window)
def deactivate (self, window):
self._instances [window].deactivate ()
del self._instances [window]
def update_ui (self, window):
self._instances [window].update_ui ()