Exemple #1
0
class ResonanceSelectPopup(BasePopup):
    def __init__(self,
                 parent,
                 resonanceList,
                 resonanceDict,
                 code3Letter,
                 resName,
                 helpText,
                 multi,
                 title='Select resonances'):

        # Constructor doesn't do much except call body
        # The parent is self.parent (parent of the popup)

        self.selectedResonances = None

        self.resonanceList = resonanceList
        self.resonanceDict = resonanceDict
        self.code3Letter = code3Letter
        self.resName = resName
        self.helpText = helpText

        if multi:
            self.selectmode = Tkinter.MULTIPLE
        else:
            self.selectmode = Tkinter.SINGLE

        # modal = true means that it won't continue unless this one returns value
        BasePopup.__init__(self,
                           parent=parent,
                           title=title,
                           modal=True,
                           transient=True)

    def body(self, master):

        master.grid_columnconfigure(0, weight=1)
        for i in range(6):
            master.grid_rowconfigure(i, weight=1)

        self.geometry('600x400')

        #
        # Popup window
        #

        row = 0
        label = Label(master, text="Residue type '%s'" % self.code3Letter)
        label.grid(row=row, column=0, sticky=Tkinter.EW)

        row = row + 1
        label = Label(master, text="Resonance '%s'" % self.resName)
        label.grid(row=row, column=0, sticky=Tkinter.EW)

        row = row + 1
        label = Label(master, text="Pick resonance(s):")
        label.grid(row=row, column=0, sticky=Tkinter.W)

        row = row + 1
        self.list = ScrolledListbox(master,
                                    width=50,
                                    height=5,
                                    selectmode=self.selectmode,
                                    initial_list=self.resonanceList)
        self.list.grid(row=row, column=0, sticky=Tkinter.EW)

        row = row + 1
        label = Label(master, text=self.helpText, fg='blue')
        label.grid(row=row, column=0, sticky=Tkinter.EW)

        row = row + 1
        texts = ['OK']
        commands = [
            self.ok
        ]  # This calls 'ok' in BasePopup, this then calls 'apply' in here
        buttons = createDismissHelpButtonList(master,
                                              texts=texts,
                                              commands=commands)
        buttons.grid(row=row, column=0)

    def apply(self):

        selectedResNames = self.list.getSelectedItems()

        #
        # Return value depends on whether multi or not
        #

        if selectedResNames:
            if type(selectedResNames) == type([]):
                self.selectedResonances = []
                for selectedResName in selectedResNames:
                    self.selectedResonances.append(
                        self.resonanceDict[selectedResName])
            else:
                self.selectedResonances = [
                    self.resonanceDict[selectedResNames]
                ]

        else:
            return False

        return True
Exemple #2
0
class CreateShiftListPopup(BasePopup):

    help_url = joinPath(getHelpUrlDir(), 'CreateShiftList.html')

    def __init__(self, parent, project):

        self.project = project
        self.peakLists = []

        BasePopup.__init__(self,
                           parent=parent,
                           title="Project '%s': " % project.name +
                           'Create shift list from peak lists',
                           modal=False,
                           transient=True)

    def body(self, master):

        #
        # Peaklist setup
        #

        self.peakListDict = {}

        for experiment in self.project.currentNmrProject.sortedExperiments():
            for dataSource in experiment.sortedDataSources():
                for peakList in dataSource.sortedPeakLists():

                    peakListLabel = "%s:%s:%d:%s" % (
                        experiment.name, dataSource.name, peakList.serial,
                        peakList.name)

                    self.peakListDict[peakListLabel] = peakList

        peakListLabels = self.peakListDict.keys()
        peakListLabels.sort()

        #
        # chemical shift list setup
        #

        self.shiftListDict = {}
        self.shiftListDict['None'] = None

        for shiftList in self.project.currentNmrProject.findAllMeasurementLists(
                className='ShiftList'):

            shiftListLabel = "%d:%s" % (shiftList.serial, shiftList.name)

            self.shiftListDict[shiftListLabel] = shiftList

        shiftListLabels = self.shiftListDict.keys()
        shiftListLabels.sort()

        row = 0

        label = Label(master, text="Generation of chemical shift list")
        label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W)

        row += 1

        label = Label(master, text="Peak lists:")
        label.grid(row=row, column=0, sticky=Tkinter.W)

        self.peakListBox = ScrolledListbox(master,
                                           width=50,
                                           height=5,
                                           selectmode=Tkinter.MULTIPLE,
                                           initial_list=peakListLabels)
        self.peakListBox.grid(row=row, column=1, sticky=Tkinter.EW)

        row += 1

        label = Label(master, text="Use existing shift list:")
        label.grid(row=row, column=0, sticky=Tkinter.W)

        self.shiftListSelect = PulldownMenu(master, entries=shiftListLabels)
        self.shiftListSelect.grid(row=row, column=1, sticky=Tkinter.EW)

        row += 1

        label = Label(master, text="Use multiple assignments:")
        label.grid(row=row, column=0, sticky=Tkinter.W)

        self.useAllContribs = CheckButton(master)
        self.useAllContribs.grid(row=row, column=1, sticky=Tkinter.W)

        #
        # Setup the default shift error per nucleus
        #

        self.defaultShiftError = {}

        for (nucl, text, defValue) in [('1H', 'proton', '0.002'),
                                       ('13C', 'carbon', '0.1'),
                                       ('15N', 'nitrogen', '0.1')]:

            row += 1

            label = Label(master, text="Default %s shift error:" % text)
            label.grid(row=row, column=0, sticky=Tkinter.W)

            self.defaultShiftError[nucl] = Entry(master, text=defValue)
            self.defaultShiftError[nucl].grid(row=row,
                                              column=1,
                                              sticky=Tkinter.W)

        row += 1

        texts = ['Create shift list']
        commands = [
            self.ok
        ]  # This calls 'ok' in BasePopup, this then calls 'apply' in here
        buttons = createDismissHelpButtonList(master,
                                              texts=texts,
                                              commands=commands,
                                              help_url=self.help_url)
        buttons.grid(row=row, columnspan=2, column=0)

    def apply(self):

        selectedPeakLists = self.peakListBox.getSelectedItems()

        for peakListLabel in selectedPeakLists:

            self.peakLists.append(self.peakListDict[peakListLabel])

        chemShiftList = self.shiftListDict[self.shiftListSelect.getSelected()]

        if not chemShiftList:

            chemShiftListName = askString("Enter chemical shift list name",
                                          "New chemical shift list name", '',
                                          self)

        else:

            chemShiftListName = chemShiftList.name

        useAllContribs = self.useAllContribs.isSelected()

        defaultShiftError = {}
        for nucl in self.defaultShiftError.keys():
            defaultShiftError[nucl] = returnFloat(
                self.defaultShiftError[nucl].get())

        listCreated = createChemShifts(self.peakLists,
                                       guiParent=self.parent,
                                       multiDialog=self.parent.multiDialog,
                                       shiftList=chemShiftList,
                                       useAllContribs=useAllContribs,
                                       defaultShiftError=defaultShiftError,
                                       shiftListName=chemShiftListName)

        if listCreated:
            showInfo(
                "Success",
                "Succesfully created a chemical shift list from peaklist(s)")

        return True
