def __init__(self, toolkit, maingml): self.gmlfile = maingml self.toolkit = toolkit #model from histogram.applications.gui.models.HistogramContainer import HistogramContainer self.histograms = HistogramContainer() #data self.pyshell_locals = {} self.pyshell_locals.update(self.histograms) self.focus = None self.open_tools_default_dir = '.' self.open_data_default_dir = '.' self.threads = [] return
class MainController(ControllerBase): def __init__(self, toolkit, maingml): self.gmlfile = maingml self.toolkit = toolkit #model from histogram.applications.gui.models.HistogramContainer import HistogramContainer self.histograms = HistogramContainer() #data self.pyshell_locals = {} self.pyshell_locals.update(self.histograms) self.focus = None self.open_tools_default_dir = '.' self.open_data_default_dir = '.' self.threads = [] return def __del__(self): for thread in self.threads: thread.join() return def main(self): self.pyshell_locals['_controller'] = self gmlfile = self.gmlfile toolkit = self.toolkit self.view = view = toolkit.mainView() view.controller = self self.pyshell_locals['_view'] = view from luban.gml import gml2gui view = gml2gui(gmlfile, self, toolkit.renderer()) import pylab self.pyshell_locals['pylab'] = pylab import histogram self.pyshell_locals['histogram'] = histogram.histogram self.pyshell_locals['axis'] = histogram.axis self.pyshell_locals['arange'] = histogram.arange plotwindow = view.getSubview('histogramfigure') plotwindow.makePylabUsable() self.pyshell_locals['refresh'] = self.refreshPlot def _plot(): return plotwindow.plot self.pyshell_locals['_plot'] = _plot self.plotCmdHistory = {} #add "." to sys.path import sys sys.path = ['.'] + sys.path from Tools import Tools self._tools = Tools(self) self.addDefaultTools() view.start() return def refreshPlot(self): plotwindow = self.view.getSubview('histogramfigure') # this is assuming a method 'Refresh' on a view plotwindow.Refresh() return def addNewHistogram(self, name, histogram): histograms = self.histograms histograms.set(name, histogram) self.pyshell_locals.update(histograms) names = histograms.keys() self.view.getSubview("histogramList").update(names) self.SwitchFocus(name) return def addPythonModuleAsToolset(self, menuname, pyfile): '''add a python module as a toolset that shows up in the "tools" menu ''' from Tools import toolsetFromPythonModule directory, filename = os.path.split(pyfile) moduleName, toolset = toolsetFromPythonModule(directory, filename) self.addToolset(menuname, toolset) return def addDefaultTools(self): ''' add default tools to the "tools" menu ''' import histogram.applications.gui.tools as tools modules = tools.__export__ for menuname, m in modules: pyfile = m.__file__ self.addPythonModuleAsToolset(menuname, pyfile) continue return def addToolset(self, name, toolset): ''' add a toolset as a submenu in the "tools" menu name is the name of the submenu toolset is a dictionary. for each pair of (key, value), key will show up as the name of the subsubmenu in the submenu value is the function that will be called when the subsubmenu is selected. ''' self._tools.addToolset(name, toolset) return def OnAbout(self, e): toolkit = self.toolkit toolkit.messageDialog(None, "Histogram Viewer", about_msg) return def OnLoadToolset(self, e): open_tools_default_dir = self.open_tools_default_dir pyfile = self.toolkit.loadfileDialog( None, "Open toolset module (any python file)", open_tools_default_dir) self.open_tools_default_dir = os.path.dirname(pyfile) directory, filename = os.path.split(pyfile) name, ext = os.path.splitext(filename) self.addPythonModuleAsToolset(name, pyfile) def OnOnlineTutorial(self, e): import webbrowser webbrowser.open(tutorial_url) return def OnExit(self, evt): self.view.end() return def OnOpenHistogramFile(self, evt): open_data_default_dir = self.open_data_default_dir filename = self.toolkit.loadfileDialog( None, "Open histogram data file", defaultDir=open_data_default_dir) self.open_data_default_dir = os.path.dirname(filename) if filename.endswith('.pkl'): from pickle import load hist = load(open(filename)) elif filename.endswith('h5') or filename.endswith('hdf5'): from histogram.hdf.utils import getOnlyEntry entry = getOnlyEntry(filename) from histogram.hdf import load hist = load(filename, entry) else: toolkit = self.toolkit msg = "Don't know how to open file {0!s}\n" \ "Supported formats : \n" \ " - python pickle\n"\ " - hdf5\n".format(filename) toolkit.messageDialog(None, "Error", msg) return name = hist.name() name = _validVariableName(name) if name in self.histograms.keys(): msg = 'Histogram of name "{0!s}" already exists. \n'\ 'Please rename or delete the existing histogram. \n'.format(name) toolkit = self.toolkit toolkit.messageDialog(None, "Error", msg) return self.addNewHistogram(name, hist) return def OnSelectHistogram(self, evt): listview = self.view.getSubview('histogramList') index = listview.getSelection() names = self.histograms.keys() key = names[index] self.SwitchFocus(key) return def OnSaveFigure(self, evt): figure = self.view.getSubview("histogramfigure") filetypes = figure.getPictureTypes() toolkit = self.toolkit filename = toolkit.savefileDialog(None, "Save figure to file", filetypes) if filename: figure.savePlot(filename) return def OnSaveHistogram(self, evt): toolkit = self.toolkit # get histogram key = self.focus histogram = self.histograms.get(key) # no histogram, alert if histogram is None: toolkit.messageDialog(None, "Error", "No histogram is on focus") return # save filetypes = 'h5' filename = toolkit.savefileDialog( None, "Save histogram to file", filetypes) if filename: import os if os.path.exists(filename): toolkit.messageDialog( None, "Error", "Overwrite is not supported yet.") return import histogram.hdf as hh hh.dump(histogram, filename, '/', 'c') return def OnKeyDownInShellWindow(self, evt): view = self.view #check if <enter> is hit if evt.getKeyCode() != 13: return from histogram.Histogram import Histogram #get a dictinoary of histograms in the shell window locals histograms = {} for key, value in self.pyshell_locals.iteritems(): if isinstance(value, Histogram): histograms[key] = value pass continue #assign the dictionary to the data model changed = self.histograms.assign(histograms) #if there is change, we need to update views if changed: names = self.histograms.keys() view.getSubview("histogramList").update(names) if len(names) > 0: focus = names[-1] self.SwitchFocus(focus) pass pass else: pyshell = view.getSubview("pythonshell") #check whether "plotting" command is involved lastcommand = pyshell.history[0] for cmd in ['pylab', ]: # getpylabcmds(): if lastcommand.find(cmd) != -1: #if so, update the plot self.refreshPlot() # and also keep the command in the history focus = self.focus if focus: history = self.plotCmdHistory.get(focus) or [] if lastcommand not in history: history.append(lastcommand) self.plotCmdHistory[focus] = history pass # end if focus pass # end if lastcommand continue # end for cmd pass return def removeHistogram(self, histogram): listbox = self.view.getSubview('histogramList') histograms = self.histograms names = histograms.keys() index = names.index(histogram) #index = listbox.getSelection() selected = histogram self.histograms.delete(selected) del self.pyshell_locals[selected] del self.plotCmdHistory[histogram] #new list of histogram names names = histograms.keys() # keep listbox in sync listbox.update(names) #move cursor to the next histogram if len(names) != 0: if index >= len(names): # if what is just deleted is the last item, then # we refocus to the current last item focus = names[-1] else: # otherwise, we switch to the item that was just after # the deleted one focus = names[index] self.SwitchFocus(focus) pass else: #no histograms self.view.getSubview("histogramfigure").update(None) self.focus = None pass return def OnKeyDownInListWindow(self, evt): #print(evt.getKeyCode()) if evt.getKeyCode() == 127: # delete listbox = self.view.getSubview('histogramList') histograms = self.histograms names = histograms.keys() index = listbox.getSelection() selected = names[index] self.removeHistogram(selected) return #helpers def SwitchFocus(self, key): print("MainController.SwitchFocus: self.focus = {0!s}, key={1!s}".format(self.focus, key)) if self.focus == key: return self.focus = key names = self.histograms.keys() histogram = self.histograms.get(key) self.view.getSubview("histogramList").select(names.index(key)) self.view.getSubview("histogramfigure").update(histogram) # rerun commands if histogram: history = self.plotCmdHistory.get(key) or [] goodhistory = [] for i, cmd in enumerate(history): try: exec(cmd in self.pyshell_locals) goodhistory.append(cmd) except: pass continue self.plotCmdHistory[key] = goodhistory self.refreshPlot() return pass # end of MainController