def initModel(self): self.aligner = Aligner()
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