Exemple #3
0
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 MultiSelectionListSkeleton:
 
  def __init__(self, parent, selectionList, selectionDict = {}, selectedItems = [], title = 'MultiSelect', text = 'MultiSelect', endText = None, dismissText = 'dismiss', urlFile = None, modal = False):
  
    self.selectionList = selectionList
    self.selectionDict = selectionDict
    self.selectedItems = selectedItems
    self.text = text
    self.endText = endText
    self.dismissText = dismissText
    self.isSelectedList = None
    
    self.setUrlFile(urlFile)
    
    self.startBasePopup(parent,title,modal,True)
    
  def startBasePopup(self,parent,title,modal,True):
  
    pass
     
  def setUrlFile(self,urlFile):
  
    self.help_url = None
 
  def body(self, master):
    
    #
    # Popup window
    #

    row = 0
    label = Label(master, text= self.text)
    label.grid(row=row, column=0, sticky=Tkinter.EW)

    row = row + 1
    self.multiSelect = ScrolledListbox(master,
                                       width = 50,
	                                      height = 5,
	                                      selectmode = Tkinter.MULTIPLE,
                                       initial_list = self.selectionList)
    self.multiSelect.grid(row=row, column=0, sticky=Tkinter.E, ipadx = 20)
    master.grid_columnconfigure(0, weight=1)
    master.grid_rowconfigure(row, weight=1)
    
    if self.selectedItems:
      self.multiSelect.setSelectedItems(self.selectedItems)
 
    if self.endText:
      row = row + 1
      label = Label(master, text= self.endText)
      label.grid(row=row, column=0, sticky=Tkinter.EW)
 
    row = row + 1
    texts = [ 'OK' ]
    commands = [ self.ok ]   # This calls 'ok' in BasePopup, this then calls 'apply' in here
    buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text = self.dismissText, help_url=self.help_url)
    buttons.grid(row=row, column=0)
   

  def apply(self):
    
    self.isSelectedList = []
    
    for selectedItem in self.multiSelect.getSelectedItems():
    
      if self.selectionDict.has_key(selectedItem):
        self.isSelectedList.append(self.selectionDict[selectedItem])
      else:
        self.isSelectedList.append(selectedItem)
        
    return True
Exemple #5
0
class WriteMappingPopup(BasePopup):
 
  help_url = joinPath(getHelpUrlDir(),'WriteMapping.html')

  def __init__(self, parent, project):

    self.project = project
    self.selectedFormats = []
    self.defaultText = 'Select file'
    
    self.formats = allFormatsDict.keys()
    self.formats.sort()
     
    BasePopup.__init__(self, parent=parent, title= "Project '%s': " % project.name +  'Write ccpNmr mapping file', modal=False, transient=True)

  def body(self, master):
      
    row = 0
    
    label = Label(master, text= "CcpNmr resonance -> atom mapping file writer.")
    label.grid(row=row, column=0, columnspan = 2, sticky=Tkinter.W)
    
    row += 1
    
    label = Label(master, text= "File formats:")
    label.grid(row=row, column=0, sticky=Tkinter.W)

    self.formatListBox = ScrolledListbox(master, width = 50, height = 5, selectmode = Tkinter.MULTIPLE,
                                       initial_list = self.formats)
    self.formatListBox.grid(row=row, column=1, sticky=Tkinter.EW)
    
    # Default is all formats selected...
    self.formatListBox.setSelectedItems(self.formatListBox.getItems())

    row += 1
    
    label = Label(master, text= "Mapping output file:")
    label.grid(row=row, column=0, sticky=Tkinter.W)

    self.fileButton = Tkinter.Button(master, text = self.defaultText, command = self.selectFile)
    self.fileButton.grid(row=row, column=1, sticky=Tkinter.W)

    row += 1

    texts = [ 'Write mapping' ]
    commands = [ self.ok ]   # This calls 'ok' in BasePopup, this then calls 'apply' in here
    buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url)
    buttons.grid(row=row, columnspan = 2, column=0)

  def selectFile(self):
   
    fileName = self.fileButton.__getitem__('text')
    
    if fileName == self.defaultText:
      fileName = 'ccpNmr.map'
    
    popup = FormatFilePopup(self, file = fileName, component = 'mapping', format = ccpNmr_kw)
    
    if popup.fileSelected:
    
      self.fileButton.config(text = popup.file)      
      popup.destroy()

  def apply(self):
    
    self.selectedFormats = self.formatListBox.getSelectedItems()
    
    fileName = self.fileButton.__getitem__('text')
    
    if fileName == self.defaultText:
      return False
    
    fileCreated = writeMappingFile(self.project,fileName,originalFormats = self.selectedFormats)
    
    if fileCreated:
      showInfo("Success","Succesfully wrote mapping file")
    else:
      showError("Not written","Error writing file %s. File not written" % fileName)
      return False
          
    return True