Beispiel #1
0
class ModEditComponent:

    __metaclass__ = edef.Singleton
    def __init__(self):
        self._controller = Controller()
        self._model      = Model()

        self._model.registerProtocol("mod", ModModel())
        self._controller.registerEditorClass("mod", ModuleEditor)
        self._module_tree = self._controller.addNavigatorClass( ModuleTreePanel ).getModuleTree()

    def getModuleTree(self): return self._module_tree
Beispiel #2
0
    def __init__(self):
        self._controller = Controller()
        self._model      = Model()

        self._model.registerProtocol("mod", ModModel())
        self._controller.registerEditorClass("mod", ModuleEditor)
        self._module_tree = self._controller.addNavigatorClass( ModuleTreePanel ).getModuleTree()
    def __init__(self, parent, ID):
        wx.TreeCtrl.__init__(self, parent, ID, size=wx.Size(-1,-1),
                             style=wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_FULL_ROW_HIGHLIGHT)
        
        self._d_imgs = wx.ImageList(16,16)
        self._bmp_class = self._d_imgs.Add( wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)) )
        self._bmp_class_open = self._d_imgs.Add( wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)) )
        self._bmp_module = self._d_imgs.Add( getModuleBitmap() )
        self.SetImageList(self._d_imgs)

        self._d_model = Model()
        self._d_controller = Controller()
        self._d_mainframe  = self._d_controller.getMainFrame()
        self._logger = self._d_controller.getLogger()

        self._d_root = self.AddRoot("root")
        self.SetPyData(self._d_root, ("Class","mod:/") )

        mods = self._d_model.openURI("mod://")
        self.popClasses(mods)

        self._left_down_uri = None

        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelection)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate)
        self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMove)
class CircuitDropTarget(wx.TextDropTarget):
    def __init__(self, editor):
        wx.TextDropTarget.__init__(self)
        self._editor = editor
        self._model  = Model()
    
    #FIXME use OnDragOver() to check if there can a module be placed

    def OnDropText(self, x, y, uri):
        if not self._model.checkURI(uri):
            raise Exception("Unknown module %s"%uri)
        if not re.match("^mod://",uri):
            raise Exception("Can only place modules here!")
        (x,y) = self._editor._convertCoords( (x,y) )
        self._editor.loadModule(uri, x, y)
    def __init__(self, parent, ID):
        wx.TreeCtrl.__init__(self, parent, ID, size=wx.Size(-1,-1),
                             style=wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_FULL_ROW_HIGHLIGHT)
        
        self._d_imgs = wx.ImageList(16,16)
        self._bmp_class = self._d_imgs.Add( getArchiveBitmap() )
        self._bmp_class_open = self._d_imgs.Add( getArchiveBitmap() )
        self._bmp_module = self._d_imgs.Add( getPythonBitmap() )
        self.SetImageList(self._d_imgs)

        self._d_model = Model()
        self._d_controller = Controller()
        self._d_mainframe = self._d_controller.getMainFrame()

        self._d_root = self.AddRoot("root")
        self.SetPyData(self._d_root, (None,None))
        self._logger = self._d_controller.getLogger()


        #Add all archives:
        archives = self._d_model.openURI("zip://")
        for archive_uri in archives:
            uri_list = self._d_model.openURI(archive_uri)
            archive_name = getArchive(archive_uri)
            arch_item = self.AppendItem(self._d_root, archive_name)
            self.SetPyData(arch_item, ("Archive", archive_uri) )
            self.SetItemImage(arch_item, self._bmp_class, wx.TreeItemIcon_Normal)
            self.SetItemImage(arch_item, self._bmp_class_open, wx.TreeItemIcon_Expanded)

            for file_uri in uri_list:
                file_name = getPyFile(file_uri)
                file_item = self.AppendItem(arch_item, file_name)
                self.SetPyData(file_item, ("File", file_uri))
                self.SetItemImage(file_item, self._bmp_module, wx.TreeItemIcon_Normal)
                self.SetItemImage(file_item, self._bmp_module, wx.TreeItemIcon_Expanded)
        
        # FIXME self._d_mainframe.bindNewArch(self.NewArchive)

        # Events:
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelection)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate)
        self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
    def __init__(self, parent, ID, uri):
        EditorInterface.__init__(self, parent, False, uri)
        ElementMap.__init__(self, parent, ID)

        self._controller = Controller()
        self._logger     = self._controller.getLogger()
        self._model      = Model()
        self._circtree   = ComponentManager().getComponent("circuit").getCircuitTree()
        self._importer   = edef.Importer()
        self._mainframe  = self._controller.getMainFrame()
        
        self.setTitle(uri)
       
        if not uri == "circ://":
            self._loadCircuit(uri)
            self.redraw()
            self.setModified(False)

        self._target = CircuitDropTarget(self)
        self.SetDropTarget( self._target )
    def __init__(self, parent, ID, uri):
        ScrolledPanel.__init__(self, parent, ID)
        eDevEditorInterface.__init__(self, parent, False, uri)

        self._controller = Controller()
        self._model      = Model()
        self._mainframe  = self._controller.getMainFrame()
        self._component_manager = ComponentManager()
        self._moduletree = self._component_manager.getComponent("modeditor").getModuleTree()
        self._notebook   = self._controller.getNotebook()


        if uri == "mod://":
            txt = '<?xml version="1.0"?><Module version="1.0"/>'
            title = "unsaved"
        else:
            txt = self._model.openURI(uri)
            title = getModuleName(uri)
        self.setTitle(title)
        
        self._d_doc = xml.dom.minidom.parseString(txt)

        vert_box = wx.BoxSizer(wx.VERTICAL)
        self._d_basic_data = eDevModuleEditorBasic(self, -1, self._d_doc)
        self._d_require = eDevModuleEditorRequire(self, -1, self._d_doc)
        self._d_provide = eDevModuleEditorProvide(self, -1, self._d_doc)

        self.Bind(Events.EVT_MODIFIED, self.OnModified, self._d_basic_data)
        self.Bind(Events.EVT_MODIFIED, self.OnModified, self._d_require)
        self.Bind(Events.EVT_MODIFIED, self.OnModified, self._d_provide)

        vert_box.Add(self._d_basic_data, 0, wx.EXPAND|wx.ALL, 15)
        vert_box.Add(self._d_require, 0, wx.EXPAND|wx.ALL, 15)
        vert_box.Add(self._d_provide, 0, wx.EXPAND|wx.ALL, 15)

        self.SetSizer(vert_box)
        self.SetAutoLayout(1)
        self.SetupScrolling()
