# Part of the A-A-P GUI IDE: Tool class for Boa # 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 import time import Util import RecPython from Tool import Tool # TODO: do this properly with gettext(). def _(x): return x boa_app_started = 0 # Boa was started. toollist = [] # Added to in Tool.py 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: return {} if type == "python" and boa_exists(): return { "edit" : 80, "view" : 80, "debug" : 80, } if type in [ "png", "gif" ] and boa_exists(): return { "view" : 20, } return {} boa_found = -1 # 0 when check didn't find it, 1 when it exists. def boa_exists(): """Check if there is a boa program somewhere.""" global boa_found if boa_found < 0: if RecPython.program_path("boa"): boa_found = 1 else: boa_found = 0 return boa_found def getProperties(topmodel): """Properties that this kind of tool supports.""" return { "mdi" : 1, "one_instance" : 1, "open_url" : [ "http", "ftp" ], "set_position" : 1, } def openItem(item, action, lnum = None, col = None, off = None): """Open ActyItem "item" in this Tool. Creat a new Tool when there isn't one yet, otherwise return the existing one. We never create a second Boa.""" if toollist: print "Trying to start Boa Twice!" return None # Safety: Can only start one. return BoaTool("Python editor", item, action, lnum = lnum, col = col, off = off) class BoaTool(Tool): def __init__(self, *args, **keyw): apply(Tool.__init__, (self,) + args, keyw) self.starttime = 0 self.lastname = '' 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.action = action def reload(self, item, node = None): """Reload the "item", it was changed elsewhere.""" # XXX todo self.openItem(item, self.action) def close(self, shutdown): """Close the tool. Return non-zero if closing is OK.""" global boa_app_started if boa_app_started: # TODO: tell Boa to quit if there are no changed files boa_app_started = 0 self.topmodel.toollist.delTool(self) return 1 # can shutdown def goto(self, item, node = None, lnum = None, col = None, off = None): """goto position "lnum"/"col" or "off" in "item".""" self.foreground(item, node, lnum = lnum) def foreground(self, item, node = None, lnum = None): """Move this tool to the foreground.""" if item: self.setCurrentItem(item) # Edit a specific item, if specified. if item: node = item.node if node: self.editfile(node.fullName(), lnum = lnum) # TODO: Bring Boa to the foreground # TODO: select the editor for the current activityitem. def editfile(self, name, lnum = None): """Edit a file with Boa. This also starts Boa if necessary.""" if lnum: # Boa supports the form :: boa_name = name + ("::%d" % lnum) else: boa_name = name file_created = 0 if not os.path.exists(name): # The file does not exist yet. Since Boa can't edit a new file, # create it, start Boa and delete it again. try: os.close(os.open(name, os.O_WRONLY + os.O_CREAT + os.O_EXCL, 0644)) file_created = 1 except StandardError, e: # XXX better error handling print "Cannot create '%s': %s" % (name, str(e)) # We don't know if a Boa is running, just try connecting to it and fail # if there isn't one. # Since Boa takes several seconds to startup, only try starting one # every ten seconds (otherwise you end up with several Boas!). while 1: res = self.sendToRunningBoa(boa_name) if res or time.time() > self.starttime + 10: break time.sleep(1) if not res: # Sending didn't work, try running a new Boa. self.starttime = time.time() Util.async_system([], None, '{quiet} boa "%s"' % name) self.lastname = name if file_created: # wait for Boa to have started up time.sleep(3) if file_created: try: time.sleep(0.2) # wait for Boa to open the file os.unlink(name) except StandardError, e: # XXX better error handling print "Cannot delete '%s': %s" % (name, str(e)) global boa_app_started boa_app_started = 1 def sendToRunningBoa(self, name, host='127.0.0.1', port=50007): """Send the names (URLs) of files to a running Boa through a socket. Taken from Boa.py.""" # Don't open the same file twice, Boa might run into trouble. if name == self.lastname: return 1 self.lastname = name import socket try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(name) s.close() except socket.error: return 0 # failed else: return 1 # success # vim: set sw=4 et sts=4 tw=79 fo+=l: