def __init__(self, guiParent, basePopup, rep1=None, rep2=None): self.basePopup = basePopup self.guiParent = guiParent # add this to shortcuts to ease navigation self.basePopup.frameShortcuts['DataExch'] = self # FIXME # This is a hack just so that we can see what it would be like # need to set these in a different way!! self.repository1 = self.basePopup.repList.currentRepository self.repository2 = self.basePopup.repList.currentRepository Frame.__init__(self, guiParent) self.grid_columnconfigure(0, weight=0, minsize=10) self.grid_columnconfigure(1, weight=1, minsize=20) self.grid_columnconfigure(2, weight=0, minsize=40) self.grid_columnconfigure(3, weight=1, minsize=20) self.grid_columnconfigure(4, weight=0, minsize=10) self.grid_rowconfigure(0, weight=0, minsize=10) self.grid_rowconfigure(1, weight=0, minsize=10) self.grid_rowconfigure(2, weight=0, minsize=10) self.grid_rowconfigure(3, weight=1, minsize=10) self.grid_rowconfigure(4, weight=0, minsize=10) # build up the body. start really simple self.repLabel1 = Label(self, text='Repository 1') self.repLabel2 = Label(self, text='Repository 2') self.noDataWidgets = [] self.noRep1Label = Label(self,text='No repository currently selected.') self.noDataWidgets.append(self.noRep1Label) self.noRep2Label = Label(self,text='No repository currently selected.') self.noDataWidgets.append(self.noRep2Label) # widgets for view when current repository set self.dataWidgets1 = [] self.label1 = Label(self) self.dataWidgets1.append(self.label1) self.frame1 = Tree(self) self.dataWidgets1.append(self.frame1) self.dataWidgets2 = [] self.label2 = Label(self) self.dataWidgets2.append(self.label2) self.frame2 = Tree(self) self.dataWidgets2.append(self.frame2) self.drawFrame()
def __init__(self, guiParent, basePopup): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent self.basePopup.frameShortcuts['Workflow'] = self #self.registerNotify=basePopup.registerNotify #self.unregisterNotify=basePopup.unregisterNotify Frame.__init__(self, guiParent) self.grid_rowconfigure(0, weight=0) self.grid_rowconfigure(1, weight=0, minsize=100) self.grid_rowconfigure(2, weight=1) self.grid_rowconfigure(3, weight=0, minsize=30) self.grid_columnconfigure(0, weight=0) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure(2, weight=0) # build up the body. self.lcA = LinkChart(self, background='#8080B0', height=110) self.lcB = LinkChart(self, background='#8080B0') lcButtonOpts=['Load','Save','Clear','New Protocol'] lcButtonCmds=[self.tmpCall,self.tmpCall,self.tmpCall,self.tmpCall] self.lcButtons = ButtonList(self, lcButtonOpts, lcButtonCmds) # hack for now. This should come from db of meta-tasks self.expts=['Test1','Test2','ARIA','CING','ISD'] # needs custom version self.filter = FilterFrame(self, self.basePopup, text='Filter') # no bean udnerneath for now so mock up nodes self.wfTree = Tree(self, width=35) wfButtonOpts=['Load','Save'] wfButtonCmds=[self.tmpCall,self.tmpCall] self.wfButtons = ButtonList(self, wfButtonOpts, wfButtonCmds) self.drawFrame()
class WorkflowFrame(Frame): def __init__(self, guiParent, basePopup): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent self.basePopup.frameShortcuts['Workflow'] = self #self.registerNotify=basePopup.registerNotify #self.unregisterNotify=basePopup.unregisterNotify Frame.__init__(self, guiParent) self.grid_rowconfigure(0, weight=0) self.grid_rowconfigure(1, weight=0, minsize=100) self.grid_rowconfigure(2, weight=1) self.grid_rowconfigure(3, weight=0, minsize=30) self.grid_columnconfigure(0, weight=0) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure(2, weight=0) # build up the body. self.lcA = LinkChart(self, background='#8080B0', height=110) self.lcB = LinkChart(self, background='#8080B0') lcButtonOpts=['Load','Save','Clear','New Protocol'] lcButtonCmds=[self.tmpCall,self.tmpCall,self.tmpCall,self.tmpCall] self.lcButtons = ButtonList(self, lcButtonOpts, lcButtonCmds) # hack for now. This should come from db of meta-tasks self.expts=['Test1','Test2','ARIA','CING','ISD'] # needs custom version self.filter = FilterFrame(self, self.basePopup, text='Filter') # no bean udnerneath for now so mock up nodes self.wfTree = Tree(self, width=35) wfButtonOpts=['Load','Save'] wfButtonCmds=[self.tmpCall,self.tmpCall] self.wfButtons = ButtonList(self, wfButtonOpts, wfButtonCmds) self.drawFrame() def drawFrame(self): # hack the WF Tree for now. just get is looking OK texts=['JMCI WF 1','JMCI WF 2'] icons=[] parents=[] callbacks=[] objects=['JMCI WF 1','JMCI WF 2'] for text in texts: icons.append('list-add') callbacks.append(None) parents.append(None) self.wfTree.update(parents, objects, texts, icons, callbacks) self.lcA.grid(row=1, column=1, padx=5, pady=5, sticky='new') self.lcB.grid(row=2, column=1, padx=5, pady=5, sticky='nsew') self.lcButtons.grid(row=3, column=1, padx=5, pady=5, sticky='ew') self.filter.grid(row=1, column=2, sticky='new') self.wfTree.grid(row=2, column=2, padx=5, pady=5, sticky='nsew') self.wfButtons.grid(row=3, column=2, padx=5, pady=5, sticky='ew') self.nodes = [] x = 0 for expt in self.expts: node = PrototypeNode(self.lcA, title=expt, width=38, updateFunc=None, resizeable=False, shape='SQUARE', coords=(50+x*90, 50), object=None) x += 1 self.lcA.draw() self.lcB.draw() def tmpCall(self): pass def administerNotifiers(self, notifyFunc): for func in ('__init__','delete','setName'): notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.Experiment', func) notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.DataSource', func) def updateAllAfter(self, obj): self.after_idle(self.updateAll) def updateAll(self, project=None): if project: self.project = project self.nmrProject = project.currentNmrProject if not self.nmrProject: self.nmrProject = project.newNmrProject(name=project.name) if not self.project: return def quit(self): self.guiParent.parent.destroy() def destroy(self): self.administerNotifiers(self.basePopup.unregisterNotify) Frame.destroy(self)
def __init__(self, guiParent, basePopup): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent self.basePopup.frameShortcuts['Protocol'] = self Frame.__init__(self, guiParent) self.grid_rowconfigure(0, weight=0) self.grid_rowconfigure(1, weight=0, minsize=10) self.grid_rowconfigure(2, weight=0) self.grid_rowconfigure(3, weight=1) self.grid_rowconfigure(4, weight=0, minsize=30) self.grid_rowconfigure(5, weight=0, minsize=30) self.grid_columnconfigure(0, weight=0) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure(2, weight=0) # build up the body. self.title = Label(self, font='Helvetica16') self.details = Label(self) initial_cols = ['Parameter', 'Type', 'Value'] self.pMatrix = ScrolledMatrix(self, headingList=initial_cols, initialRows=15) editButtonOpts = ['Save', 'Clear', 'New Protocol', 'New Expt Type'] editButtonCmds = [ self.tmpCall, self.tmpCall, self.tmpCall, self.tmpCall ] self.editButtons = ButtonList(self, editButtonOpts, editButtonCmds) # needs custom version self.filter = FilterFrame(self, self.basePopup, text='Filter') # no bean udnerneath for now so mock up nodes self.pTree = Tree(self, width=33) pButtonOpts1 = ['Load', 'Save'] pButtonCmds1 = [self.tmpCall, self.tmpCall] self.pButtons1 = ButtonList(self, pButtonOpts1, pButtonCmds1) pButtonOpts2 = ['New', 'Delete'] pButtonCmds2 = [self.tmpCall, self.tmpCall] self.pButtons2 = ButtonList(self, pButtonOpts2, pButtonCmds2) self.openedLinks = { 'Test 1': ['ParSet 1', 'ParSet 2'], 'Test 2': ['Std Pars', 'Big Pars', 'Little Pars'], 'ARIA': ['default', 'complex'], 'CING': ['Std'], 'ISD': ['protein', 'DNA'] } self.drawFrame()
class ProtocolFrame(Frame): def __init__(self, guiParent, basePopup): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent self.basePopup.frameShortcuts['Protocol'] = self Frame.__init__(self, guiParent) self.grid_rowconfigure(0, weight=0) self.grid_rowconfigure(1, weight=0, minsize=10) self.grid_rowconfigure(2, weight=0) self.grid_rowconfigure(3, weight=1) self.grid_rowconfigure(4, weight=0, minsize=30) self.grid_rowconfigure(5, weight=0, minsize=30) self.grid_columnconfigure(0, weight=0) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure(2, weight=0) # build up the body. self.title = Label(self, font='Helvetica16') self.details = Label(self) initial_cols = ['Parameter', 'Type', 'Value'] self.pMatrix = ScrolledMatrix(self, headingList=initial_cols, initialRows=15) editButtonOpts = ['Save', 'Clear', 'New Protocol', 'New Expt Type'] editButtonCmds = [ self.tmpCall, self.tmpCall, self.tmpCall, self.tmpCall ] self.editButtons = ButtonList(self, editButtonOpts, editButtonCmds) # needs custom version self.filter = FilterFrame(self, self.basePopup, text='Filter') # no bean udnerneath for now so mock up nodes self.pTree = Tree(self, width=33) pButtonOpts1 = ['Load', 'Save'] pButtonCmds1 = [self.tmpCall, self.tmpCall] self.pButtons1 = ButtonList(self, pButtonOpts1, pButtonCmds1) pButtonOpts2 = ['New', 'Delete'] pButtonCmds2 = [self.tmpCall, self.tmpCall] self.pButtons2 = ButtonList(self, pButtonOpts2, pButtonCmds2) self.openedLinks = { 'Test 1': ['ParSet 1', 'ParSet 2'], 'Test 2': ['Std Pars', 'Big Pars', 'Little Pars'], 'ARIA': ['default', 'complex'], 'CING': ['Std'], 'ISD': ['protein', 'DNA'] } self.drawFrame() def drawFrame(self): # hack the WF Tree for now. just get is looking OK texts = ['Test 1', 'Test 2', 'ARIA', 'CING', 'ISD'] icons = [] parents = [] callbacks = [] objects = ['Test 1', 'Test 2', 'ARIA', 'CING', 'ISD'] for text in texts: icons.append('list-add') callbacks.append(self.openLink) parents.append(None) self.pTree.update(parents, objects, texts, icons, callbacks) self.title.set('Protocol: Std (ARIA)') self.title.grid(row=1, column=1, padx=5, sticky='w') self.details.set('Description: details about the exp type or protocol') self.details.grid(row=2, column=1, padx=5, sticky='nw') self.pMatrix.grid(row=3, rowspan=2, column=1, padx=5, pady=5, sticky='ew') self.editButtons.grid(row=5, column=1, padx=5, pady=5, sticky='ew') self.filter.grid(row=1, column=2, rowspan=2, sticky='new') self.pTree.grid(row=3, column=2, padx=5, pady=5, sticky='nsew') self.pButtons1.grid(row=4, column=2, padx=5, sticky='ew') self.pButtons2.grid(row=5, column=2, padx=5, sticky='ew') matrix = [] objs = [] matrix.append(['Parameter1', 'String', 'foobar']) objs.append('obj1') matrix.append(['Parameter2', 'Number', '10']) objs.append('obj2') self.pMatrix.update(objectList=objs, textMatrix=matrix) def tmpCall(self): pass def openLink(self, node): tree = node.tree par = node.object print 'opening node "', par, '"' print 'got series "', self.openedLinks[par], '"' if len(self.openedLinks[par]) > 0: for pv in self.openedLinks[par]: icon = 'folder' obj = par + '::' + pv text = pv callback = None tree.add(node, obj, text, icon, callback) def administerNotifiers(self, notifyFunc): for func in ('__init__', 'delete', 'setName'): notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.Experiment', func) notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.DataSource', func) def updateAllAfter(self, obj): self.after_idle(self.updateAll) def updateAll(self, project=None): if project: self.project = project self.nmrProject = project.currentNmrProject if not self.nmrProject: self.nmrProject = project.newNmrProject(name=project.name) if not self.project: return def quit(self): self.guiParent.parent.destroy() def destroy(self): self.administerNotifiers(self.basePopup.unregisterNotify) Frame.destroy(self)
def __init__(self, guiParent, basePopup, callback=None): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent # we need to be able to define a callback before exit self.callback = callback Frame.__init__(self, guiParent) # Basic principle is that we want to supply a root directory # and we will get a tree that will allow us to browse anything # below the directory. We will also have a button for going # up a directory. self.rootDir = '/home/jionides/work/CCPN/test_WMS_archive' self.icon_dict = { 'none': 'text-x-generic-template', 'text': 'text-x-generic', 'text/plain': 'text-x-generic', 'text/html': 'text-html', 'text/script': 'text-x-script', 'text/x-python': 'text-x-script', 'text/x-perl': 'text-x-script', 'image': 'image-x-generic', 'application': 'applications-other', 'video': 'video-x-generic', 'message': 'internet-mail', 'audio': 'audio-x-generic', 'chemical': 'applications-internet', 'application/x-tar': 'package-x-generic', 'application/msword': 'x-office-document', 'application/postscript': 'x-office-drawing', 'application/pdf': 'x-office-drawing', 'application/xml': 'text-x-script', 'application/x-python-code': 'application-x-executable', } self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(1, weight=1) self.fileTree = Tree(self) self.fileTree.grid(row=1, column=1, padx=10, pady=10, sticky='nsew') self.ok_button = Button(self, width=10, text='OK', command=self.isOk) #self.ok_button = Button(self, text='OK', command=self.isOk) self.ok_button.grid(row=2, column=1, padx=10, pady=10, sticky='e') self.cancel_button = Button(self, width=10, text='Cancel', command=self.isCancel) #self.cancel_button = Button(self,text='Cancel', command=self.isCancel) self.cancel_button.grid(row=2, column=1, padx=10, pady=10, sticky='w') files = listdir(self.rootDir) parents = [None] * len(files) icons = [] objects = [] texts = [] callbacks = [] for file in files: file = path.join(self.rootDir, file) text, icon, isDir = self.getData(file) icons.append(icon) texts.append(text) objects.append(file) if isDir: callbacks.append(self.openDir) else: callbacks.append(None) print 'updating', texts self.fileTree.update(parents, objects, texts, icons, callbacks)
class FileBrowserFrame(Frame): def __init__(self, guiParent, basePopup, callback=None): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent # we need to be able to define a callback before exit self.callback = callback Frame.__init__(self, guiParent) # Basic principle is that we want to supply a root directory # and we will get a tree that will allow us to browse anything # below the directory. We will also have a button for going # up a directory. self.rootDir = '/home/jionides/work/CCPN/test_WMS_archive' self.icon_dict = { 'none': 'text-x-generic-template', 'text': 'text-x-generic', 'text/plain': 'text-x-generic', 'text/html': 'text-html', 'text/script': 'text-x-script', 'text/x-python': 'text-x-script', 'text/x-perl': 'text-x-script', 'image': 'image-x-generic', 'application': 'applications-other', 'video': 'video-x-generic', 'message': 'internet-mail', 'audio': 'audio-x-generic', 'chemical': 'applications-internet', 'application/x-tar': 'package-x-generic', 'application/msword': 'x-office-document', 'application/postscript': 'x-office-drawing', 'application/pdf': 'x-office-drawing', 'application/xml': 'text-x-script', 'application/x-python-code': 'application-x-executable', } self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(1, weight=1) self.fileTree = Tree(self) self.fileTree.grid(row=1, column=1, padx=10, pady=10, sticky='nsew') self.ok_button = Button(self, width=10, text='OK', command=self.isOk) #self.ok_button = Button(self, text='OK', command=self.isOk) self.ok_button.grid(row=2, column=1, padx=10, pady=10, sticky='e') self.cancel_button = Button(self, width=10, text='Cancel', command=self.isCancel) #self.cancel_button = Button(self,text='Cancel', command=self.isCancel) self.cancel_button.grid(row=2, column=1, padx=10, pady=10, sticky='w') files = listdir(self.rootDir) parents = [None] * len(files) icons = [] objects = [] texts = [] callbacks = [] for file in files: file = path.join(self.rootDir, file) text, icon, isDir = self.getData(file) icons.append(icon) texts.append(text) objects.append(file) if isDir: callbacks.append(self.openDir) else: callbacks.append(None) print 'updating', texts self.fileTree.update(parents, objects, texts, icons, callbacks) def getData(self, file): dirr, text = path.split(file) readable = access(file, R_OK) isDir = False if path.isdir(file): if not readable: icon = 'emblem-unreadable' elif path.islink(file): isDir = True icon = 'folder-remote' else: isDir = True icon = 'folder' text += '/' elif path.isfile(file): if not readable: icon = 'emblem-unreadable' #elif path.islink(file): # icon = 'text-html' else: mimeType = mimetypes.guess_type(file)[0] if mimeType: if not self.icon_dict.get(mimeType): print mimeType icon = self.icon_dict.get(mimeType) \ or self.icon_dict.get(mimeType.split('/')[0]) \ or self.icon_dict['none'] else: icon = self.icon_dict['none'] elif not readable: icon = 'emblem-unreadable' else: icon = 'emblem-system' return text, icon, isDir def openDir(self, node): tree = node.tree filePath = node.object files = listdir(filePath) for file in files: file = path.join(filePath, file) text, icon, isDir = self.getData(file) parent, null = path.split(file) if isDir and access(file, R_OK): callback = self.openDir else: callback = None tree.add(node, file, text, icon, callback) def isCancel(self): print 'should be exiting' self.quit() def isOk(self): print 'setting selected ', self.fileTree.getSelected() def destroy(self): print 'in main destroy method' Frame.destroy(self) def quit(self): print 'in main quit method' self.guiParent.parent.destroy()
def __init__(self, guiParent, basePopup): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent # should the screen autorefresh self.autoRefresh = False # add this to shortcuts to ease navigation self.basePopup.frameShortcuts['Repository'] = self # get a port proxy instance # this should probably belong to the repository directly # or else should belong in a dictionary in the main gui # layer when it can be picked up easily # FIXME JMCI # need to work out how to get a number of these! loc = SharedBeanServiceLocator() self.port = loc.getSharedBean() self.registerNotify = basePopup.registerNotify self.unregisterNotify = basePopup.unregisterNotify Frame.__init__(self, guiParent) # set up the grid self.grid_columnconfigure(0, weight=0, minsize=20) self.grid_columnconfigure(1, weight=1, minsize=10) self.grid_columnconfigure(2, weight=0, minsize=20) self.grid_rowconfigure(0, weight=0, minsize=5) self.grid_rowconfigure(1, weight=0, minsize=0) self.grid_rowconfigure(2, weight=0, minsize=10) self.grid_rowconfigure(3, weight=0, minsize=10) self.grid_rowconfigure(4, weight=0, minsize=10) self.grid_rowconfigure(5, weight=1, minsize=10) self.grid_rowconfigure(6, weight=0, minsize=10) self.grid_rowconfigure(7, weight=0, minsize=10) # widgets for view when no data self.noDataWidgets = [] self.noRepLabel = Label(self, text='No repository currently selected.') self.noDataWidgets.append(self.noRepLabel) # widgets for view when current repository set self.dataWidgets = [] self.repTitle = Label(self, text='Repository:', font='Helvetica16') self.dataWidgets.append(self.repTitle) #self.repLabel = Label(self,text='All Projects in Repository') #self.dataWidgets.append(self.repLabel) self.repTree = Tree(self, doubleCallback=self.goto_project_tab) self.dataWidgets.append(self.repTree) sel = 1 if self.autoRefresh: sel = 0 self.autoRefreshSwitchLabel = Label(self, text='Auto Refresh') self.autoRefreshSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_refresh, selected_index=sel) # need to decide whether this is static or not r_button_texts = [ 'Add to Basket', ' Import ', ' Export ', ' Refresh ', 'Properties' ] r_button_cmds = [ self.tmpCall, self.import_project, self.export_project, self.drawFrame, self.goto_project_tab ] self.rep_button_list = ButtonList(self, r_button_texts, r_button_cmds) self.dataWidgets.append(self.rep_button_list) self.filterFrame = FilterFrame(self, self.basePopup, text='Filter') self.dataWidgets.append(self.filterFrame) baskets = ('basket1', 'basket2', 'basket3') self.basketSelect = PulldownList(self, self.tmpCall, baskets) self.dataWidgets.append(self.basketSelect) basketElements = ('1ay3', '1ay7') self.basketList = ScrolledListbox(self, basketElements, 25, 18) self.dataWidgets.append(self.basketList) b_button_texts = ['Remove from Basket', 'New Basket'] b_button_cmds = [self.tmpCall, self.tmpCall] self.b_button_list = ButtonList(self, b_button_texts, b_button_cmds) self.dataWidgets.append(self.b_button_list) # draw if not automatically refreshing if sel == 1: self.drawFrame() # set up a loop self.refresh()
class RepositoryFrame(Frame): def __init__(self, guiParent, basePopup): # Base popup required to handle notification of data model changes # e.g. new peak lists, so that the GUI can update to the latest # state self.basePopup = basePopup self.guiParent = guiParent # should the screen autorefresh self.autoRefresh = False # add this to shortcuts to ease navigation self.basePopup.frameShortcuts['Repository'] = self # get a port proxy instance # this should probably belong to the repository directly # or else should belong in a dictionary in the main gui # layer when it can be picked up easily # FIXME JMCI # need to work out how to get a number of these! loc = SharedBeanServiceLocator() self.port = loc.getSharedBean() self.registerNotify = basePopup.registerNotify self.unregisterNotify = basePopup.unregisterNotify Frame.__init__(self, guiParent) # set up the grid self.grid_columnconfigure(0, weight=0, minsize=20) self.grid_columnconfigure(1, weight=1, minsize=10) self.grid_columnconfigure(2, weight=0, minsize=20) self.grid_rowconfigure(0, weight=0, minsize=5) self.grid_rowconfigure(1, weight=0, minsize=0) self.grid_rowconfigure(2, weight=0, minsize=10) self.grid_rowconfigure(3, weight=0, minsize=10) self.grid_rowconfigure(4, weight=0, minsize=10) self.grid_rowconfigure(5, weight=1, minsize=10) self.grid_rowconfigure(6, weight=0, minsize=10) self.grid_rowconfigure(7, weight=0, minsize=10) # widgets for view when no data self.noDataWidgets = [] self.noRepLabel = Label(self, text='No repository currently selected.') self.noDataWidgets.append(self.noRepLabel) # widgets for view when current repository set self.dataWidgets = [] self.repTitle = Label(self, text='Repository:', font='Helvetica16') self.dataWidgets.append(self.repTitle) #self.repLabel = Label(self,text='All Projects in Repository') #self.dataWidgets.append(self.repLabel) self.repTree = Tree(self, doubleCallback=self.goto_project_tab) self.dataWidgets.append(self.repTree) sel = 1 if self.autoRefresh: sel = 0 self.autoRefreshSwitchLabel = Label(self, text='Auto Refresh') self.autoRefreshSwitch = RadioButtons(self, ['on', 'off'], select_callback=self.set_refresh, selected_index=sel) # need to decide whether this is static or not r_button_texts = [ 'Add to Basket', ' Import ', ' Export ', ' Refresh ', 'Properties' ] r_button_cmds = [ self.tmpCall, self.import_project, self.export_project, self.drawFrame, self.goto_project_tab ] self.rep_button_list = ButtonList(self, r_button_texts, r_button_cmds) self.dataWidgets.append(self.rep_button_list) self.filterFrame = FilterFrame(self, self.basePopup, text='Filter') self.dataWidgets.append(self.filterFrame) baskets = ('basket1', 'basket2', 'basket3') self.basketSelect = PulldownList(self, self.tmpCall, baskets) self.dataWidgets.append(self.basketSelect) basketElements = ('1ay3', '1ay7') self.basketList = ScrolledListbox(self, basketElements, 25, 18) self.dataWidgets.append(self.basketList) b_button_texts = ['Remove from Basket', 'New Basket'] b_button_cmds = [self.tmpCall, self.tmpCall] self.b_button_list = ButtonList(self, b_button_texts, b_button_cmds) self.dataWidgets.append(self.b_button_list) # draw if not automatically refreshing if sel == 1: self.drawFrame() # set up a loop self.refresh() def drawFrame(self): if self.basePopup.repList.currentRepository == None: for widget in self.dataWidgets: widget.grid_remove() self.noRepLabel.grid(row=1, column=1, sticky='n') else: self.repository = self.basePopup.repList.currentRepository for widget in self.noDataWidgets: widget.grid_remove() # Column headers # want to have a general admin panel; current repository, button to change, info # about login and so on self.repTitle.set('Repository: ' + self.repository.user + '@' + self.repository.name + ' ( ' + self.repository.connect + ' )') self.repTitle.grid(row=1, column=1, sticky='w') # self.repLabel.grid(row=2, column=1, sticky='w') # Repository block #grid and update self.repTree.grid(row=3, column=1, rowspan=3, sticky='nsew') self.updateRepTree() self.autoRefreshSwitchLabel.grid(row=6, column=1, padx=10, sticky='w') self.autoRefreshSwitch.grid(row=6, column=1, padx=10, sticky='e') # the buttons for functionality in repository area self.rep_button_list.grid(row=7, column=1, padx=3, sticky='ew') # filter frame self.filterFrame.grid(row=3, column=2, stick='nsew') # list of baskest. Will callback to change current basket self.basketSelect.grid(row=4, column=2, padx=10, stick='w') # lists projects per basket self.basketList.grid(row=5, rowspan=2, column=2, padx=10, stick='nsew') self.b_button_list.grid(row=7, column=2, padx=5, stick='ew') def openLink(self, node): tree = node.tree par = node.object # this should be associated with the repository object request = getList() # FIXME JMCI # 1. Potentially need to traverse up the node tree # 2. Currently there is bug in expansion/contraction # 3. Search needs to work off proxy method (not off # generated stubs # pass the parent name for now. may need other criteria later h1 = {'name': par.__str__()} h2 = {'project': h1} wsstr_in = WSString(h2) request._arg0 = 'org.pimslims.applet.server.ProjectVersionBean' request._arg1 = 'getListWithFields' request._arg2 = wsstr_in.str # get the response response = self.port.getList(request) # currently we just get a list of numbers. May want to send # all the fields for every object too to cut down on db calls wsstr_out = WSString(response._return) ss = wsstr_out.getStruct() for hm in ss: print 'handling ', hm, ', ', hm['status'].__str__() #if hm['status'].__str__() == 'AVAILABLE': icon = 'text-x-generic' #else: # icon='emblem-readonly' pv = par.__str__() + '::' + hm['versionTag'].__str__() obj = pv text = hm['versionTag'].__str__() callback = None tree.add(node, obj, text, icon, callback) def set_refresh(self, text): print 'setting refresh ', text if text == 'on': self.autoRefresh = True else: self.autoRefresh = False def refresh(self): if self.autoRefresh: print 'refreshing frame ', time.time() self.drawFrame() self.after(5000, self.refresh) # FIME JMCI # it would probably be a good idea to have a method that allowed # a user to unlock a given project version. Would need to check # permissions very carefully, though def unlock_project_version(self): pass def goto_project_tab(self, node=None): if node is None: # get the selected node selected_nodes = self.repTree.getSelectedNodes() # restrict the choice to one node = selected_nodes[0] # we really need to traverse the tree a lot more carefully pv = node.object.__str__() print 'GOTO PROJECT ', pv, ', ', node, ', ', node.object pat = re.compile('::') matcher = pat.search(pv, 0) name = pv[0:matcher.start()] versionTag = pv[matcher.end():] print 'GOTO PROJECT ', name, ', ', versionTag #versionTag = node.object.__str__() #name = node.parent.object.__str__() #print node.__dict__ #print node.parent.__dict__ self.basePopup.repList.currentRepository.currentProjectName = name self.basePopup.repList.currentRepository.currentVersionTag = versionTag # this is going to have to be keyed on a natural key that then # gets set into the criteria of a ws query # hack for now. build in later. Essentially, we have to handle two # cases; that of a specific projectVersion request and that of a # request on a project alone. Probably the best behaviour would be # for the project-only request to default to the latest trunk # version of the project and the most elegent way of triggering # this would probably be to have this as a property of the project # returned in the main hash from Project.getFields(). self.basePopup.tabbedFrame.select(1) if self.basePopup.frameShortcuts.has_key('Project'): self.basePopup.frameShortcuts['Project'].drawFrame() def import_project(self): # FIXME JMCI # need to preserve the current status. Take default from the # Wms layer rootDir = self.basePopup.repList.current_import_dir fileSelectPopup = FileSelectPopup(self, None, rootDir) new_project_dir = fileSelectPopup.getDirectory() self.basePopup.repList.current_import_dir = new_project_dir print 'in import project with directory', new_project_dir idx = new_project_dir.rfind('/') new_project_name = new_project_dir[idx + 1:] print 'in import project with project', new_project_name # FIXME # need to set the project version number somewhere. For now set to none # and this gets picked up and set to a default 1.1 later self.repository.import_project(new_project_name, None, new_project_dir) self.drawFrame() def export_project(self): # get the selected node selected_nodes = self.repTree.getSelectedNodes() # restrict the choice to one node = selected_nodes[0] # we really need to traverse the tree a lot more carefully name = node.parent.object.__str__() versionTag = node.object.__str__()[len(name) + 2:] # need to preserve the current status. Take a default from the # Wms layer rootDir = self.basePopup.repList.current_export_dir # This should be obtained from a query box. Hard code for now fileSelectPopup = FileSelectPopup(self, None, rootDir) exp_project_dir = fileSelectPopup.getDirectory() self.basePopup.repList.current_export_dir = exp_project_dir self.repository.export_project(name, versionTag, exp_project_dir) def disconnectRepository(self): # do we need to formally break a connection and destroy the session? # yes we probably should. # need an "are you sure" dialog box # need to protect self.repository.repList.repositories.remove(self.repository) self.grid_remove() for ff in self.guiParent.guiParent.parent.frames[0].children.values(): ff.drawFrame() def tmpCall(self): return # This will need a separate call to the WS with an additional # criterion (picking up the checkout version) def updateRepTree(self): texts = [] icons = [] parents = [] callbacks = [] objects = [] # OK, this would be a good point to access the list # this should be associated with the repository object loc = SharedBeanServiceLocator() port = loc.getSharedBean() request = getList() # these are actually static request._arg0 = 'org.pimslims.applet.server.ProjectBean' request._arg1 = 'getList' request._arg2 = '' # get the response response = port.getList(request) # this is a hack at present. It needs to be written properly wsstr = WSString(response._return) ss = wsstr.getStruct() for strg in ss: texts.append(strg) icons.append('folder') parents.append(None) objects.append(strg) callbacks.append(self.openLink) print 'UPDATE ', ss print 'UPDATE ', len(ss) if len(ss) > 0: print 'UPDATE: updating ' self.repTree.update(parents, objects, texts, icons, callbacks) def administerNotifiers(self, notifyFunc): for func in ('__init__', 'delete', 'setName'): notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.Experiment', func) notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.DataSource', func) def updateAllAfter(self, obj): self.after_idle(self.updateAll) def updateAll(self, project=None): return def quit(self): self.guiParent.parent.destroy() def destroy(self): self.administerNotifiers(self.basePopup.unregisterNotify) Frame.destroy(self)
class DataExchFrame(Frame): def __init__(self, guiParent, basePopup, rep1=None, rep2=None): self.basePopup = basePopup self.guiParent = guiParent # add this to shortcuts to ease navigation self.basePopup.frameShortcuts['DataExch'] = self # FIXME # This is a hack just so that we can see what it would be like # need to set these in a different way!! self.repository1 = self.basePopup.repList.currentRepository self.repository2 = self.basePopup.repList.currentRepository Frame.__init__(self, guiParent) self.grid_columnconfigure(0, weight=0, minsize=10) self.grid_columnconfigure(1, weight=1, minsize=20) self.grid_columnconfigure(2, weight=0, minsize=40) self.grid_columnconfigure(3, weight=1, minsize=20) self.grid_columnconfigure(4, weight=0, minsize=10) self.grid_rowconfigure(0, weight=0, minsize=10) self.grid_rowconfigure(1, weight=0, minsize=10) self.grid_rowconfigure(2, weight=0, minsize=10) self.grid_rowconfigure(3, weight=1, minsize=10) self.grid_rowconfigure(4, weight=0, minsize=10) # build up the body. start really simple self.repLabel1 = Label(self, text='Repository 1') self.repLabel2 = Label(self, text='Repository 2') self.noDataWidgets = [] self.noRep1Label = Label(self,text='No repository currently selected.') self.noDataWidgets.append(self.noRep1Label) self.noRep2Label = Label(self,text='No repository currently selected.') self.noDataWidgets.append(self.noRep2Label) # widgets for view when current repository set self.dataWidgets1 = [] self.label1 = Label(self) self.dataWidgets1.append(self.label1) self.frame1 = Tree(self) self.dataWidgets1.append(self.frame1) self.dataWidgets2 = [] self.label2 = Label(self) self.dataWidgets2.append(self.label2) self.frame2 = Tree(self) self.dataWidgets2.append(self.frame2) self.drawFrame() def drawFrame(self): self.repository1 = self.basePopup.repList.currentRepository self.repository2 = self.basePopup.repList.currentRepository self.repLabel1.grid(row=1, column=1, sticky='n') self.repLabel2.grid(row=1, column=3, sticky='n') if self.repository1 is None: for widget in self.dataWidgets1: widget.grid_remove() self.noRep1Label.grid(row=2, column=1, sticky='n') else : self.noRep1Label.grid_remove() self.label1.set(self.repository1.user + '@' + self.repository1.name + ' ( ' + self.repository1.connect + ' )') self.label1.grid(row=2,column=1, sticky='w') self.frame1.grid(row=3,column=1, sticky='nsew') self.update_tree(self.frame1) if self.repository2 is None: for widget in self.dataWidgets2: widget.grid_remove() self.noRep2Label.grid(row=2, column=3, sticky='n') else: self.noRep2Label.grid_remove() self.label2.set(self.repository2.user + '@' + self.repository2.name + ' ( ' + self.repository2.connect + ' )') self.label2.grid(row=2,column=3, sticky='w') self.frame2.grid(row=3,column=3, sticky='nsew') self.update_tree(self.frame2) def update_tree(self, tree): texts=[] icons=[] parents=[] callbacks=[] objects=[] # OK, this would be a good point to access the list # this should be associated with the repository object loc = SharedBeanServiceLocator() port = loc.getSharedBean() request = getList(); # these are actually static request._arg0 = 'org.pimslims.applet.server.ProjectBean'; request._arg1 = 'getList'; request._arg2 = '' # get the response response = port.getList(request) # this is a hack at present. It needs to be written properly wsstr = WSString(response._return) ss = wsstr.getStruct() for strg in ss: texts.append(strg) icons.append('list-add') parents.append(None) objects.append(strg) callbacks.append(None) print 'UPDATE ', ss print 'UPDATE ', len(ss) if len(ss) > 0: print 'UPDATE: updating ' tree.update(parents, objects, texts, icons, callbacks) def administerNotifiers(self, notifyFunc): for func in ('__init__','delete','setName'): notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.Experiment', func) notifyFunc(self.updateAllAfter, 'ccp.nmr.Nmr.DataSource', func) def updateAllAfter(self, obj): self.after_idle(self.updateAll) def updateAll(self, project=None): if project: self.project = project self.nmrProject = project.currentNmrProject if not self.nmrProject: self.nmrProject = project.newNmrProject(name=project.name) if not self.project: return def quit(self): self.guiParent.parent.destroy() def destroy(self): self.administerNotifiers(self.basePopup.unregisterNotify) Frame.destroy(self)