Exemple #1
0
 def init(self, raw_api):
     self.api = APIProxy(raw_api)
     self.ggbApi = APIProxy(raw_api.getGgbApi())
     self.pywin = None
     self.reinit()
Exemple #2
0
class Interface(PythonScriptInterface):
    
    def init(self, raw_api):
        self.api = APIProxy(raw_api)
        self.ggbApi = APIProxy(raw_api.getGgbApi())
        self.pywin = None
        self.reinit()
    
    def reinit(self):
        global selection
        api = self.api
        factory = self.factory = objects.ElementFactory(api)
        functions = Functions(api, factory)
        self.geo = objects.GeoNamespace(self.factory)
        selection = self.selection = objects.Selection(self.factory)
        self.init_namespace = {
            'RConnection': RConnection,
            'Color': Color,
            # Below we must assume that the GgbApi is already created.
            'ggbApplet': self.ggbApi,
            'geo': self.geo,
            'selection': self.selection,
            #'interactive': interactive,
            'input': functions.input,
            'debug': functions.debug,
            'alert': functions.alert,
            'dialog': functions.dialog,
            'command': functions.command,
            'pyfunc': functions.pyfunc,
            'sleep': time.sleep,
            'in_new_thread': in_new_thread,
            'in_main_thread': in_main_thread,
            'start_new_thread': start_new_thread,
            'run_in_main_thread': run_in_main_thread,
            'Element': objects.Element,
            '__factory__': factory,
            '__api__': api,
        }
        for obj in objects.__objects__:
            self.init_namespace[obj.__name__] = getattr(factory, obj.__name__)
        self.init_namespace['Intersect'] = factory.Intersect
        self.init_namespace.update(objects.unary_functions(self.factory))
        self.reset_namespace()
        self.handling_event = False
        self.event_listeners = defaultdict(list)

    def reset_namespace(self):
        self.namespace = {}
        self.namespace.update(self.init_namespace)
    
    def execute(self, script):
        self.run(script)
    
    def show_traceback(self, header, skip_lines=None):
        sys.stderr.write(header)
        if self.pywin is not None:
            self.pywin.error(header)
            tb_lines = traceback.format_exception(*sys.exc_info())
            if skip_lines is not None:
                tb_lines = tb_lines[skip_lines:]
            self.pywin.error("".join(tb_lines))
    
    def handleEvent(self, evt_type, target):
        # if ... return and try ... finally are hacks to try to fix #1520
        # I can't run ATM so...
        label = API.Geo.getLabel(target)
        # print "1.", evt_type, label
        if label is not None:
            for listener in self.event_listeners[evt_type]:
                try:
                    listener(evt_type, target)
                except Exception:
                    self.show_traceback("Error while running listener for %s" % evt_type)
        if self.handling_event:
            return
        cached = target in self.factory._cache
        # print "2.", evt_type, label, cached
        if cached or (label and evt_type == 'add'):
            element = self.factory.get_element(target)
            try:
                action = getattr(element, "on" + evt_type)
            except AttributeError:
                if evt_type == 'add' and not cached:
                    del self.factory._cache[target]
                return
        else:
            return
        # print "3.", evt_type, element.label
        try:
            self.handling_event = True
            action()
        except Exception:
            header = "Error while handling event '%s' on '%r'\n" % (evt_type, target)
            self.show_traceback(header, 2)
            raise
        finally:
            if evt_type == 'remove':
                del self.factory._cache[target]
            self.handling_event = False
        
    def notifySelected(self, geo, add):
        # geo = API.Geo(geo)
        if self.selection_listener:
            el = self.factory.get_element(geo)
            self.selection_listener.send(el, add)
            if self.selection_listener.done:
                self.remove_selection_listener()
        else:
            # We shouldn't get here :)
            self.remove_selection_listener()
    
    def get_pywin(self):
        if self.pywin is None:
            from pygeo import gui
            self.pywin = gui.PythonWindow(self.api)
        return self.pywin
    
    def toggleWindow(self):
        self.get_pywin().toggle_visibility()
    
    def isWindowVisible(self):
        return False
        return self.pywin is not None and self.pywin.frame.visible

    def setEventHandler(self, geo, evt, code):
        el = self.factory.get_element(geo)
        print "Setting event listener for", el.label
        if not code.strip():
            try:
                delattr(el, "on" + evt)
            except AttributeError:
                pass
            return
        code = pythonify(code)
        code = "\n".join("\t" + line for line in code.split("\n"))
        code = "def __handle_event__(self=__el__):\n%s" % code
        try:
            self.namespace['__el__'] = el
            handler_def = compile(code, "<%s %s>" % (evt, el.label), 'exec')
            exec handler_def in self.namespace
            setattr(el, "on" + evt, self.namespace['__handle_event__'])
            del self.namespace['__handle_event__']
        except SyntaxError:
            header = "Error while compiling '%s' action for '%s'" % (evt, geo)
            self.show_traceback(header)
            raise
        finally:
            del self.namespace['__el__']

    def removeEventHandler(self, geo, evt):
        if geo not in self.factory._cache:
            return
        el = self.factory.get_element(geo)
        print "Removing event listener for", el.label
        try:
            delattr(el, "on" + evt)
        except AttributeError:
            pass
    
    def reset(self):
        # Make sure all objects are fresh
        reload(objects)
        # Refresh the namespace and stuff as well
        self.reinit()
        # Reset the Python Window if it's up
        if self.pywin is not None:
            self.pywin.reset()
    
    def runInitScript(self):
        # Run the init script and run ggbOnInit() if it exists
        self.run(self.api.getInitScript() +
                 "if 'ggbOnInit' in globals():"
                 "    ggbOnInit()"
        )
    
    def getCurrentInitScript(self):
        if self.pywin is None:
            return None
        return self.pywin.get_current_script()
    
    def addEventListener(self, evt, listener):
        self.event_listeners[evt].append(listener)
    
    def removeEventListener(self, evt, listener):
        self.event_listeners[evt].remove(listener)
        
    def set_selection_listener(self, sl):
        self.api.startSelectionListener()
        self.selection_listener = sl
    
    def remove_selection_listener(self):
        self.api.stopSelectionListener();
        self.selection_listener = None

    def format_source(self, source):
        if isinstance(source, basestring):
            return pythonify(source)
        else:
            return source
    
    def compileinteractive(self, source):
        source = self.format_source(source)
        return compile(source, "<pyggb>", "single")
    
    def compilemodule(self, source):
        source = self.format_source(source)
        return compile(source, "<pyggb>", "exec")

    def compile_im(self, source):
        source = self.format_source(source)
        try:
            code = self.compileinteractive(source)
        except SyntaxError:
            try:
                code = self.compilemodule(source)
            except SyntaxError, e:
                raise e
        return code