Esempio n. 1
0
 def initModel(self):
     self.aligner = Aligner()
Esempio n. 2
0
class AlgraephFrame(wx.Frame):
    wildcard = "Parallel Graph Corpus (*.pgc)|*.pgc|Parallel Graph Corpus (*.xml)|*.xml"
    
    def __init__(self):
        wx.Frame.__init__(self, parent=None, id=-1, title="Algraeph")

        self.initModel()
        
        self.makeMenuBar()
        self.makeSplits()
        self.makeStatusBar()
        
        self.subscribe()

        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.Maximize()
        
        
    def initModel(self):
        self.aligner = Aligner()
        
        
    def subscribe(self):
        subscribe(self.updateStatusbar, "statusDescription") 
        subscribe(self.updateStatusbarCounter, "newGraphPair.gui") 
        subscribe(self.updateSplitterWindow, "newCorpus")
        subscribe(self.updateWindowTitle, "newCorpusName")   
        subscribe(self.updateDisabledWidgets, "newCorpus")        
        

    # ------------------------------------------------------------------------
    # widget construction methods
    # ------------------------------------------------------------------------
        
    def makeSplits(self):
        splitter1 = wx.SplitterWindow(self, style=wx.SP_3DSASH)
        graphTokens = GraphTokenPanel(splitter1, self.aligner)
               
        splitter2 = wx.SplitterWindow(splitter1, -1, style=wx.SP_3DSASH) 
        self.graphView = GraphViewPanel(splitter2, self.aligner, self)
        bottom = BottomPanel(splitter2, self.aligner)
        
        splitter1.SetMinimumPaneSize(graphTokens.GetBestSize()[1])
        splitter2.SetMinimumPaneSize(bottom.GetBestSize()[1])
        
        splitter2.SetSashGravity(1.0)
        
        splitter1.SplitHorizontally(graphTokens, splitter2, graphTokens.GetBestSize()[1])
        splitter2.SplitHorizontally(self.graphView, bottom, bottom.GetBestSize()[1])
        
        # save for resizing when the numbr of relations in bottom panel changes
        self.splitterWindow = splitter2
        
        
    def menuData(self):
        return ( ("&File",
                  dict(text="&Open\tCtrl-O", help="Open corpus", handler=self.onMenuOpen),
                  dict(text="&Save\tCtrl-S", help="Save corpus", handler=self.onMenuSave, enable=False),
                  dict(text="Save &As", help="Save corpus as", handler=self.onMenuSaveAs, enable=False),
                  dict(text="&Quit\tCtrl-Q", help="Quit", handler=self.onClose, id=wx.ID_EXIT)),
                  ("&Go",
                   dict(text="&Prev\tCtrl-P", help="Previous graph pair", handler=self.onMenuPrev, enable=False),
                   dict(text="&Next\tCtrl-N", help="Next graph pair", handler=self.onMenuNext, enable=False),
                   dict(text="&Goto\tCtrl-G", help="Goto graph pair", handler=self.onMenuGoto, enable=False)),
                   ("&View", ),
                   ("&Help",
                    dict(text="&Algraeph User Manual\tCtrl-?", help="Read online user manual", 
                         handler=self.onMenuHelp, id=wx.ID_HELP),
                    dict(text="Algraeph &License", help="Read online license", 
                         handler=self.onMenuLicense),
                    dict(text="&About Algraeph", help="Information about Algraeph", 
                         handler=self.onMenuAbout, id=wx.ID_ABOUT))
                     )

    
    def makeMenuBar(self):                     
        menuBar = wx.MenuBar() 
        self.disabledMenuItems = []
        
        for eachMenuData in self.menuData(): 
            menuLabel = eachMenuData[0] 
            menuItems = eachMenuData[1:] 
            menuBar.Append(self.makeMenu(menuItems), menuLabel)
        
        self.SetMenuBar(menuBar)


    def makeMenu(self, menuData):                                 
        menu = wx.Menu() 
        
        for data in menuData: 
            if not data: 
                menu.AppendSeparator() 
                continue 
            
            menuItem = menu.Append(id=data.get("id", -1), 
                                   text=data["text"],
                                   help=data.get("help", ""),
                                   kind=data.get("kind", wx.ITEM_NORMAL)) 
            self.Bind(wx.EVT_MENU, data["handler"], menuItem)
            
            if not data.get("enable", True):
                menuItem.Enable(False)
                self.disabledMenuItems.append(menuItem)
                
            
        return menu    
    

    def makeStatusBar(self):
        self.statusBar = self.CreateStatusBar() 
        self.statusBar.SetFieldsCount(2) 
        self.statusBar.SetStatusWidths([-3, -1]) 
        
    # ------------------------------------------------------------------------
    # event methods
    # ------------------------------------------------------------------------
    
    #def onNew(self, evt):
    #    pass
    
    def onMenuOpen(self, evt):
        try:
            if not self.saveChanges():
                return
        except:
            # Error is reported by saveChanges.
            # Return and hope that user can solve the error
            # otherwise the system is locked
            return
        
        dlg = wx.FileDialog(self, "Open corpus...", 
                            self.aligner.get_corpus_dir() or getcwd(),
                            style=wx.FD_OPEN,
                            wildcard = self.wildcard)
        
        if dlg.ShowModal() == wx.ID_OK:
            filename = dlg.GetPath()
            self.openCorpus(filename)
            
        dlg.Destroy()

        
    def onMenuSave(self, evt):
        self.aligner.save_corpus()

        
    def onMenuSaveAs(self, evt):
        dlg = wx.FileDialog(self, "Save corpus as...", 
                            self.aligner.get_corpus_dir() or getcwd(),
                            style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT,
                            wildcard = self.wildcard)
        
        if dlg.ShowModal() == wx.ID_OK:
            filename = dlg.GetPath()
            self.aligner.save_corpus(filename)
            
        dlg.Destroy()
        
        
    def onMenuPrev(self, evt):
        self.aligner.goto_prev_graph_pair()

        
    def onMenuNext(self, evt):
        self.aligner.goto_next_graph_pair()
        
        
    def onMenuGoto(self, evt):
        dlg = wx.TextEntryDialog(self, 'Goto graph pair number:', 'Goto')

        if dlg.ShowModal() == wx.ID_OK:
            try:
                i = int(dlg.GetValue())
            except ValueError:
                pass
            else:
                # aligner ignores out-of-bounds index
                self.aligner.goto_graph_pair(i - 1)

        dlg.Destroy()        
        
    
    def onMenuHelp(self, evt):
        help_frame = HelpViewFrame(self, title="Algraeph User Manual") 
        help_frame.loadDoc(release.name, release.version, "algraeph-user-manual.htm")
        
        
    def onMenuLicense(self, evt):
        lic_frame = HelpViewFrame(self, title="Algraeph License") 
        lic_frame.loadDoc(release.name, release.version, "GPL.html")
    

    def onMenuAbout(self, evt):
        
        info = wx.AboutDialogInfo()
        info.AddDeveloper("%s <%s>" % (release.author, release.author_email))
        info.SetName(release.name)
        info.SetDescription("%s\n%s" % (release.description, release.url))
        info.SetVersion(release.version)
        info.SetCopyright("Copyright %s\nReleased under %s" % 
                          (release.copyright, release.license))
        #info.SetWebSite("https://github.com/emsrc/algraeph")
        wx.AboutBox(info)

        
    def onClose(self, evt):
        self.Destroy()

        
    def Destroy(self):
        try:
            if self.saveChanges():
                wx.Frame.Destroy(self)                
        except:
            # Error is reported by saveChanges.
            # Return and hope that user can solve the error
            # otherwise the system is locked
            return

        
    #-------------------------------------------------------------------------------
    # Listeners
    #-------------------------------------------------------------------------------
    
    def updateStatusbar(self, msg=None):
        # subscriptions:
        # - statusDescription
        
        receive(self.updateStatusbar, msg)
        self.statusBar.SetStatusText(msg.data or "Ready", 0)
        
        
    def updateStatusbarCounter(self, msg=None):
        # subscriptions:
        # - statusDescription
        receive(self.updateStatusbarCounter, msg)
        self.statusBar.SetStatusText("%d of %d graph pairs" % self.aligner.get_graph_pair_counter(), 1)

        name = self.aligner.get_corpus_filename()
        
        if name:
            self.SetTitle("Algraeph:  %s  (%s)" % ( basename(name), dirname(name)))
        else:
            self.SetTitle("Algraeph")

            
    def updateWindowTitle(self, msg=None):
        # subscriptions: 
        # - newCorpus      
        receive(self.updateWindowTitle, msg)
        name = self.aligner.get_corpus_filename()
        
        if name:
            self.SetTitle("Algraeph: %s (%s)" % (basename(name), dirname(name)))
        else:
            self.SetTitle("Algraeph")
            
        
    def updateSplitterWindow(self, msg=None):
        # subscriptions: 
        # - newCorpus        
        receive(self.updateSplitterWindow, msg)
        bottom = self.splitterWindow.GetWindow2()
        bestSize = bottom.GetBestSize()[1]
        self.splitterWindow.SetMinimumPaneSize(bestSize)
        self.splitterWindow.SetSashPosition(-bestSize)
        
        
    def updateDisabledWidgets(self,  msg=None):
        # subscriptions: 
        # - newCorpus
        receive(self.updateDisabledWidgets, msg)
        
        for menuItem in self.disabledMenuItems:
            menuItem.Enable(True)

        
    #-------------------------------------------------------------------------------
    # Support methods
    #-------------------------------------------------------------------------------
    
    # file
    
    def openCorpus(self, filename):
        try:
            self.aligner.open_corpus(filename)
        except Exception, inst:
            # assume aligner will reset the corpus to a valid state
            self.reportError(str(inst))
            raise