Beispiel #8
0
    def __init__(self, parent, ID):
        wx.Dialog.__init__(self,parent, ID, title="Save circuit as")

        self._model = Model()

        box = wx.BoxSizer(wx.VERTICAL)

        dlg_txt = """<font size="14">Enter new (full) circuit name.</font>
            For example "class.subclass.name". A class or circuit name
            can only contain a-z, A-Z, 0-9 and _."""

        txt = StaticFancyText(self, -1, dlg_txt)
        box.Add(txt, 0, wx.ALL, 10)

        self._name = wx.TextCtrl(self, -1)
        box.Add(self._name, 1, wx.EXPAND|wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT|wx.BOTTOM, 20)

        bbox = self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL)
        box.Add(bbox, 1, wx.ALIGN_CENTER|wx.ALL, 10)

        self.SetSizer(box)
        box.Fit(self)

        self.Bind(wx.EVT_BUTTON, self.OnOk, id=wx.ID_OK)
class CircuitTree(wx.TreeCtrl):
    
    def __init__(self, parent, ID):
        wx.TreeCtrl.__init__(self, parent, ID, size=wx.Size(-1,-1),
                             style=wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_FULL_ROW_HIGHLIGHT)
        
        self._d_imgs = wx.ImageList(16,16)
        self._bmp_class = self._d_imgs.Add( wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)) )
        self._bmp_class_open = self._d_imgs.Add( wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)) )
        self._bmp_module = self._d_imgs.Add( getCircuitBitmap() )
        self.SetImageList(self._d_imgs)

        self._d_model = Model()
        self._d_controller = Controller()
        self._d_mainframe  = self._d_controller.getMainFrame()
        self._logger = self._d_controller.getLogger()

        self._d_root = self.AddRoot("root")
        self.SetPyData(self._d_root, ("Class","circ:/") )

        circs = self._d_model.openURI("circ://")
        self.popClasses(circs)

        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelection)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate)
        self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)


    def popClasses(self, circs, item=None):
        if item == None:
            item = self._d_root
        (typ, prefix) = self.GetPyData(item)
        
        def class_filter(uri): return re.match("^%s/\w+/.+$"%prefix, uri)
        circuits = filter(class_filter, circs)
        for circ_uri in circuits:
            m = re.match("^%s/(\w+)/.+$"%prefix, circ_uri)
            class_name = m.group(1)
            uri = "%s/%s"%(prefix,class_name)
            
            if self.hasClassURI(uri, self._d_root):
                citem = self.getItemByURI(uri, self._d_root)
                self.popCircuits(circs,citem)
                continue
            
            citem = self.AppendItem(item, class_name)
            self.SetPyData(citem, ("Class", uri) )
            self.SetItemImage(citem, self._bmp_class, wx.TreeItemIcon_Normal)
            self.SetItemImage(citem, self._bmp_class_open, wx.TreeItemIcon_Expanded)
            self.popClasses(circs, citem)

        self.popCircuits(circs, item)


    def popCircuits(self, circs, item=None):
        if item == None:
            item = self._d_root

        (typ, prefix) = self.GetPyData(item)
        def circuit_filter(uri): return re.match("^%s/(\w+)$"%prefix, uri)
        circuits = filter(circuit_filter, circs)
        for circuit in circuits:
            if self.hasURI(circuit, self._d_root): continue
            m = re.match("^%s/(\w+)"%prefix, circuit)
            circ_name = m.group(1)
            citem = self.AppendItem(item, circ_name)
            self.SetPyData(citem, ("Circuit", circuit) )
            self.SetItemImage(citem, self._bmp_module, wx.TreeItemIcon_Normal)
            self.SetItemImage(citem, self._bmp_module, wx.TreeItemIcon_Expanded)
   

    def addURI(self, uri):
        if self.hasURI(uri,self._d_root): return
        (proto, path) = Tools.splitURI(uri)
        if not proto == "circ": return
        self.popClasses([uri])


    def deleteURI(self, uri):
        if not self.hasURI(uri, self._d_root): return
        
        item = self.getItemByURI(uri, self._d_root)
        if self.ItemHasChildren(item): return
        
        (typ, iuri) = self.GetPyData(item)
        if iuri == "circ:/": return
        self.Delete(item)
        
        pitem = self.GetItemParent(item)
        (typ, uri) = self.GetPyData(pitem)
        self.deleteURI(uri)
   

    def hasURI(self, uri, item):
        if self.getItemByURI(uri, item): return True
        return False

    def getItemByURI(self, uri, item, cookie=None):
        if not item: return None
        (typ, iuri) = self.GetPyData(item)
        if iuri == uri: return item
        
        citem = self.GetFirstChild(item)
        if citem: (citem, ncookie) = citem
        ret = self.getItemByURI(uri, citem, ncookie)
        if ret: return ret

        item = self.GetNextSibling(item)
        return self.getItemByURI(uri, item, cookie)


    def hasClassURI(self, uri, item, cookie=None):
        if not item: return False
        (typ, iuri) = self.GetPyData(item)
        if iuri == uri and typ=="Class": return True
        
        citem = self.GetFirstChild(item)
        if citem: (citem, ncookie) = citem
        if self.hasClassURI(uri, citem, ncookie): return True

        item = self.GetNextSibling(item)
        if self.hasClassURI(uri, item): return True
        return False
    

    #
    # CONTROLLER PART:
    #
    def OnFocus(self, evt):
        self._updateMainFrame()
        evt.Skip()


    def OnSelection(self, evt):
        item = evt.GetItem()
        self._updateMainFrame(item)
        evt.Skip()


    def _updateMainFrame(self, item=None):
        if not item: item = self.GetSelection()
        self._d_mainframe.bindNew()
        self._d_mainframe.bindOpen()
        self._d_mainframe.bindDelete()
        
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ == "Circuit":
            self._d_mainframe.bindOpen(self.OnCircuitOpen, "&Open circuit")
            self._d_mainframe.bindDelete(self.OnCircuitDelete, "&Delete circuit")
        elif typ == "Class":
            self._d_mainframe.bindOpen(self.OnClassOpen, "&Open class")
        self._d_mainframe.bindNew(self.OnNewCircuit, "&New circuit")

    def OnActivate(self, evt):
        item = evt.GetItem()
        (typ, uri) = self.GetPyData(item)
        if typ == "Class":
            self.Toggle(item)
            return
        self._d_controller.DocumentOpen(uri)

    def OnCircuitOpen(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ=="Circuit":
            self._d_controller.DocumentOpen(uri)

    def OnClassOpen(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ == "Class":
            self.Expand(item)

    def OnNewCircuit(self, evt=None):
        self._d_controller.DocumentOpen("circ://")

    def OnCircuitDelete(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ == "Class": return

        self._d_controller.DocumentDelete(uri)
        self.deleteURI(uri)
class eDevModuleEditor(ScrolledPanel, eDevEditorInterface):
    _d_txt  = None

    def __init__(self, parent, ID, uri):
        ScrolledPanel.__init__(self, parent, ID)
        eDevEditorInterface.__init__(self, parent, False, uri)

        self._controller = Controller()
        self._model      = Model()
        self._mainframe  = self._controller.getMainFrame()
        self._component_manager = ComponentManager()
        self._moduletree = self._component_manager.getComponent("modeditor").getModuleTree()
        self._notebook   = self._controller.getNotebook()


        if uri == "mod://":
            txt = '<?xml version="1.0"?><Module version="1.0"/>'
            title = "unsaved"
        else:
            txt = self._model.openURI(uri)
            title = getModuleName(uri)
        self.setTitle(title)
        
        self._d_doc = xml.dom.minidom.parseString(txt)

        vert_box = wx.BoxSizer(wx.VERTICAL)
        self._d_basic_data = eDevModuleEditorBasic(self, -1, self._d_doc)
        self._d_require = eDevModuleEditorRequire(self, -1, self._d_doc)
        self._d_provide = eDevModuleEditorProvide(self, -1, self._d_doc)

        self.Bind(Events.EVT_MODIFIED, self.OnModified, self._d_basic_data)
        self.Bind(Events.EVT_MODIFIED, self.OnModified, self._d_require)
        self.Bind(Events.EVT_MODIFIED, self.OnModified, self._d_provide)

        vert_box.Add(self._d_basic_data, 0, wx.EXPAND|wx.ALL, 15)
        vert_box.Add(self._d_require, 0, wx.EXPAND|wx.ALL, 15)
        vert_box.Add(self._d_provide, 0, wx.EXPAND|wx.ALL, 15)

        self.SetSizer(vert_box)
        self.SetAutoLayout(1)
        self.SetupScrolling()


    def OnModified(self, evt):
        #print "Something was modified"
        self.setModified()
        event = Events.PageModifiedEvent(Events._event_modified, self.GetId())
        event.SetPage(self)
        self.GetEventHandler().ProcessEvent(event)
        evt.Skip()
        self._updateMainFrame()

    
    def OnSelected(self):
        self._updateMainFrame()

    
    def _updateMainFrame(self):
        self._mainframe.bindCopy()
        self._mainframe.bindCut()
        self._mainframe.bindPaste()
        self._mainframe.bindRedo()
        self._mainframe.bindUndo()

        self._mainframe.bindSaveAs(self.OnSaveAs)
        if self.isModified() and self.getURI() != "mod://":
            self._mainframe.bindSave(self.OnSave)
        else: self._mainframe.bindSave()


    def _toXML(self):
        impl = xml.dom.minidom.getDOMImplementation()
        dom  = impl.createDocument(None, "Module", None)
        dom.documentElement.setAttribute("version","1.0")
        
        node_list = self._d_basic_data.ToXML(dom)
        
        node_list += self._d_require.ToXML(dom)
        
        node_list += self._d_provide.ToXML(dom)
        
        for node in node_list:
            dom.documentElement.appendChild(node)

        return dom.toprettyxml("    ")


    def OnSave(self, evt=None):
        if self.getURI() == "mod://": return
        
        txt = self._toXML()
        self._controller.DocumentSave(self.getURI(),txt)
        self.setModified(False)
        self._updateMainFrame()


    def OnSaveAs(self, evt=None):
        selected = False
        while not selected:
            dlg = Dialogs.eDevSaveModuleAsDialog(self, -1)
            if dlg.ShowModal() != wx.ID_OK:
                return
            uri = "mod://%s"%dlg.getSelection()
            dlg.Destroy()
            if self._model.checkURI(uri):
                # FIXME Override?
                continue
            selected = True
        
        if not self._model.checkURI(uri):
            self._controller.DocumentSave(uri, self._toXML())
            self._moduletree.addURI(uri)
        else:
            self._controller.DocumentSave(uri, self._toXML())
        self.setURI(uri)
        self.setTitle( getModuleName(uri) )
class PythonEditor(stc.StyledTextCtrl, EditorInterface):
    def __init__(self, parent, ID, uri):
        stc.StyledTextCtrl.__init__(self, parent, ID, style=0)

        if uri == "zip://":
            modified = True
            title = "unsaved"
        else:
            modified = False
            (aname, title) = splitPyFile(uri)

        EditorInterface.__init__(self, parent, False, uri)
        self.setTitle(title)

        self._d_config = Config()

        self._d_controller = Controller()
        self._logger = self._d_controller.getLogger()
        self._d_mainframe = self._d_controller.getMainFrame()
        self._d_model = Model()
        self._d_notebook = self._d_controller.getNotebook()
        self._pyedit_component = ComponentManager().getComponent("pyeditor")
        self._archive_tree = self._pyedit_component.getArchiveTree()

        self.SetLexer(stc.STC_LEX_PYTHON)
        self.SetKeyWords(0, " ".join(keyword.kwlist))

        # config:
        font = self._d_config.getEditorFont()
        fsize = self._d_config.getEditorFontSize()
        sdfsize = self._d_config.getEditorSecondFontSize()
        faces = {"times": font, "mono": font, "helv": font, "other": font, "size": fsize, "size2": sdfsize}

        self.SetTabWidth(self._d_config.getEditorTabSpace())
        self.SetUseTabs(not self._d_config.getEditorExpandTab())

        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
        self.StyleClearAll()  # Reset all to be like the default

        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
        self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")

        self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_OPERATOR, "bold,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
        self.SetCaretForeground("BLUE")

        if isPyFileURI(uri):
            text = self._d_model.openURI(uri)
        else:
            text = ""
        self.SetText(text)
        self.EmptyUndoBuffer()
        self.Colourise(0, -1)

        self.Bind(stc.EVT_STC_CHANGE, self.OnModified)

    def OnModified(self, evt):
        if self.isModified():
            return
        self.setModified()
        event = Events.PageModifiedEvent(Events._event_page_modified, self.GetId())
        event.SetPage(self)
        self.GetEventHandler().ProcessEvent(event)
        self._updateMainFrame()
        # evt.Skip()

    def OnSelected(self, evt=None):
        self._updateMainFrame()

    def _updateMainFrame(self):
        self._d_mainframe.bindRedo()
        self._d_mainframe.bindUndo()
        self._d_mainframe.bindSave()
        self._d_mainframe.bindSaveAs()
        self._d_mainframe.bindCopy()
        self._d_mainframe.bindCut()
        self._d_mainframe.bindPaste()

        if self.CanRedo():
            self._d_mainframe.bindRedo(self.OnRedo)
        if self.CanUndo():
            self._d_mainframe.bindUndo(self.OnUndo)
        self._d_mainframe.bindCopy(self.OnCopy)
        self._d_mainframe.bindCut(self.OnCut)
        if self.CanPaste():
            self._d_mainframe.bindPaste(self.OnPaste)

        self._d_mainframe.bindSaveAs(self.OnSaveAs)
        if self.isModified() and self.getURI() != "zip://":
            self._d_mainframe.bindSave(self.OnSave)

    def OnSaveAs(self, evt=None):
        selected = False
        while not selected:
            dlg = Dialogs.eDevSaveAsDialog(self, -1)
            if dlg.ShowModal() != wx.ID_OK:
                return
            uri = "zip://%s/%s" % dlg.getSelection()
            dlg.Destroy()
            if self._d_model.checkURI(uri):
                # FIXME Override?
                continue
            selected = True

        if not self._d_model.checkURI(uri):
            self._d_controller.DocumentSave(uri, self.GetText())
            self._archive_tree.addURI(uri)
        else:
            self._d_controller.DocumentSave(uri, self.GetText())
        self.setURI(uri)
        self._logger.debug("rename to " + uri)
        self._d_notebook.setPageTitleByURI(uri, getPyFile(uri))

    def OnSave(self, evt=None):
        txt = self.GetText()
        try:
            self._d_controller.DocumentSave(self.getURI(), txt)
            self.setModified(False)
        finally:
            self._updateMainFrame()

    def OnCopy(self, evt=None):
        self.Copy()
        self._updateMainFrame()

    def OnCut(self, evt=None):
        self.Cut()
        self._updateMainFrame()

    def OnPaste(self, evt=None):
        self.Paste()
        self._updateMainFrame()

    def OnRedo(self, evt=None):
        self.Redo()
        self._updateMainFrame()

    def OnUndo(self, evt=None):
        self.Undo()
        self._updateMainFrame()
 def __init__(self, editor):
     wx.TextDropTarget.__init__(self)
     self._editor = editor
     self._model  = Model()
    def __init__(self, parent, ID, uri):
        stc.StyledTextCtrl.__init__(self, parent, ID, style=0)

        if uri == "zip://":
            modified = True
            title = "unsaved"
        else:
            modified = False
            (aname, title) = splitPyFile(uri)

        EditorInterface.__init__(self, parent, False, uri)
        self.setTitle(title)

        self._d_config = Config()

        self._d_controller = Controller()
        self._logger = self._d_controller.getLogger()
        self._d_mainframe = self._d_controller.getMainFrame()
        self._d_model = Model()
        self._d_notebook = self._d_controller.getNotebook()
        self._pyedit_component = ComponentManager().getComponent("pyeditor")
        self._archive_tree = self._pyedit_component.getArchiveTree()

        self.SetLexer(stc.STC_LEX_PYTHON)
        self.SetKeyWords(0, " ".join(keyword.kwlist))

        # config:
        font = self._d_config.getEditorFont()
        fsize = self._d_config.getEditorFontSize()
        sdfsize = self._d_config.getEditorSecondFontSize()
        faces = {"times": font, "mono": font, "helv": font, "other": font, "size": fsize, "size2": sdfsize}

        self.SetTabWidth(self._d_config.getEditorTabSpace())
        self.SetUseTabs(not self._d_config.getEditorExpandTab())

        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
        self.StyleClearAll()  # Reset all to be like the default

        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
        self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")

        self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_OPERATOR, "bold,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
        self.StyleSetSpec(stc.STC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
        self.SetCaretForeground("BLUE")

        if isPyFileURI(uri):
            text = self._d_model.openURI(uri)
        else:
            text = ""
        self.SetText(text)
        self.EmptyUndoBuffer()
        self.Colourise(0, -1)

        self.Bind(stc.EVT_STC_CHANGE, self.OnModified)
class CircuitEditor(EditorInterface, ElementMap):
    
    def __init__(self, parent, ID, uri):
        EditorInterface.__init__(self, parent, False, uri)
        ElementMap.__init__(self, parent, ID)

        self._controller = Controller()
        self._logger     = self._controller.getLogger()
        self._model      = Model()
        self._circtree   = ComponentManager().getComponent("circuit").getCircuitTree()
        self._importer   = edef.Importer()
        self._mainframe  = self._controller.getMainFrame()
        
        self.setTitle(uri)
       
        if not uri == "circ://":
            self._loadCircuit(uri)
            self.redraw()
            self.setModified(False)

        self._target = CircuitDropTarget(self)
        self.SetDropTarget( self._target )


    def _loadCircuit(self, uri):
        wire_list = []
        mod_table = {}
        self._logger.debug("Load %s"%uri)
        
        xml = self._model.openURI(uri)
        meta = CircuitMeta(xml)
        mods = meta.getModules()
        
        for (ID, (name, label, (x,y), params)) in mods.items():
            self._logger.debug("Load module %s as %s @ %s,%s"%(name, label, x,y))
            moduri = "mod://"+"/".join(name.split("."))
            mod_table[ID] = self.loadModule(moduri, x,y, params)
            mod_table[ID].setLabel(label)
            wire_list += meta.getWires(ID)
            
        for ( frm, to ) in wire_list:
            (frm_id, frm_pin) = frm
            (to_id,  to_pin)  = to
            frm = mod_table[frm_id].getPin(frm_pin)
            to  = mod_table[to_id].getPin(to_pin)
            self.connect(frm,to)
         

    def OnSelected(self, evt=None):
        self._updateMainFrame()


    def _updateMainFrame(self):
        self._mainframe.bindCopy()
        self._mainframe.bindCut()
        self._mainframe.bindPaste()
        self._mainframe.bindRedo()
        self._mainframe.bindUndo()
        
        self._mainframe.bindSaveAs(self.OnSaveAs)
        if self.isModified() and self.getURI() != "circ://":
            self._mainframe.bindSave(self.OnSave)
        else: self._mainframe.bindSave()


    def OnModified(self):
        self.setModified(True)
        self._updateMainFrame()
        

    def OnSave(self, evt):
        self._logger.debug("On save...")
        
        if self.getURI() == "circ://":
            self.OnSaveAs(evt)
            return
                    
        txt = self._to_xml().toprettyxml(" ")
        self._model.saveURI(self.getURI(), txt)
        self.setModified(False)
        self._updateMainFrame()


    def OnSaveAs(self, evt):
        dlg = SaveAsDialog(self, -1)
        if dlg.ShowModal()==wx.ID_CANCEL:
            dlg.Destroy()
            return
        uri = dlg.getSelection()
        dlg.Destroy()

        try:
            txt = self._to_xml().toprettyxml("  ")
            self._model.saveURI(uri, txt)
        except:
            showExceptionDialog(self, -1, "Unable to save file to %s"%uri)

        self.setURI(uri)
        self.setTitle(uri)
        self._circtree.addURI(uri)
        self.setModified(False)
        self._updateMainFrame()


    def _to_xml(self):
        dom_impl = getDOMImplementation()

        doc = dom_impl.createDocument(None, "Circuit", None)
        root = doc.documentElement

        mods = self.getObjects(gModule)
        for idx in range(len(mods)):
            mod = mods[idx]
            mod_node = mod._to_xml(doc, idx)
            cons = self.getConnectionsFrom(mod)
            for con in cons:
                to_pin = con.getTo().getName()
                frm_pin = con.getFrom().getName()
                to_idx = mods.index(con.getTo().getModule())
                wire = doc.createElement("Wire")
                frm = doc.createElement("From")
                frm.setAttribute("id", str(idx))
                frm.setAttribute("pin",frm_pin)
                wire.appendChild(frm)
                to = doc.createElement("To")
                to.setAttribute("id", str(to_idx))
                to.setAttribute("pin", to_pin)
                wire.appendChild(to)
                root.appendChild(wire)
            root.appendChild(mod_node)
        return doc
Beispiel #15
0
class SaveAsDialog(wx.Dialog):
    def __init__(self, parent, ID):
        wx.Dialog.__init__(self,parent, ID, title="Save circuit as")

        self._model = Model()

        box = wx.BoxSizer(wx.VERTICAL)

        dlg_txt = """<font size="14">Enter new (full) circuit name.</font>
            For example "class.subclass.name". A class or circuit name
            can only contain a-z, A-Z, 0-9 and _."""

        txt = StaticFancyText(self, -1, dlg_txt)
        box.Add(txt, 0, wx.ALL, 10)

        self._name = wx.TextCtrl(self, -1)
        box.Add(self._name, 1, wx.EXPAND|wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT|wx.BOTTOM, 20)

        bbox = self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL)
        box.Add(bbox, 1, wx.ALIGN_CENTER|wx.ALL, 10)

        self.SetSizer(box)
        box.Fit(self)

        self.Bind(wx.EVT_BUTTON, self.OnOk, id=wx.ID_OK)


    def validate(self, name):
        if not re.match("^[\w\_]+[\.[\w\_]+]*$", name): return False
        return True


    def circuitExists(self, name):
        uri = "circ://"+"/".join( name.split(".") )
        if self._model.checkURI(uri):
            return True
        return False


    def getSelection(self):
        # FIXME maybe we will return the uri
        return "circ://"+"/".join(self._name.GetValue().split("."))


    def OnOk(self, evt):
        name = self._name.GetValue()

        if not self.validate(name):
            wx.MessageBox("Invalid circuit name.\n"+
                           "The name should only constists of [a-zA-Z0-9_] "+
                           "seperated by dots!",
                          "Invalid circuit name", wx.OK|wx.ICON_ERROR, self, -1)
            return              
        
        if self.circuitExists(name):
            ret = wx.MessageBox("There exists allready a circuit named %s. Override?"%name,
                                "Override?", wx.YES|wx.NO|wx.ICON_QUESTION,
                                self, -1)
            if ret == wx.NO: return

        self.EndModal(wx.ID_OK)
class ArchiveTree(wx.TreeCtrl):
    def __init__(self, parent, ID):
        wx.TreeCtrl.__init__(self, parent, ID, size=wx.Size(-1,-1),
                             style=wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_FULL_ROW_HIGHLIGHT)
        
        self._d_imgs = wx.ImageList(16,16)
        self._bmp_class = self._d_imgs.Add( getArchiveBitmap() )
        self._bmp_class_open = self._d_imgs.Add( getArchiveBitmap() )
        self._bmp_module = self._d_imgs.Add( getPythonBitmap() )
        self.SetImageList(self._d_imgs)

        self._d_model = Model()
        self._d_controller = Controller()
        self._d_mainframe = self._d_controller.getMainFrame()

        self._d_root = self.AddRoot("root")
        self.SetPyData(self._d_root, (None,None))
        self._logger = self._d_controller.getLogger()


        #Add all archives:
        archives = self._d_model.openURI("zip://")
        for archive_uri in archives:
            uri_list = self._d_model.openURI(archive_uri)
            archive_name = getArchive(archive_uri)
            arch_item = self.AppendItem(self._d_root, archive_name)
            self.SetPyData(arch_item, ("Archive", archive_uri) )
            self.SetItemImage(arch_item, self._bmp_class, wx.TreeItemIcon_Normal)
            self.SetItemImage(arch_item, self._bmp_class_open, wx.TreeItemIcon_Expanded)

            for file_uri in uri_list:
                file_name = getPyFile(file_uri)
                file_item = self.AppendItem(arch_item, file_name)
                self.SetPyData(file_item, ("File", file_uri))
                self.SetItemImage(file_item, self._bmp_module, wx.TreeItemIcon_Normal)
                self.SetItemImage(file_item, self._bmp_module, wx.TreeItemIcon_Expanded)
        
        # FIXME self._d_mainframe.bindNewArch(self.NewArchive)

        # Events:
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelection)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate)
        self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)



    def removeURI(self, uri):
        item = self.getItemByURI(uri,self._d_root)
        if not item: raise Exception("Item %s not found"%uri)
        self.Delete(item)

    def addURI(self, uri):
        if self.getItemByURI(uri, self._d_root): return

        if isPyFileURI(uri):
            (ar, py) = splitPyFile(uri)
            item = self.getItemByURI("zip://"+ar, self._d_root)
            fitem = self.AppendItem(item, py)
            self.SetPyData(fitem, ("File", uri))
            self.SetItemImage(fitem, self._bmp_module, wx.TreeItemIcon_Normal)
            self.SetItemImage(fitem, self._bmp_module, wx.TreeItemIcon_Expanded)
        elif isArchiveURI(uri):
            path = getArchive(uri)
            item = self.AppendItem(self._d_root, path)
            self.SetPyData(item, ("Archive",uri))
            self.SetItemImage(item, self._bmp_class, wx.TreeItemIcon_Normal)
            self.SetItemImage(item, self._bmp_class_open, wx.TreeItemIcon_Expanded)
        else: raise Exception("Unkonw URI %s"%uri)
        

    def getItemByURI(self, uri, item):
        (typ, iuri) = self.GetPyData(item)
        if iuri==uri: return item
        (citem, cookie) = self.GetFirstChild(item)
        
        while citem:
            ret = self.getItemByURI(uri, citem)
            if ret != None: return ret
            (citem, cookie) = self.GetNextChild(item,cookie)
 

    
    #
    # CONTROLLER PART
    #
    def OnFocus(self, evt):
       self._updateMainFrame()
       evt.Skip()


    def OnSelection(self, event):
        item = event.GetItem()
        self._updateMainFrame(item)
        event.Skip()


    def _updateMainFrame(self, item=None):
        if not item: item = self.GetSelection()
        self._d_mainframe.bindNew()
        self._d_mainframe.bindOpen()
        self._d_mainframe.bindDelete()
        
        if not item: return
        (typ, uri) = self.GetPyData(item)

        if typ is "File":
            self._d_mainframe.bindOpen(self.OpenFile, "&Open file")
            self._d_mainframe.bindDelete(self.DeleteFile, "&Delete file")
        elif typ is "Archive":
            self._d_mainframe.bindNew(self.NewFile, "&New file")
            self._d_mainframe.bindOpen(self.OpenArchive, "&Open archive")
            self._d_mainframe.bindDelete(self.DeleteArchive, "&Delete archive")
  

    def OnActivate(self, event):
        item = event.GetItem()
        (typ, uri) = self.GetPyData(item)
        if typ == "File":
            self._d_controller.DocumentOpen(uri)
        event.Skip()


    def OpenFile(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if not typ == "File": return
        self._d_controller.DocumentOpen(uri)

    def DeleteFile(self, evt=None):
        item = self.GetSelection()
        if not item:
            self._logger.warning("No item selected to delete")
            return
        (typ, uri) = self.GetPyData(item)
        if not typ == "File": return
        try:
            self._d_controller.DocumentDelete(uri)
            self.removeURI(uri)
        except:
            self._logger.exception("Unable to remove file %s"%uri)


    def NewFile(self, evt=None):
        self._d_controller.DocumentOpen("zip://")
    
    def OpenArchive(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if not typ=="Archive": return
        self.Expand(item)
   
    def NewArchive(self, evt=None):
        selected = False
        while not selected:
            dlg = Dialogs.eDevNewArchiveDialog(self, -1)
            if dlg.ShowModal() == wx.ID_CANCEL: return
            uri = dlg.getSelection()
            dlg.Destroy()

            if self._d_model.checkURI(uri):
                # FIXME ask for overwrite
                continue
            selected = True
        self._d_model.saveURI(uri,"")
        self.addURI(uri)

    def DeleteArchive(self, evt=None):
        item = self.GetSelection()
        (typ, uri) = self.GetPyData(item)

        py_list = self._d_model.openURI(uri)
        for py in py_list:
           self._d_controller.DocumentDelete(py)
        self._d_model.deleteURI(uri)
        self.Delete(item)
Beispiel #17
0
class eDevModuleTree(wx.TreeCtrl):
    
    def __init__(self, parent, ID):
        wx.TreeCtrl.__init__(self, parent, ID, size=wx.Size(-1,-1),
                             style=wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_FULL_ROW_HIGHLIGHT)
        
        self._d_imgs = wx.ImageList(16,16)
        self._bmp_class = self._d_imgs.Add( wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)) )
        self._bmp_class_open = self._d_imgs.Add( wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)) )
        self._bmp_module = self._d_imgs.Add( getModuleBitmap() )
        self.SetImageList(self._d_imgs)

        self._d_model = Model()
        self._d_controller = Controller()
        self._d_mainframe  = self._d_controller.getMainFrame()
        self._logger = self._d_controller.getLogger()

        self._d_root = self.AddRoot("root")
        self.SetPyData(self._d_root, ("Class","mod:/") )

        mods = self._d_model.openURI("mod://")
        self.popClasses(mods)

        self._left_down_uri = None

        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelection)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate)
        self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMove)


    def popClasses(self, mods, item=None):
        if item == None:
            item = self._d_root
        (typ, prefix) = self.GetPyData(item)
        
        def class_filter(uri): return re.match("^%s/\w+/.+$"%prefix, uri)
        modules = filter(class_filter, mods)
        for mod_uri in modules:
            m = re.match("^%s/(\w+)/.+$"%prefix, mod_uri)
            class_name = m.group(1)
            uri = "%s/%s"%(prefix,class_name)
            
            if self.hasClassURI(uri, self._d_root):
                citem = self.getItemByURI(uri, self._d_root)
                self.popModules(mods,citem)
                continue
            
            citem = self.AppendItem(item, class_name)
            self.SetPyData(citem, ("Class", uri) )
            self.SetItemImage(citem, self._bmp_class, wx.TreeItemIcon_Normal)
            self.SetItemImage(citem, self._bmp_class_open, wx.TreeItemIcon_Expanded)
            self.popClasses(mods, citem)

        self.popModules(mods, item)


    def popModules(self, mods, item=None):
        if item == None:
            item = self._d_root

        (typ, prefix) = self.GetPyData(item)
        def module_filter(uri): return re.match("^%s/(\w+)$"%prefix, uri)
        modules = filter(module_filter, mods)
        for module in modules:
            if self.hasURI(module, self._d_root): continue
            m = re.match("^%s/(\w+)"%prefix, module)
            mod_name = m.group(1)
            citem = self.AppendItem(item, mod_name)
            self.SetPyData(citem, ("Module", module) )
            self.SetItemImage(citem, self._bmp_module, wx.TreeItemIcon_Normal)
            self.SetItemImage(citem, self._bmp_module, wx.TreeItemIcon_Expanded)
   

    def addURI(self, uri):
        if self.hasURI(uri,self._d_root): return
        (proto, path) = Tools.splitURI(uri)
        if not proto == "mod": return
        self.popClasses([uri])


    def deleteURI(self, uri):
        if not self.hasURI(uri, self._d_root): return
        
        item = self.getItemByURI(uri, self._d_root)
        if self.ItemHasChildren(item): return
        
        (typ, iuri) = self.GetPyData(item)
        if iuri == "mod:/": return
        self.Delete(item)
        
        pitem = self.GetItemParent(item)
        (typ, uri) = self.GetPyData(pitem)
        self.deleteURI(uri)
   

    def hasURI(self, uri, item):
        if self.getItemByURI(uri, item): return True
        return False

    def getItemByURI(self, uri, item, cookie=None):
        if not item: return None
        (typ, iuri) = self.GetPyData(item)
        if iuri == uri: return item
        
        citem = self.GetFirstChild(item)
        if citem: (citem, ncookie) = citem
        ret = self.getItemByURI(uri, citem, ncookie)
        if ret: return ret

        item = self.GetNextSibling(item)
        return self.getItemByURI(uri, item, cookie)


    def hasClassURI(self, uri, item, cookie=None):
        if not item: return False
        (typ, iuri) = self.GetPyData(item)
        if iuri == uri and typ=="Class": return True
        
        citem = self.GetFirstChild(item)
        if citem: (citem, ncookie) = citem
        if self.hasClassURI(uri, citem, ncookie): return True

        item = self.GetNextSibling(item)
        if self.hasClassURI(uri, item): return True
        return False
    

    #
    # CONTROLLER PART:
    #
    def OnFocus(self, evt):
        self._updateMainFrame()
        evt.Skip()


    def OnSelection(self, evt):
        item = evt.GetItem()
        self._updateMainFrame(item)
        evt.Skip()


    def OnLeftDown(self, evt):
        (item,flag) = self.HitTest(evt.GetPosition())
        if item and flag&(wx.TREE_HITTEST_ONITEMLABEL|wx.TREE_HITTEST_ONITEMICON):
            (typ, uri) = self.GetPyData(item)
            if typ == "Module": self._left_down_uri = uri
        evt.Skip()

    def OnLeftUp(self, evt):
        self._left_down_uri = None

    def OnMove(self, evt):
        if self._left_down_uri:
            self._logger.debug("begin dragging module: %s"%self._left_down_uri)
            drag_uri = wx.TextDataObject(self._left_down_uri)
            dragSrc = wx.DropSource(self)
            dragSrc.SetData(drag_uri)
            dragSrc.DoDragDrop( True )
            self._left_down_uri = None
        evt.Skip()


    def _updateMainFrame(self, item=None):
        if not item: item = self.GetSelection()
        self._d_mainframe.bindNew()
        self._d_mainframe.bindOpen()
        self._d_mainframe.bindDelete()
        
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ == "Module":
            self._d_mainframe.bindOpen(self.OnModuleOpen, "&Open module")
            self._d_mainframe.bindDelete(self.OnModuleDelete, "&Delete module")
        elif typ == "Class":
            self._d_mainframe.bindOpen(self.OnClassOpen, "&Open class")
        self._d_mainframe.bindNew(self.OnNewModule, "&New module")


    def OnActivate(self, evt):
        item = evt.GetItem()
        (typ, uri) = self.GetPyData(item)
        if typ == "Class":
            self.Toggle(item)
            return
        self._d_controller.DocumentOpen(uri)

    def OnModuleOpen(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ=="Module":
            self._d_controller.DocumentOpen(uri)

    def OnClassOpen(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ == "Class":
            self.Expand(item)

    def OnNewModule(self, evt=None):
        self._d_controller.DocumentOpen("mod://")

    def OnModuleDelete(self, evt=None):
        item = self.GetSelection()
        if not item: return
        (typ, uri) = self.GetPyData(item)
        if typ == "Class": return

        self._d_controller.DocumentDelete(uri)
        self.deleteURI(uri)