# Part of the A-A-P GUI IDE: Tool class for Grepping # Copyright (C) 2002-2003 Stichting NLnet Labs # Permission to copy and use this file is specified in the file COPYING. # If this file is missing you can find it here: http://www.a-a-p.org/COPYING import os.path import re import Tool from Navigator import ItemPos from GrepToolUtil.GrepToolWindow import GrepToolWindow import GrepToolUtil.GrepToolDialog import Util toollist = [] # Added to in Tool.py # TODO: do this properly with gettext(). def _(x): return x def canDoActions(item, type): """Return a dictionary that describes how well this Tool can perform actions on ActyItem "item" with type "type".""" if not (item.node or item.children): return {} return { "search": 50, } def getProperties(topmodel): """Properties that this kind of tool supports.""" return { "start_send" : 1, } def openItem(item, action, lnum = None, col = None, off = None): """Open ActyItem "item" in a newly created Tool.""" tool = GrepTool("Find text in item(s)", item, action) tool.doDialog() if not tool.what.get("text"): # Dialog was cancelled. del tool return None item.acty.topmodel.toollist.addTool(tool) return tool class GrepTool(Tool.Tool): """A Grep Tool: edit files with Grep.""" def __init__(self, name, item, action, **keyw): apply(Tool.Tool.__init__, (self, name, item, action), keyw) self.window = None # window with grep results self.what = {} # what to search for self.list = [] # list of found matches self.item = None # item that was grepped in def doDialog(self): """Open a dialog for the user to select the text to search for.""" what = GrepToolUtil.GrepToolDialog.doDialog(self.topmodel.view, self.what) # Don't use an empty text (e.g., dialog cancelled). if what.get("text"): self.what = what def doGrep(self): """Perform the grep operation on the currently selected item. The results will appear in self.list.""" self.list = [] if not self.item or not self.what.get("text"): print "Nothing to grep for!" return if self.what.get("type") == "pattern": pattern = self.what["text"] elif self.what.get("type") == "word": pattern = '\\b' + re.escape(self.what["text"]) + '\\b' else: pattern = re.escape(self.what["text"]) flags = 0 if self.what.get("case") == "ignore": flags = re.IGNORECASE try: regobj = re.compile(pattern, flags) except: print "Can't compile pattern '%s'" % pattern return # Do the grepping self.list = self.doGrepItem(self.item, regobj) # Remember the directory of the top item, other item names will be made # relative to it. self.rootdir = os.path.dirname(self.item.fullName()) if not self.rootdir: self.rootdir = os.path.dirname(self.item.parent.fullName()) # XXX update the name of the tool to reflect what was searched for in # what item: - Find "the" in SOURCE - text = self.what["text"] if len(text) > 20: text = text[:18] + ".." if self.item.parent: # Item is part of a project. name = self.item.listName() extra = " of %s" % Util.display_name(self.item.getRoot().shortName()) else: # Item is an activity itself. name = Util.display_name(self.item.shortName()) extra = '' self.setName('Search "%s" in %s%s' % (text, name, extra)) def doGrepItem(self, item, regobj): """Grep one item for the regex of "regobj".""" list = [] node = item.node if node: try: fname = node.fullName() f = open(fname) lnum = 1 off = 0 while 1: line = f.readline() if not line: break if regobj.search(line): list.append(ItemPos(item, lnum = lnum, off = off, text = line)) lnum = lnum + 1 off = off + len(line) f.close() except StandardError, e: print "Grep error: ", e # Include matches in any children of the item. if item.children: for child in item.children.getAllItems(): list.extend(self.doGrepItem(child, regobj)) return list def doShow(self): """Fill the window with the results.""" self.window.setList(self.list, self.rootdir) def getProperties(self): """Properties that this tool supports.""" return getProperties(self.topmodel) def openItem(self, item, action, lnum = None, off = None): """Open ActyItem "item" in this Tool.""" self.addItem(item) self.reload(item) def reload(self, item, node = None): """Reload the "item", it was changed elsewhere. Does not ask for new text and type.""" # Make sure the window is open. self.openWindow() # Perform the grep (again). self.item = item self.doGrep() self.doShow() def entryActivated(self, idx): """Called when an item in the list was activated by the user.""" Tool.gotoItem(self.topmodel, self.list[idx].item, lnum = self.list[idx].lnum, off = self.list[idx].off) def again(self): """Use the same item(s) again but prompt for new text.""" self.doDialog() self.reload(self.item) def close(self, shutdown): """Close the tool. Called when the node that is using this tool is being closed. Return non-zero if closing is OK.""" if self.window: # self.windowClosed() will be invoked by calling Close() self.window.Close() return 1 # can shutdown def foreground(self, item, node = None, lnum = None): """Move this Tool to the foreground, with the current activity. When "item" is not None edit this item. When "node" is not None edit this node.""" if item and item != self.item: # first time. self.reload(item) elif not self.window: self.openWindow() self.doShow() self.window.Raise() def openWindow(self): if not self.window: self.window = GrepToolWindow(None, self) def windowClosed(self): """Callback from the window handler to let us know that it's closing.""" self.window = None self.topmodel.toollist.delTool(self) for item in self.itemlist: item.delTool(self) # vim: set sw=4 et sts=4 tw=79 fo+=l: