Example #1
0
  def makeProjectMenu(self):

    importsMenu = Menu(self.mainMenu, tearoff=False)
    importsMenu.add_command(label='Fasta Sequence',command=self.importFastaSeq)
    importsMenu.add_command(label='NMR-STAR 2.1.1', command=self.importNmrStar211)
    importsMenu.add_command(label='NMR-STAR 3.1', command=self.importNmrStar31)
    importsMenu.add_command(label='PDB 3.20',command=self.importPdb)
    importsMenu.add_command(label='PDB Coords',command=self.importPdbCoords)
    #importsMenu.add_command(label='CNS Distance Restraints',command=self.importCnsDistance)

    exportsMenu = Menu(self.mainMenu, tearoff=False)
    exportsMenu.add_command(label='NMR-STAR 3.1', command=self.eciFrame.exportNmrStar31)
    exportsMenu.add_command(label='PDB Coords',command=self.eciFrame.exportPdb)
    #exportsMenu.add_command(label='CNS Distance Restraints',command=self.eciFrame.exportCnsDistance)

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Add various options to the menu and state the functions they call
    menu.add_command(label='New',     shortcut='N', command=self.newProject)
    menu.add_command(label='Open',    shortcut='O', command=self.openProject)
    menu.add_command(label='Close',   shortcut='C', command=self.closeProject)
    menu.add_command(label='Save',    shortcut='S', command=self.saveProject)
    menu.add_command(label='Save As', shortcut='A', command=self.saveAsProject)
    menu.add_cascade(label='Import',  shortcut='I', menu=importsMenu)
    menu.add_cascade(label='Export',  shortcut='E', menu=exportsMenu)
    menu.add_command(label='Quit',    shortcut='Q', command=self.quit)
    menu.add_command(label='Version', shortcut='V', command=self.showVersion)
    self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu)

    menu.options = ['New','Open','Close','Save','Save As','Import','Export','Quit','Version']  
    return menu
Example #2
0
  def makeOtherMenu(self):
    
    # The fonts menu is a pre-created widget
    fontsMenu = FontMenu(self.mainMenu, self.setFont, sizes=(8,10,12),
                         doItalic=0, doBoldItalic=0, tearoff=0)

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Only Fonts option so far
    menu.add_cascade(label='Fonts',          shortcut='F', menu=fontsMenu)
    self.mainMenu.add_cascade(label='Options', shortcut='O', menu=menu)

    menu.options = ['Fonts',]
    return menu
Example #3
0
  def makeAppearanceMenu(self):
    
    # The fonts menu is a pre-created widget
    fontsMenu = FontMenu(self.mainMenu, self.setFont, sizes=(8,10,12),
                         doItalic=0, doBoldItalic=0, tearoff=0)

    # Plot color schemes
    colorMenu = Menu(self.mainMenu, tearoff=0)
    colorMenu.add_radiobutton(label='Red', command=self.colorSchemeRed,)
    colorMenu.add_radiobutton(label='Rainbow', command=self.colorSchemeRainbow,)
    #colorMenu.add_radiobutton(label='Black',   shortcut='B', command=self.colorSchemeBlack)
    #colorMenu.add_radiobutton(label='White',   shortcut='W', command=self.colorSchemeWhite)

    # Submenu of the main menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Only Fonts option so far
    menu.add_cascade(label='Plot Colour Scheme',shortcut='C', menu=colorMenu)
    menu.add_cascade(label='Fonts',             shortcut='F', menu=fontsMenu)
    self.mainMenu.add_cascade(label='Appearance', shortcut='A', menu=menu)

    menu.options = ['Plot Colour Scheme','Fonts']
    return menu
Example #4
0
class DataFileImportGui(BasePopup):

    # TODO CHANGE
    help_url = 'http://www.ebi.ac.uk/pdbe'

    def __init__(self, root):

        self.root = root

        self.font = DEFAULT_FONT
        # Application object needed to store application-specific data with project
        self.application = Application(name=PROGRAM_NAME)
        self.versionInfo = VERSION

        ccpnProjectName = askString(
            "CCPN project name", 'Please give a name to this import session:')

        self.fcWrapper = FormatConverterWrapper(
            ccpnProjectName=ccpnProjectName, guiRoot=self)
        self.project = self.fcWrapper.formatConversion.ccpnProject

        # Application popup is a superclass of memops.editor.BasePoup
        BasePopup.__init__(self,
                           parent=root,
                           title=PROGRAM_NAME,
                           location='+100+100',
                           class_=self.application.name)

        self.setTitle(PROGRAM_NAME)

    def body(self, guiParent):

        self.geometry('600x350')

        # Ensure that the first row and column in popup expand
        guiParent.expandGrid(0, 0)

        self.importFrame = DataFileImportFrame(guiParent,
                                               basePopup=self,
                                               grid=(0, 0))

        # Dictionary to store popups opened by this application - e.g. need to close upon quit
        self.popups = {}

        # Default font
        self.font = DEFAULT_FONT

        # Closing the window from the desktop environment calls the proper quit
        self.protocol('WM_DELETE_WINDOW', self.quit)

        self.mainMenu = Menu(self)
        self.projectMenu = self.makeProjectMenu()

        self.mainMenu.add_command(label='Formats',
                                  shortcut='F',
                                  command=self.importFrame.showFormats)
        self.mainMenu.add_command(
            label='Help',
            shortcut='H',
            command=self.importFrame.showMainInstructions)

        # Put the main menu
        self.config(menu=self.mainMenu)

        self.setMenuState()

    def makeProjectMenu(self):

        # Submenu of the min menu
        menu = Menu(self.mainMenu, tearoff=0)
        menu.add_command(label='Save', shortcut='S', command=self.saveProject)
        menu.add_command(label='Save As',
                         shortcut='A',
                         command=self.saveAsProject)
        menu.add_command(label='Quit', shortcut='Q', command=self.quit)
        menu.add_command(label='Version',
                         shortcut='V',
                         command=self.showVersion)
        self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu)

        menu.options = ['Save', 'Save As', 'Quit', 'Version']
        return menu

    def saveProject(self):

        self.saveFile()

    def saveAsProject(self):

        self.askSaveFile()

    def showVersion(self):

        showInfo('Version', 'Version ' + self.versionInfo, parent=self)

    def setMenuState(self):

        state = Tkinter.NORMAL

        for option in ('Save', 'Save As', 'Quit', 'Version'):
            i = self.projectMenu.options.index(option)
            self.projectMenu.entryconfig(i, state=state)

    def askSaveFile(self):

        popup = self.openPopup('save_project', SaveProjectPopup)
        popup.refresh()

    def modalAskSaveFile(self):

        popup = SaveProjectPopup(self,
                                 project=self.project,
                                 dismiss_text='Cancel Quit',
                                 modal=True)
        did_save = popup.did_save
        popup.destroy()

        return did_save

    def quitSaveProject(self):

        if (self.project.activeRepositories):
            return self.saveFile()
        else:
            return self.modalAskSaveFile()

    """
  def destroyPopups(self):

    for key in self.popups.keys():
      popup = self.popups[key]
      popup.destroy()

    self.popups = {}
  """

    def saveFile(self):

        if not self.project:
            return False

        try:
            saveProject(self.project, createFallback=True)

            print 'successfully saved project'
            return True
        except IOError, e:
            showError('Saving file', str(e), parent=self)
            return False
Example #5
0
class DangleGui(BasePopup):
  """
  **A Bayesian inferential prediction method for protein backbone dihedral angles**
  
  DANGLE (Dihedral ANgles from Global Likelihood Estimates) predicts protein
  backbone Phi and Psi angles and secondary structure assignments solely from
  amino acid sequence information, experimental chemical shifts and a database
  of known protein structures and their associated shifts. This approach
  uses Bayesian inferential logic to analyse the likelihood of conformations
  throughout Ramachandran space, paying explicit attention to the population
  distributions expected for different amino acid residue types.

  Simple filtering procedures can identify the most "predictable" residues,
  yielding 92% of all Phi and Psi predictions accurate to within +/-30 degrees.
  In contrast to previous approaches, more than 80% of Phi or Psi predictions
  for glycine and pre-proline are reliable. Furthermore, DANGLE provides
  meaningful upper and lower bounds for the predictions which are shown to
  represent the precision of the prediction. Over 90% of the experimental
  dihedral angles in the set of test proteins are within the boundary ranges
  suggested by DANGLE. At a lower resolution level, the program correctly
  assigns each residue to one of three secondary structure states (H, E or C) in
  85% of cases.

  DANGLE also provides an indication of the degeneracy in the relationship
  between shift measurements and conformation at each site.

  For more documentation see the `DANGLE web site`_ at SourceForge.
  
  .. _`DANGLE web site`: http://dangle.sourceforge.net/

  **Reference**
  
  *Ming-Sin Cheung, Mahon L. Maguire, Tim J. Stevens, and R. William Broadhurst.
  "DANGLE: A Bayesian inferential method for predicting protein backbone
  dihedral angles and secondary structure." Journal of Magnetic Resonance Volume
  202, Issue 2, February 2010, Pages 223-233*

  """

  def __init__(self, root, programName=PROGRAM_NAME, **kw):

    self.parent = root
    self.programName = programName
    # Application object needed to store application-specific data with project
    self.application = Application(name=PROGRAM_NAME) 
    self.versionInfo = 'Version ' + VERSION
    self.graphPopup  = None
    self.analysisProfile = None
    
    # Application popup is a superclass of memops.editor.BasePoup
    BasePopup.__init__(self, parent=root, title=PROGRAM_NAME,
                       location='+100+100', class_=self.application.name, **kw)
                       
    
  def body(self, guiParent):

    # Ensure that the first row and column in popup expand
    guiParent.grid_rowconfigure(1, weight=1)
    guiParent.grid_columnconfigure(0, weight=1, minsize=200)
    frame = Frame(guiParent) # Body widgets can be put in this frame
    frame.grid(row=1, column=0, sticky='nsew')
    
    frame.grid_rowconfigure(0, weight=1)
    frame.grid_columnconfigure(0, weight=1, minsize=200)

    self.dangleFrame = DangleFrame(frame, self, project=self.project)
    self.dangleFrame.grid(row=0, column=0, sticky='nsew')

    # Dictionary to store popups opened by this application - e.g. need to close upon quit
    self.popups = {}
    
    # Default font
    self.font   = 'Helvetica 10'

    # Closing the window from the desktop environment calls the proper quit
    self.protocol('WM_DELETE_WINDOW', self.quit)

    self.mainMenu    = Menu(self)
    self.projectMenu = self.makeProjectMenu()
    self.viewMenu    = self.viewFileMenu()
    self.otherMenu   = self.makeAppearanceMenu()
    
    # Put the main menu 
    self.config(menu=self.mainMenu)

    self.initProject()

  def makeProjectMenu(self):

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Add various options to the menu and state the functions they call
    menu.add_command(label='New',     shortcut='N', command=self.newProject,
                     tipText='Make a new, blank CCPN project. Closes any existing project')
    menu.add_command(label='Open',    shortcut='O', command=self.openProject,
                     tipText='Open a new CCPN project from disk, closing any existing project')
    menu.add_command(label='Close',   shortcut='C', command=self.closeProject,
                     tipText='Close the current CCPN project')
    menu.add_command(label='Save',    shortcut='S', command=self.saveProject,
                     tipText='Save the current CCPN prjoject at its pre-specified location')
    menu.add_command(label='Save As', shortcut='A', command=self.saveAsProject,
                     tipText='Save the current CCPN project at a new location')
    menu.add_command(label='Backup',  shortcut='B', command=self.backupProject,
                     tipText='Manage options for automatic CCPN project backup')
    menu.add_command(label='Quit',    shortcut='Q', command=self.quit,
                     tipText='Exit from the DANGLE program')
    menu.add_command(label='Version', shortcut='V', command=self.showVersion)
    self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu)

    menu.options = ['New','Open','Close','Save','Save As','Backup','Quit','Version']  
    return menu


  def viewFileMenu(self):

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Add various options to the menu and state the functions they call
    menu.add_command(label='Prediction Graph', shortcut='G', command=self.viewGraph,
                     tipText='Show a graphical view of the poredicted backbone dihedral angles')
    self.mainMenu.add_cascade(label='View', shortcut='V', menu=menu)

    menu.options = ['Prediction Graph']  
    return menu


  def makeAppearanceMenu(self):
    
    # The fonts menu is a pre-created widget
    fontsMenu = FontMenu(self.mainMenu, self.setFont, sizes=(8,10,12),
                         doItalic=0, doBoldItalic=0, tearoff=0)

    # Plot color schemes
    colorMenu = Menu(self.mainMenu, tearoff=0)
    colorMenu.add_radiobutton(label='Red', command=self.colorSchemeRed,)
    colorMenu.add_radiobutton(label='Rainbow', command=self.colorSchemeRainbow,)
    #colorMenu.add_radiobutton(label='Black',   shortcut='B', command=self.colorSchemeBlack)
    #colorMenu.add_radiobutton(label='White',   shortcut='W', command=self.colorSchemeWhite)

    # Submenu of the main menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Only Fonts option so far
    menu.add_cascade(label='Plot Colour Scheme',shortcut='C', menu=colorMenu)
    menu.add_cascade(label='Fonts',             shortcut='F', menu=fontsMenu)
    self.mainMenu.add_cascade(label='Appearance', shortcut='A', menu=menu)

    menu.options = ['Plot Colour Scheme','Fonts']
    return menu

  def colorSchemeRed(self):
  
    self.dangleFrame.colorScheme = 'red'
    
  def colorSchemeRainbow(self):
  
    self.dangleFrame.colorScheme = 'rainbow'

  def colorSchemeBlack(self):
  
    self.dangleFrame.colorScheme = 'black'

  def colorSchemeWhite(self):
  
    self.dangleFrame.colorScheme = 'white'
  
  def viewGraph(self):
    
    phiData, psiData = self.dangleFrame.getPhiPsiPredictions()
    
    if self.graphPopup:
      self.graphPopup.open()
    else:
      self.graphPopup = DangleGraphPopup(self)
    
    dangleChain = self.dangleFrame.dangleChain
    
    good = []
    med = []
    bad = []
    if dangleChain:
      
      resNum = 0 # In case no residues
      
      for dResidue in dangleChain.dangleResidues:
        resNum = dResidue.residue.seqCode
        nIslands = dResidue.numIslands
        
        if nIslands < 2:
          good.append((resNum, nIslands))
        elif nIslands < 4:
          med.append((resNum, nIslands))
        else:
          bad.append((resNum, nIslands))
      
      good.append((resNum, 0)) # To bias the graph
      
    islandData = [good, med, bad]
    
    self.graphPopup.update(phiData,psiData,islandData)
    

  def newProject(self):

    if self.project:
      # Project already present
      if not self.closeProject():
        # If we don't close the current project do nothing
        return

    name = askString(title='Project name', prompt='Enter project name:',parent=self)

    if name:
      # Make the API Project object
      project = Implementation.MemopsRoot(name=name)
      nmrProject = project.newNmrProject(name = project.name)
      self.initProject(project)

  def openProject(self):

    if self.project:
      if not self.closeProject():
        return

    self.openPopup('open_project', OpenProjectPopup, callback=self.initProject)
                   
  def openPopup(self, popup_name, clazz, *args, **kw):

    popup = self.popups.get(popup_name)
  
    if popup:
      popup.open()
      
    else:
      if self.analysisProfile:
        transient = self.analysisProfile.transientWindows
      else:
        transient = True
        
      # Below automatically opens popup
      popup = self.popups[popup_name] = clazz(self, project=self.project, transient=transient, *args, **kw)

    return popup


  def closeProject(self, queryClose=True, querySave=True):

    if queryClose:
      if (not showYesNo('Close project', 'Close current project?')):
        return False

    if querySave:
      if (not self.checkSaving()):
        return False

    self.destroyPopups()
    self.initProject()
 
    return True

  def saveProject(self):

    #if (self.project.isStored):
    self.saveFile()
    #else:
    #  self.askSaveFile()

  def saveAsProject(self):

    self.askSaveFile()

  def backupProject(self):

    pass
    #self.openPopup('backup_project', BackupProjectPopup)

  def showVersion(self):

    showInfo('Version', self.versionInfo, parent=self)


  def setFont(self, fontName=None, popup=None):

    if fontName is None:
      if self.analysisProfile:
        # Get font specification saved as project application data
        self.font = self.analysisProfile.font
    
    else:
      self.font = fontName
      if self.analysisProfile:
        # Set font specification as project application data
        self.analysisProfile.font = fontName
    
    if not popup:
      popup = self
      
    childList = popup.children.values()
    
    classes = [Tkinter.Button,
               Tkinter.Label,
               Tkinter.Menu,
               Tkinter.Entry,
               Tkinter.Checkbutton,
               Tkinter.Radiobutton]
    
    for child in childList:
      for clazz in classes:
        if isinstance(child, clazz):
          if hasattr(child, 'font'):
            if not child.font:
              child.config( font=self.font)
          else:
            child.config( font=self.font )
          break
    
      if hasattr(child, 'children'):
        childList.extend( child.children.values() )

  def initProject(self, project=None):

    if project:
      self.project = project
    else:
      project = self.project
    
    self.setTitle(self.programName)

    if project:
      self.project.application = self.application
      self.setFont()
      self.dangleFrame.updateProject(project)
      self.setupSoftware()

      if not project.currentAnalysisProfile:
        analysisProfiles = project.sortedAnalysisProfiles()
        if analysisProfiles:
          project.currentAnalysisProfile = analysisProfiles[0]
        else:
          project.newAnalysisProfile(name=project.name)
 
      self.analysisProfile = project.currentAnalysisProfile
    
    self.setMenuState()
  
  def setupSoftware(self):
    
     project = self.project
    
     methodStore = project.currentMethodStore or \
                   project.findFirstMethodStore() or \
                   project.newMethodStore(name=project.name)
        
     software = methodStore.findFirstSoftware(name=PROGRAM_NAME, version=VERSION)
     if not software:
       software = methodStore.newSoftware(name=PROGRAM_NAME, version=VERSION)

     #software.vendorName = 'Nicole Cheung'
     #software.vendorAddress = ''
     #software.vendorWebAddress = 'http:'
     #software.details = ''
      
  def setMenuState(self):

    if self.project:
      state = Tkinter.NORMAL
    else:
      state = Tkinter.DISABLED

    # Disable bits of the project menu if there's no project
    for option in ('Save','Save As','Backup','Close'):
      i = self.projectMenu.options.index(option)
      self.projectMenu.entryconfig(i, state=state)

    # Disable bits of the project menu if not stand-alone
    if hasattr(self.parent, 'project'): 
      for option in ('New','Open','Close'):
        i = self.projectMenu.options.index(option)
        self.projectMenu.entryconfig(i, state=Tkinter.DISABLED)

    # Disable other manus and view menu if there's no project
    for menu in [self.otherMenu,self.viewMenu]: # Include more menus in this list
      for i in range(len(menu.options)):
        menu.entryconfig(i, state=state)
      
      
  def askSaveFile(self):

    popup = self.openPopup('save_project', SaveProjectPopup)

  def modalAskSaveFile(self):

    popup = SaveProjectPopup(self, project=self.project, dismiss_text='Cancel Quit',
                             modal=True)
    did_save = popup.did_save
    popup.destroy()

    return did_save

  def quitSaveProject(self):

    if self.project.activeRepositories:
      return self.saveFile()
    else:
      return self.modalAskSaveFile()

  def destroyPopups(self):

    for key in self.popups.keys():
      popup = self.popups[key]
      popup.destroy()

    self.popups = {}

  def saveFile(self):

    if (not self.project):
      return False

    try:
      self.project.saveModified()
      print 'Successfully saved project'
      return True
      
    except IOError, e:
      showError('Saving file', str(e))
      return False
Example #6
0
class ApplicationPopup(BasePopup):

    help_url = 'http://www.ccpn.ac.uk'

    def __init__(self, root, programName='Ccpn Workflow Management System'):

        self.programName = programName
        self.font = DEFAULT_FONT
        # Application object needed to store application-specific data with project
        self.application = Application(name=PROGRAM_NAME)
        self.versionInfo = 'Version ' + VERSION
        self.ariaProjectFile = None

        self.username = None

        # what do these do??
        self.updateFuncs = []
        self.projButtons = []

        # may need these in the end
        self.ariaPaths = []
        self.isdPaths = []

        # FIXME JMCI

        # hard code this for now. this should be initialised from file
        # read during GUI login and then extended using the menu options

        # should set a placeholder. In fact, this placeholder will also have
        # a default user (guest) so that there is always a structure to
        # extend should the user wish to start from scratch and not log in

        self.repList = RepositoryList()
        self.currentTask = None

        # going to stick in shortcuts to frames for quick access
        self.frameShortcuts = {}

        # Application popup is a superclass of memops.editor.BasePoup
        BasePopup.__init__(self,
                           parent=root,
                           title=PROGRAM_NAME,
                           location='+100+100',
                           class_=self.application.name)

        self.setTitle(PROGRAM_NAME)

    def body(self, guiParent):

        self.geometry('700x600')

        # Ensure that the first row and column in popup expand
        guiParent.grid_rowconfigure(0, weight=1)
        guiParent.grid_columnconfigure(0, weight=1, minsize=200)
        frame = Frame(guiParent)  # Body widgets can be put in this frame
        frame.grid()

        # this is going to set up the options on the tabs. Really we need
        # stronger bookeeping between the options and the frames.  it
        # might make sense to define a master dictionary with option_name
        # => index. We can use this dictionary to build up the software
        # options and can also use it to define any refreshes etc (although
        # these would be better done through notifiers)

        softwareOpts = [
            'Repository', 'Project', 'Process', 'Client Tasks', 'Server Tasks',
            'Data Exchange', 'Workflow', 'Protocols', 'User'
        ]

        # FIXME JMCI

        # we should have a tidier tabbed frame. ned to discuss rules with
        # tjs but it would seem to make sense to have the tabs stretch
        # across the entire top of the frame. Check the existing options
        # first, though

        self.tabbedFrame = TabbedFrame(guiParent,
                                       options=softwareOpts,
                                       toggleOff=False,
                                       selected=0)
        self.tabbedFrame.grid(row=0, column=0, sticky='nsew')

        frames = self.tabbedFrame.frames

        # Logos
        ccpnDir = getTopDirectory()
        imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images')
        imageFile = os.path.join(imageDir, 'CcpnLogo.gif')
        self.ccpnLogo = Tkinter.PhotoImage(file=imageFile)

        # Dictionary to store popups opened by this application - e.g. need to close upon quit
        self.popups = {}

        # Default font
        self.font = 'Helvetica 10'

        # Closing the window from the desktop environment calls the proper quit
        self.protocol('WM_DELETE_WINDOW', self.quit)

        # jmci we are going to have to change these drastically
        self.mainMenu = Menu(self)
        self.userMenu = self.makeUserMenu()
        self.repositoryMenu = self.makeRepositoryMenu()
        self.otherMenu = self.makeOtherMenu()

        # Put the top level menu
        self.config(menu=self.mainMenu)
        self.initRepository(frames[0])
        self.initProjectFrame(frames[1])
        self.initWms(frames[2])
        self.initTasks(frames[3])
        self.initDataExch(frames[5])
        self.initWorkflow(frames[6])
        self.initProtocol(frames[7])
        self.initUserFrame(frames[8])

        self.initProject()

        if not self.project:
            for button in self.projButtons:
                button.disable()

        # the main client side daemon. This is going to run in the background
        # and control the task processing
        self.taskDaemon = TaskManager(self)
        self.taskDaemon.active = False
        self.taskDaemon.start()

    ## THE TABBED FRAMES ##

    def initRepository(self, frame):

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        repositoryFrame = RepositoryFrame(frame, basePopup=self)
        repositoryFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(repositoryFrame.updateAll)

    def initProjectFrame(self, frame):

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        self.projectFrame = ProjectFrame(frame, basePopup=self)
        self.projectFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(self.projectFrame.updateAll)

    def initWms(self, frame):

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        extendNmrFrame = ExtendNmrFrame(frame, basePopup=self)
        extendNmrFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(extendNmrFrame.updateAll)

    def initTasks(self, frame):

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        tasksFrame = TasksFrame(frame, self)
        tasksFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(tasksFrame.updateAll)

    def initDataExch(self, frame):

        row = 0
        frame.config(bg='#E6E6E6')

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        dataExchFrame = DataExchFrame(frame, basePopup=self)
        dataExchFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(dataExchFrame.updateAll)

    def initWorkflow(self, frame):

        row = 0
        frame.config(bg='#FFFFFF')

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        workflowFrame = WorkflowFrame(frame, basePopup=self)
        workflowFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(workflowFrame.updateAll)

    def initProtocol(self, frame):

        row = 0
        frame.config(bg='#FFFFFF')

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        protocolFrame = ProtocolFrame(frame, basePopup=self)
        protocolFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(protocolFrame.updateAll)

    def initUserFrame(self, frame):

        frame.grid_columnconfigure(0, weight=1)
        frame.grid_rowconfigure(1, weight=1)

        row = 0
        frame.config(bg='#FFFFFF')

        userFrame = UserFrame(frame, basePopup=self)
        userFrame.grid(row=1, column=0, sticky='nsew')

        self.updateFuncs.append(userFrame.updateAll)

    ## The Menu ##

    def makeUserMenu(self):
        menu = Menu(self.mainMenu, tearoff=0)
        menu.add_command(label='Log In',
                         shortcut='I',
                         command=self.openLoginPopup)
        menu.add_command(label='Log Out', shortcut='O', command=self.logout)
        menu.add_command(label='Save Profile',
                         shortcut='S',
                         command=self.tmpCall)
        menu.add_command(label='View Profile',
                         shortcut='V',
                         command=self.tmpCall)
        menu.add_command(label='Create Profile',
                         shortcut='C',
                         command=self.tmpCall)
        menu.add_command(label='Edit Profile',
                         shortcut='E',
                         command=self.tmpCall)
        self.mainMenu.add_cascade(label='User', shortcut='U', menu=menu)
        menu.options = [
            'Log In', 'Log Out', 'Save Profile', 'View Profile',
            'Create Profile', 'Edit Profile'
        ]
        return menu

    def makeRepositoryMenu(self):
        self.repMenu = Menu(self.mainMenu, tearoff=0)
        # Add various options to the menu and state the functions they call
        self.repMenu.add_command(label='Manager',
                                 shortcut='M',
                                 command=self.tmpCall)
        self.repMenu.add_command(label='Connect',
                                 shortcut='C',
                                 command=self.openRepository)

        # doesn't really work to have a disconnect; we do not have a list
        # of repositories and so would it refer to? Better to do this from
        # within the RepositoryFrame

        self.repMenu.add_command(label='Disconnect',
                                 shortcut='D',
                                 command=self.tmpCall)

        # again, this is functionality that would make sense but which it is hard to put
        # in the top level menu because it is not obvious which repository it refers
        # to

        self.repMenu.add_command(label='Import Project',
                                 shortcut='I',
                                 command=self.tmpCall)
        self.repMenu.add_command(label='Export Project',
                                 shortcut='E',
                                 command=self.tmpCall)

        # FIXME JMCI

        # the quit option needs to be tied to a dialogue box that asks whether
        # the current connection state should be saved. This will have to be
        # secured and so means that the GUI should have a login itself (beyond
        # the logins for the various resources).

        self.repMenu.add_command(label='Quit', shortcut='Q', command=self.quit)

        self.mainMenu.add_cascade(label='Repository',
                                  shortcut='R',
                                  menu=self.repMenu)
        self.repMenu.options = [
            'Connect', 'Disconnect', 'Import Project', 'Export Project', 'Quit'
        ]
        return self.repMenu

    def makeProjectMenu(self):

        # Submenu of the min menu
        menu = Menu(self.mainMenu, tearoff=0)
        # Add various options to the menu and state the functions they call
        menu.add_command(label='New', shortcut='N', command=self.newProject)
        menu.add_command(label='Open', shortcut='O', command=self.openProject)
        menu.add_command(label='Close',
                         shortcut='C',
                         command=self.closeProject)
        menu.add_command(label='Save', shortcut='S', command=self.saveProject)
        menu.add_command(label='Save As',
                         shortcut='A',
                         command=self.saveAsProject)
        menu.add_command(label='Quit', shortcut='Q', command=self.quit)
        menu.add_command(label='Version',
                         shortcut='V',
                         command=self.showVersion)
        self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu)

        menu.options = [
            'New', 'Open', 'Close', 'Save', 'Save As', 'Quit', 'Version'
        ]
        return menu

    def makeOtherMenu(self):

        # The fonts menu is a pre-created widget
        fontsMenu = FontMenu(self.mainMenu,
                             self.setFont,
                             sizes=(8, 10, 12),
                             doItalic=0,
                             doBoldItalic=0,
                             tearoff=0)

        # Submenu of the min menu
        menu = Menu(self.mainMenu, tearoff=0)
        # Only Fonts option so far
        menu.add_cascade(label='Fonts', shortcut='F', menu=fontsMenu)
        self.mainMenu.add_cascade(label='Options', shortcut='O', menu=menu)

        menu.options = [
            'Fonts',
        ]
        return menu

    def makeCcpNmrMenu(self):

        try:
            from ccpnmr.analysis.AnalysisPopup import AnalysisPopup
            haveAnalysis = True
        except ImportError:
            haveAnalysis = False

        try:
            from ccpnmr.format.gui.FormatConverter import FormatConverter
            from ccpnmr.format.gui.DataShifter import DataShifter
            haveFormatConv = True
        except ImportError:
            haveFormatConv = False

        menu = Menu(self.mainMenu, tearoff=0)

        if haveAnalysis:
            menu.add_command(label='Analysis',
                             shortcut='A',
                             command=self.ccpNmrAnalysis)
        else:
            menu.add_command(label='Analysis ** NOT INSTALLED **',
                             shortcut='A',
                             command=None)

        if haveFormatConv:
            menu.add_command(label='Format Converter',
                             shortcut='F',
                             command=self.ccpNmrFormatConverter)
            menu.add_command(label='Data Shifter',
                             shortcut='D',
                             command=self.ccpNmrDataShifter)
        else:
            menu.add_command(label='Format Converter ** NOT INSTALLED **',
                             shortcut='F',
                             command=None)
            menu.add_command(label='Data Shifter ** NOT INSTALLED **',
                             shortcut='D',
                             command=None)

        self.mainMenu.add_cascade(label='CcpNmr', shortcut='C', menu=menu)

        menu.options = ['Analysis', 'Format Converter', 'Data Shifter']
        return menu

    def ccpNmrAnalysis(self, cacheSize=64):

        from ccpnmr.analysis.AnalysisPopup import AnalysisPopup
        analysis = AnalysisPopup(self, cache_size=cacheSize, glDirect=None)
        analysis.update_idletasks()  # fast
        if self.project:
            analysis.initProject(self.project)

    def ccpNmrFormatConverter(self):

        from ccpnmr.format.gui.FormatConverter import FormatConverter
        fc = FormatConverter(self, threading=False, project=self.project)
        fc.open()
        if self.project:
            fc.initProject(self.project)

    def ccpNmrDataShifter(self):

        from ccpnmr.format.gui.DataShifter import DataShifter
        ds = DataShifter(self)
        ds.open()

    def newProject(self):

        if self.project:
            # Project already present
            if not self.closeProject():
                # If we don't close the current project do nothing
                return

        name = askString(title='Project name',
                         prompt='Enter project name:',
                         parent=self)

        if name:
            # Make the API Project object
            project = Implementation.MemopsRoot(name=name)
            nmrProject = project.newNmrProject(name=name)
            self.initProject(project)

    # placeholder method until we write code

    def tmpCall(self):

        return

    def openProject(self):

        if self.project:
            if not self.closeProject():
                return

        self.openPopup('open_project',
                       OpenProjectPopup,
                       callback=self.initProject)

    def openLoginPopup(self):

        # at the moment we do this through methods in the popup. It
        # would be much more sensible to do this through some
        # sort of callback.

        login_popup = LoginPopup(self)

        # really we want to imoblise the rest. how to do?

    def setRepository(self, rep):

        self.repList.currentRepository = rep

        if self.frameShortcuts.has_key('Repository'):
            self.frameShortcuts['Repository'].drawFrame()

        if self.frameShortcuts.has_key('Tasks'):
            self.frameShortcuts['Tasks'].drawFrame()
        #for ff in self.tabbedFrame.frames[0].children.values():
        #  ff.draw()

        #for ff in self.tabbedFrame.frames[3].children.values():
        #  ff.draw()

        for ff in self.tabbedFrame.frames[8].children.values():
            ff.draw()

    def openRepository(self):

        rep_popup = RepositoryPropertiesPopup(self)

    def closeRepository(self):

        pass

    def logout(self):

        self.setUsername(None)
        self.repList = RepositoryList()

        print 'in logout ', self.repList
        print '#########################'

        print self.tabbedFrame.frames[0].__dict__
        print '#########################'

        if self.frameShortcuts.has_key('Repository'):
            self.frameShortcuts['Repository'].drawFrame()

        #for ff in self.tabbedFrame.frames[0].children.values():
        #  ff.draw()
        for ff in self.tabbedFrame.frames[8].children.values():
            ff.draw()

    def openPopup(self, popup_name, clazz, oldStyle=False, *args, **kw):

        popup = self.popups.get(popup_name)

        if (popup):
            popup.open()
        else:
            if self.project:
                analysisProfile = self.analysisProfile
            else:
                analysisProfile = None

            if analysisProfile:
                transient = analysisProfile.transientDialogs
            else:
                transient = True

            name = popup_name

            if (oldStyle):
                popup = self.popups[popup_name] = clazz(self,
                                                        transient=transient,
                                                        *args,
                                                        **kw)
            else:
                popup = self.popups[popup_name] = clazz(self,
                                                        project=self.project,
                                                        popup_name=name,
                                                        transient=transient,
                                                        *args,
                                                        **kw)
            # above automatically opens popup

        return popup

    def closeProject(self, queryClose=True, querySave=True):

        if queryClose:
            if not showYesNo(
                    'Close project', 'Close current project?', parent=self):
                return False

        if querySave:
            if not self.checkSaving():
                return False

        self.destroyPopups()
        self.initProject()

        return True

    def saveProject(self):

        self.saveFile()

        # NBNB Rasmus 22/8/08 changed to fit AnalysisPopup (and removed 'isStored' bug)
        #if (self.project.isStored):
        #  self.saveFile()
        #else:
        #  self.askSaveFile()

    def saveAsProject(self):

        self.askSaveFile()

    def showVersion(self):

        showInfo('Version', self.versionInfo, parent=self)

    def changeFont(self, analysisProfile):

        if analysisProfile is self.analysisProfile:
            if self.font != analysisProfile.font:
                self.font = analysisProfile.font or DEFAULT_FONT
                self.setFont()

    def selectFont(self, font):  # Only called from main menu option

        if self.project:
            self.analysisProfile.font = font

    def setFont(self, font=None, popup=None):

        if font is None:
            font = self.font or DEFAULT_FONT

        else:
            self.font = font

        if not popup:
            popup = self

        childList = popup.children.values()

        classes = [
            Tkinter.Button, Tkinter.Label, Tkinter.Menu, Tkinter.Entry,
            Tkinter.Checkbutton, Tkinter.Radiobutton
        ]

        for child in childList:
            for clazz in classes:
                if isinstance(child, clazz):
                    if hasattr(child, 'font'):
                        if not child.font:
                            child.config(font=font)
                    else:
                        child.config(font=font)
                    break

            if isinstance(child, Tkinter.Frame):
                child.font = font

            elif isinstance(child, ScrolledMatrix):
                child.setFont(font)

            if hasattr(child, 'children'):
                childList.extend(child.children.values())

    def initProject(self, project=None):

        self.project = project
        if project:
            self.initTopObjects(self.project)
            self.project.application = self.application
            self.setFont()
            webBrowser = ProjectWebBrowser(self.top,
                                           popup=self,
                                           project=project)
            #self.helpButton.config(command = lambda url=self.help_url: webBrowser.open(url) )

            for i, func in enumerate(self.updateFuncs):
                func(project)

            for button in self.projButtons:
                button.enable()

            self.setupSoftware()

        else:
            for button in self.projButtons:
                button.disable()

        self.setMenuState()

    def setUsername(self, name):

        self.username = name

        print 'set username ', self.username

    # jmci FIXME

    # need to look into this carefully and analyse the possible
    # states

    def setMenuState(self):

        if self.project:
            state = Tkinter.NORMAL
        else:
            state = Tkinter.DISABLED

        # Disable bits of the project menu if there's no project
        #for option in ('Save','Save As','Close'):
        #  i = self.projectMenu.options.index(option)
        #  self.projectMenu.entryconfig(i, state=state)

        # Disable other manus if there's no project
        #for menu in [self.otherMenu,]: # Include more menus in this list
        #  for i in range(len(menu.options)):
        #    menu.entryconfig(i, state=state)

    def setupSoftware(self):

        project = self.project

        methodStore = project.currentMethodStore or \
                      project.findFirstMethodStore() or \
                      project.newMethodStore(name=project.name)

        software = methodStore.findFirstSoftware(name=PROGRAM_NAME,
                                                 version=VERSION)
        if not software:
            software = methodStore.newSoftware(name=PROGRAM_NAME,
                                               version=VERSION)

        #software.vendorName = 'PDBe & CCPN'
        #software.vendorAddress = ''
        #software.vendorWebAddress = 'http:'
        #software.details = ''

    def askSaveFile(self):

        popup = self.openPopup('save_project', SaveProjectPopup)
        popup.refresh()

    def modalAskSaveFile(self):

        popup = SaveProjectPopup(self,
                                 project=self.project,
                                 dismiss_text='Cancel Quit',
                                 modal=True)
        did_save = popup.did_save
        popup.destroy()

        return did_save

    def quitSaveProject(self):

        if (self.project.activeRepositories):
            return self.saveFile()
        else:
            return self.modalAskSaveFile()

    def destroyPopups(self):

        for key in self.popups.keys():
            popup = self.popups[key]
            popup.destroy()

        self.popups = {}

    ## WMS methods

    # should maybe merge this with setUsername

    # this will read a config file that stores user setups. How this
    # is done TBD so hack for now and just return
    def readConfig(self, userName):

        # this should return the full RepositoryList structure. In reality this
        # will parse from file. set it by hand from here for now for speed
        repList = RepositoryList(userName)

        rep1 = repList.newRepository('remote', 'localhost:8080/HalxService',
                                     'ccpn', 'remote')
        repList.currentRepository = rep1
        # should these be directory objects?
        repList.current_export_dir = '/home/jionides/work/CCPN/test_JMCI_data'
        repList.current_import_dir = '/home/jionides/work/CCPN/test_EXP_data'

        self.repList = repList

        print 'in readconfig '

        self.setRepository(rep1)

        # really should be done through notifiers
        if self.frameShortcuts.has_key('Repository'):
            self.frameShortcuts['Repository'].drawFrame()

        if self.frameShortcuts.has_key('Tasks'):
            self.frameShortcuts['Tasks'].drawFrame()

        if self.frameShortcuts.has_key('DataExch'):
            self.frameShortcuts['DataExch'].drawFrame()

        for ff in self.tabbedFrame.frames[8].children.values():
            ff.draw()

        # want to update the top menu. The idea should be to add a bar item
        # and then to list all the repositories underneath. Clicking on a given
        # repository will set the home repository as current. That seems to
        # be a good sensible way of simplifying the interface in a expected
        # way. We could, alternatively, use tabs.

        opts = {}
        self.repMenu.add('separator', **opts)

        for rep in repList.repositories:
            item = {
                'command': lambda rep=rep: self.setRepository(rep),
                'label': rep.name
            }
            self.repMenu.add('comman', **item)

        self.repMenu.config()

    ## end WMS methods

    def copyModifiedStorages(self):

        modifiedStorages = [
            storage for storage in self.project.storages if storage.isModified
        ]
        if (self.project.isModified):
            modifiedStorages.append(self.project)

        for storage in modifiedStorages:
            self.copyStorage(storage)

    def saveFile(self):

        if not self.project:
            return False

        try:
            saveProject(self.project, createFallback=True)

            print 'successfully saved project'
            return True
        except IOError, e:
            showError('Saving file', str(e), parent=self)
            return False
Example #7
0
class EntryCompletionGui(BasePopup):

  '''
The standalone version of CcpNmr Entry Completion Interface (ECI).  With it, you can complete all the necessary information required for PDB and BMRB data depositions by adding an "Entry" object to your CCPN project. An "Entry" object contains all the information that you wish to deposit with your submission. You can also select chemical shift lists, peak lists, structural restraints, ensembles, etc. and all at the click of a button. In addition, you can add all the meta data that is required for submissions to the PDB and BMRB. This can be done securely on your desktop computer over the duration of your NMR project.
  '''

  help_url = 'http://www.ccpn.ac.uk'

  def __init__(self, root):

    self.root = root

    self.font = DEFAULT_FONT
    # Application object needed to store application-specific data with project
    self.application = Application(name=PROGRAM_NAME)
    self.versionInfo = VERSION
    
    # Application popup is a superclass of memops.editor.BasePoup
    BasePopup.__init__(self, parent=root, title=PROGRAM_NAME,
                       location='+100+100', class_=self.application.name)

    #self.setTitle(PROGRAM_NAME)

                       
  def body(self, guiParent):

    self.geometry('900x750')

    # Ensure that the first row and column in popup expand
    guiParent.expandGrid(0,0)
    
    self.eciFrame = EntryCompletionFrame(guiParent, basePopup=self, grid=(0,0))
 
    # Add help, close buttons
    #buttonList = UtilityButtonList(self.eciFrame.tabbedFrame.sideFrame,
    #                               grid=(0,0), sticky='e')
    
    # Dictionary to store popups opened by this application - e.g. need to close upon quit
    self.popups = {}
    
    # Default font
    self.font   = 'Helvetica 10'

    # Closing the window from the desktop environment calls the proper quit
    self.protocol('WM_DELETE_WINDOW', self.quit)

    self.mainMenu    = Menu(self)
    self.projectMenu = self.makeProjectMenu()
    self.ccpNmrMenu  = self.makeCcpNmrMenu()
    self.otherMenu   = self.makeOtherMenu()
    
    # Put the main menu 
    self.config(menu=self.mainMenu)

    self.initProject()

  def makeProjectMenu(self):

    importsMenu = Menu(self.mainMenu, tearoff=False)
    importsMenu.add_command(label='Fasta Sequence',command=self.importFastaSeq)
    importsMenu.add_command(label='NMR-STAR 2.1.1', command=self.importNmrStar211)
    importsMenu.add_command(label='NMR-STAR 3.1', command=self.importNmrStar31)
    importsMenu.add_command(label='PDB 3.20',command=self.importPdb)
    importsMenu.add_command(label='PDB Coords',command=self.importPdbCoords)
    #importsMenu.add_command(label='CNS Distance Restraints',command=self.importCnsDistance)

    exportsMenu = Menu(self.mainMenu, tearoff=False)
    exportsMenu.add_command(label='NMR-STAR 3.1', command=self.eciFrame.exportNmrStar31)
    exportsMenu.add_command(label='PDB Coords',command=self.eciFrame.exportPdb)
    #exportsMenu.add_command(label='CNS Distance Restraints',command=self.eciFrame.exportCnsDistance)

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Add various options to the menu and state the functions they call
    menu.add_command(label='New',     shortcut='N', command=self.newProject)
    menu.add_command(label='Open',    shortcut='O', command=self.openProject)
    menu.add_command(label='Close',   shortcut='C', command=self.closeProject)
    menu.add_command(label='Save',    shortcut='S', command=self.saveProject)
    menu.add_command(label='Save As', shortcut='A', command=self.saveAsProject)
    menu.add_cascade(label='Import',  shortcut='I', menu=importsMenu)
    menu.add_cascade(label='Export',  shortcut='E', menu=exportsMenu)
    menu.add_command(label='Quit',    shortcut='Q', command=self.quit)
    menu.add_command(label='Version', shortcut='V', command=self.showVersion)
    self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu)

    menu.options = ['New','Open','Close','Save','Save As','Import','Export','Quit','Version']  
    return menu

  def makeOtherMenu(self):
    
    # The fonts menu is a pre-created widget
    fontsMenu = FontMenu(self.mainMenu, self.setFont, sizes=(8,10,12),
                         doItalic=0, doBoldItalic=0, tearoff=0)

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Only Fonts option so far
    menu.add_cascade(label='Fonts',          shortcut='F', menu=fontsMenu)
    self.mainMenu.add_cascade(label='Options', shortcut='O', menu=menu)

    menu.options = ['Fonts',]
    return menu

  def makeCcpNmrMenu(self):

    try:
      from ccpnmr.analysis.AnalysisPopup import AnalysisPopup
      haveAnalysis = True
    except ImportError:
      haveAnalysis = False

    try:
      from ccpnmr.format.gui.FormatConverter import FormatConverter
      from ccpnmr.format.gui.DataShifter import DataShifter
      haveFormatConv = True
    except ImportError:
      haveFormatConv = False
  
    menu = Menu(self.mainMenu, tearoff=0)
    
    if haveAnalysis:
      menu.add_command(label='Analysis',     shortcut='A', command=self.ccpNmrAnalysis)
    else:
      menu.add_command(label='Analysis ** NOT INSTALLED **',     shortcut='A', command=None)
    
    if haveFormatConv:
      menu.add_command(label='Format Converter',  shortcut='F', command=self.ccpNmrFormatConverter)
      menu.add_command(label='Data Shifter',    shortcut='D', command=self.ccpNmrDataShifter)
    else:
      menu.add_command(label='Format Converter ** NOT INSTALLED **',  shortcut='F', command=None)
      menu.add_command(label='Data Shifter ** NOT INSTALLED **',    shortcut='D', command=None)
 
    self.mainMenu.add_cascade(label='CcpNmr', shortcut='C', menu=menu)

    menu.options = ['Analysis','Format Converter','Data Shifter']  
    return menu
  
  def ccpNmrAnalysis(self, cacheSize=64):
  
    from ccpnmr.analysis.AnalysisPopup import AnalysisPopup
    analysis = AnalysisPopup(self, cache_size=cacheSize, glDirect=None)
    analysis.update_idletasks() # fast
    if self.project:
       analysis.initProject(self.project)
       
  def ccpNmrFormatConverter(self):
  
    from ccpnmr.format.gui.FormatConverter import FormatConverter
    fc = FormatConverter(self,threading=False,project=self.project)
    fc.open()
    if self.project:
      fc.initProject(self.project)
      
  def ccpNmrDataShifter(self):
    
    from ccpnmr.format.gui.DataShifter import DataShifter
    ds = DataShifter(self)
    ds.open()

  def newProject(self):

    if self.project:
      # Project already present
      if not self.closeProject():
        # If we don't close the current project do nothing
        return

    name = askString(title='Project name', prompt='Enter project name:',parent=self)

    if name:
      # Make the API Project object
      project = Implementation.MemopsRoot(name=name)
      nmrProject = project.newNmrProject(name=name)
      self.initProject(project)

  def openProject(self):

    if self.project:
      if not self.closeProject():
        return

    self.openPopup('open_project', OpenProjectPopup,
                   callback=self.initProject)

  def openPopup(self, popup_name, clazz, oldStyle=False, *args, **kw):

    popup = self.popups.get(popup_name)
  
    if (popup):
      popup.open()
    else:
      if self.project:
        analysisProfile = self.analysisProfile
      else:
        analysisProfile = None
      
      if analysisProfile:
        transient = analysisProfile.transientDialogs
      else:
        transient = True
      
      name = popup_name
      
      if (oldStyle):
        popup = self.popups[popup_name] = clazz(self, transient=transient, *args, **kw)
      else:
        popup = self.popups[popup_name] = clazz(self, project=self.project, popup_name=name,
                                                transient=transient, *args, **kw)
      # above automatically opens popup

    return popup

  def closeProject(self, queryClose = True, querySave = True):

    if queryClose:
      if not showYesNo('Close project', 'Close current project?', parent=self):
        return False

    if querySave:
      if not self.checkSaving():
        return False

    self.destroyPopups()
    self.initProject()
 
    return True

  def saveProject(self):

    self.saveFile()

  def saveAsProject(self):

    self.askSaveFile()

  def importNmrStar211(self):

    if not self.project:
      showWarning('Failure','Please create a new CCPN project.', parent=self)
      return

    fileTypes = [ FileType('STAR', ['*.str']),
                  FileType('All', ['*'])]

    fileSelectPopup = FileSelectPopup(self, file_types=fileTypes,
                        title='Import NMR-STAR 2.1.1 file', dismiss_text='Cancel',
                        selected_file_must_exist=True, multiSelect=False,)

    fileName = fileSelectPopup.getFile()

    if not os.path.exists(fileName):
      showWarning('Failure','No such file.', parent=self)
      return

    if fileName:
      nmrStarObj = NmrStarFormat(self.project, self, verbose=True)
      nmrStarObj.readProject(fileName, minimalPrompts=True, version='2.1.1')

      self.eciFrame.updateAll()

      return nmrStarObj

  def importNmrStar31(self):

    if not self.project:
      showWarning('Failure','Please create a new CCPN project.', parent=self)
      return

    fileTypes = [ FileType('STAR', ['*.str']),
                  FileType('All', ['*'])]

    fileSelectPopup = FileSelectPopup(self, file_types=fileTypes,
                        title='Import NMR-STAR 3.1 file', dismiss_text='Cancel',
                        selected_file_must_exist=True, multiSelect=False,)

    fileName = fileSelectPopup.getFile()

    if not os.path.exists(fileName):
      showWarning('Failure','No such file.', parent=self)
      return

    if fileName:
      nmrStarObj = NmrStarFormat(self.project, self, verbose=True)
      nmrStarObj.readProject(fileName, minimalPrompts=True, version='3.1')

      self.eciFrame.updateAll()

      return nmrStarObj

  def importPdb(self):

    if not self.project:
      showWarning('Failure','Please create a new CCPN project.', parent=self)
      return

    fileTypes = [ FileType('PDB', ['*.pdb']),
                  FileType('PDB Entry', ['*.ent']),
                  FileType('All', ['*']) ]

    fileSelectPopup = FileSelectPopup(self, file_types=fileTypes,
                        title='Import PDB 3.20 file', dismiss_text='Cancel',
                        selected_file_must_exist=True, multiSelect=False,)

    fileName = fileSelectPopup.getFile()

    if not os.path.exists(fileName):
      showWarning('Failure','No such file.', parent=self)
      return

    if fileName:
      name = os.path.split(fileName)[1]
      if '.' in name:
        name = name.split('.')[0]

      pdbObj = ReadPdb(fileName, self.project, 'PDB_'+ name, self)

      self.eciFrame.updateAll()

      return pdbObj

  def importCnsDistance(self):

    if not self.project:
      showWarning('Failure','Please create a new CCPN project.', parent=self)
      return

    fileTypes = [ FileType('CNS', ['*.tbl']),
                  FileType('All', ['*']) ]

    fileSelectPopup = FileSelectPopup(self, file_types=fileTypes,
                        title='Import CNS distance restraints file', dismiss_text='Cancel',
                        selected_file_must_exist=True, multiSelect=False,)

    fileName = fileSelectPopup.getFile()

    if not os.path.exists(fileName):
      showWarning('Failure','No such file.', parent=self)
      return

    if fileName:
      name = os.path.split(fileName)[1]
      if '.' in name:
        name = name.split('.')[0]

      cnsObj = CnsFormat(self.project, self, verbose=True)
      cnsObj.readDistanceConstraints(fileName, minimalPrompts=True)

      self.eciFrame.updateAll()

      return cnsObj

  def importFastaSeq(self):

    if not self.project:
      showWarning('Failure','Please create a new CCPN project.', parent=self)
      return

    fileTypes = [ FileType('Fasta', ['*.fsa']),
                  FileType('All', ['*']) ]

    fileSelectPopup = FileSelectPopup(self, file_types=fileTypes,
                        title='Import Fasta sequence file', dismiss_text='Cancel',
                        selected_file_must_exist=True, multiSelect=False,)

    fileName = fileSelectPopup.getFile()

    if not os.path.exists(fileName):
      showWarning('Failure','No such file.', parent=self)
      return

    if fileName:
      name = os.path.split(fileName)[1]
      if '.' in name:
        name = name.split('.')[0]

      fastaObj = FastaFormat(self.project, self, verbose=True)
      fastaObj.readSequence(fileName, minimalPrompts=True)

      self.eciFrame.updateAll()

      return fastaObj

  def importPdbCoords(self):

    if not self.project:
      showWarning('Failure','Please create a new CCPN project.', parent=self)
      return

    fileTypes = [ FileType('PDB', ['*.pdb']),
                  FileType('PDB Entry', ['*.ent']),
                  FileType('All', ['*']) ]

    fileSelectPopup = FileSelectPopup(self, file_types=fileTypes,
                        title='Import PDB coordinates file', dismiss_text='Cancel',
                        selected_file_must_exist=True, multiSelect=False,)

    fileName = fileSelectPopup.getFile()

    if not os.path.exists(fileName):
      showWarning('Failure','No such file.', parent=self)
      return

    if fileName:
      name = os.path.split(fileName)[1]
      if '.' in name:
        name = name.split('.')[0]

      pdbObj = PseudoPdbFormat(self.project, self, verbose=True)
      pdbObj.readCoordinates(fileName, minimalPrompts=True)

      self.eciFrame.updateAll()

      return pdbObj

  def showVersion(self):

    showInfo('Version', 'Version ' + self.versionInfo, parent=self)

  def changeFont(self, analysisProfile):
  
    if analysisProfile is self.analysisProfile:
      if self.font != analysisProfile.font:
        self.font = analysisProfile.font or DEFAULT_FONT 
        self.setFont()
      
  def selectFont(self, font): # Only called from main menu option
    
    if self.project:
      self.analysisProfile.font = font    

  def setFont(self, font=None, popup=None):

    if font is None:
      font = self.font or DEFAULT_FONT 
          
    else:
      self.font = font

    if not popup:
      popup = self
    
    childList = popup.children.values()
    
    classes = [Tkinter.Button,
               Tkinter.Label,
               Tkinter.Menu,
               Tkinter.Entry,
               Tkinter.Checkbutton,
               Tkinter.Radiobutton]
    
    for child in childList:
      for clazz in classes:
        if isinstance(child, clazz):
          if hasattr(child, 'font'):
            if not child.font:
              child.config( font=font)
          else:
            child.config( font=font )
          break
    
      if isinstance(child, Tkinter.Frame):
        child.font = font
      
      elif isinstance(child, ScrolledMatrix):
        child.setFont(font)  
    
      if hasattr(child, 'children'):
        childList.extend( child.children.values() )
        
  def initProject(self, project=None):

    self.project = project

    if project:
      self.initTopObjects(self.project)
      self.project.application = self.application
      self.setFont()
      webBrowser = ProjectWebBrowser(self.top, popup=self, project=project)
      
      self.setupSoftware()
      self.eciFrame.updateAll(project)
      
    
    self.setMenuState()
  
  def setupSoftware(self):
    
     project = self.project
    
     methodStore = project.currentMethodStore or \
                   project.findFirstMethodStore() or \
                   project.newMethodStore(name=project.name)
        
     software = methodStore.findFirstSoftware(name=PROGRAM_NAME, version=VERSION)
     if not software:
       software = methodStore.newSoftware(name=PROGRAM_NAME, version=VERSION)

     software.vendorName = 'PDBe & CCPN'
     #software.vendorAddress = ''
     software.vendorWebAddress = 'http://www.ebi.ac.uk/pdbe/'
     software.details = 'The PDBe & CCPN Entry Completion Interface'
     software.tasks = ['data deposition']

  def setMenuState(self):

    if self.project:
      state = Tkinter.NORMAL
    else:
      state = Tkinter.DISABLED

    # Disable bits of the project menu if there's no project
    for option in ('Close','Save','Save As',):
      i = self.projectMenu.options.index(option)
      self.projectMenu.entryconfig(i, state=state)

    # Disable other menus if there's no project
    for menu in [self.otherMenu,]: # Include more menus in this list
      for i in range(len(menu.options)):
        menu.entryconfig(i, state=state)
      
      
  def askSaveFile(self):

    popup = self.openPopup('save_project', SaveProjectPopup)
    popup.refresh()

  def modalAskSaveFile(self):

    popup = SaveProjectPopup(self, project=self.project, dismiss_text='Cancel Quit',
                             modal=True)
    did_save = popup.did_save
    popup.destroy()

    return did_save

  def quitSaveProject(self):

    if (self.project.activeRepositories):
      return self.saveFile()
    else:
      return self.modalAskSaveFile()

  def destroyPopups(self):

    for key in self.popups.keys():
      popup = self.popups[key]
      popup.destroy()

    self.popups = {}

  def copyModifiedStorages(self):

    modifiedStorages = [storage for storage in self.project.storages if storage.isModified]
    if (self.project.isModified):
      modifiedStorages.append(self.project)

    for storage in modifiedStorages:
      self.copyStorage(storage)

  def saveFile(self):

    if not self.project:
      return False

    try:
      saveProject(self.project, createFallback=True)

      print 'successfully saved project'
      return True
    except IOError, e:
      showError('Saving file', str(e), parent=self)
      return False
Example #8
0
    def setProjectMenu(self):
        ProjectMenu = 'Project'

        # Imports submenu

        importsMenu = Menu(self.menubar, tearoff=False)
        importsMenu.add_command(label='Via Format Converter',
                                shortcut='F',
                                command=self.runFormatConverter)
        importsMenu.add_command(label='NMR-STAR 2.1.1',
                                command=self.importNmrStar211)
        importsMenu.add_command(label='NMR-STAR 3.1',
                                shortcut='N',
                                command=self.importNmrStar31)
        importsMenu.add_command(label='PDB 3.20',
                                shortcut='P',
                                command=self.importPdb)
        importsMenu.add_command(label='Coordinates (PDB-style)',
                                shortcut='C',
                                command=self.importCoordinates)

        # Preferences submenu

        fontsMenu = FontMenu(self.menubar,
                             self.selectFont,
                             sizes=(8, 10, 12),
                             doItalic=False,
                             doBoldItalic=False,
                             tearoff=0)

        prefsMenu = Menu(self.menubar, tearoff=False)
        prefsMenu.add_cascade(
            label='Fonts',
            shortcut='F',
            image=self.iconFont,
            compound='left',
            menu=fontsMenu,
            tipText='Select font to use in the graphical interface')
        prefsMenu.add_command(label='Colour Schemes',
                              image=self.iconTable,
                              compound='left',
                              shortcut='C',
                              tipText='Edit and create colour schemes',
                              command=self.editColorSchemes)
        prefsMenu.add_command(
            label='Residue Codes',
            image=self.iconTable,
            compound='left',
            shortcut='R',
            tipText=
            'User-specified codes that override the standard residue names',
            command=self.editResidueCodes)
        prefsMenu.add_command(label='User Options',
                              image=self.iconTable,
                              compound='left',
                              shortcut='U',
                              tipText='General options for Analysis behaviour',
                              command=self.editProfiles)

        #

        menu = Menu(self.menubar, tearoff=0)
        menu.add_command(
            label='New',
            shortcut='N',
            image=self.iconNewWindow,
            compound='left',
            command=self.newProject,
            tipText='Create a new, blank CCPN project (closes any open project)'
        )
        menu.add_command(
            label='Open Project',
            shortcut='O',
            image=self.iconOpen,
            compound='left',
            command=self.openProject,
            tipText=
            'Open a new CCPN project by selecting a project directory on disk')
        menu.add_command(
            label='Open Spectra',
            shortcut='p',
            image=self.iconOpenFile,
            compound='left',
            command=self.openSpectrum,
            tipText=
            'Open spectrum data fom disk, creating a default CCPN project if needed'
        )
        menu.add_command(label='Save',
                         shortcut='S',
                         image=self.iconSave,
                         compound='left',
                         command=self.saveProject,
                         tipText='Save the current CCPN project on disk')
        menu.add_command(
            label='Save As',
            shortcut='A',
            image=self.iconSaveAs,
            compound='left',
            command=self.saveAsProject,
            tipText=
            'Save the current CCPN project under a different name (project directory)'
        )
        menu.add_cascade(label='Import',
                         shortcut='I',
                         image=self.iconImport,
                         compound='left',
                         menu=importsMenu)
        menu.add_command(label='Close',
                         shortcut='C',
                         image=self.iconClose,
                         compound='left',
                         command=self.closeProject,
                         tipText='Close the current CCPN project')
        menu.add_command(
            label='Quit',
            shortcut='Q',
            image=self.iconQuit,
            compound='left',
            command=self.quit,
            tipText='Quit Extend-NMR, closing any open CCPN project')
        menu.add_separator()
        menu.add_cascade(label='Preferences',
                         shortcut='P',
                         image=self.iconPrefs,
                         compound='left',
                         menu=prefsMenu)
        menu.add_command(
            label='Validate',
            shortcut='V',
            image=self.iconTool,
            compound='left',
            command=self.validateProject,
            tipText=
            'Check the current CCPN project for data model consistency errors')
        menu.add_command(
            label='Backup',
            shortcut='B',
            image=self.iconTool,
            compound='left',
            command=self.backupProject,
            tipText='Setup options for automated backup of CCPN project data')
        menu.add_command(
            label='Archive',
            shortcut='r',
            image=self.iconTool,
            compound='left',
            command=self.archiveProject,
            tipText=
            'Save the current CCPN project in an archived form, e.g. tar gzipped'
        )

        self.menubar.add_cascade(label=ProjectMenu, shortcut='j', menu=menu)
        self.menus[ProjectMenu] = menu
        self.menu_items[ProjectMenu] = [
            'New',
            'Open Project',
            'Open Spectra',
            'Save',
            'Save As',
            'Import',
            'Close',
            'Quit',
            'Preferences',
            'Validate',
            'Backup',
            'Archive',
        ]

        # Menus that area ctive in absence of a project
        #for ii in (0,1,2,7,13,15):
        for ii in (
                0,
                1,
                2,
                7,
        ):
            self.fixedActiveMenus[(ProjectMenu, ii)] = True
Example #9
0
    def body(self, guiParent):

        self.menus = {}
        self.menu_items = {}

        self.fixedActiveMenus = {}

        self.popups = {}

        self.callbacksDict = {}

        self.selected_objects = []

        self.menubar = menubar = Menu(guiParent)

        self.font = DEFAULT_FONT

        self.setProjectMenu()
        #

        menu = Menu(self.menubar, tearoff=0)
        menu.bind('<Button>', self.printAnalysisCommandLineInfo)
        self.menubar.add_cascade(label='CcpNmr Analysis',
                                 shortcut='C',
                                 menu=menu)
        self.menubar.add_command(label='FormatConverter',
                                 shortcut='F',
                                 command=self.runFormatConverter)

        self.menubar = menu
        self.initProject()
        self.setPeaksMenu()
        self.setMoleculeMenu()
        self.setAssignMenu()
        self.setResonanceMenu()
        self.setDataMenu()
        self.setStructureMenu()
        self.setChartMenu()
        self.setMacroMenu()
        self.setOtherMenu()
        self.setMenuState()  # need to do it again because of OtherMenu state

        # Help Submenu

        helpMenu = Menu(self.menubar, tearoff=0)
        helpMenu.add_command(label='Version',
                             shortcut='V',
                             command=self.showVersion)
        helpMenu.add_command(label='About',
                             shortcut='A',
                             command=self.showAbout)
        helpMenu.add_command(label='Help', shortcut='H', command=self.showHelp)

        menu.add_separator()
        menu.add_command(label='CCPN Updates',
                         shortcut='U',
                         image=self.iconRefresh,
                         compound='left',
                         command=self.updateAnalysis,
                         tipText='Get any new patches and updates to CcpNmr')
        menu.add_cascade(label='CCPN Help',
                         shortcut='H',
                         image=self.iconHelp,
                         compound='left',
                         menu=helpMenu)

        self.config(menu=menubar)

        # Ensure that the first row and column in popup expand
        guiParent.grid_rowconfigure(0, weight=1)
        guiParent.grid_columnconfigure(0, weight=1, minsize=200)
        frame = Frame(guiParent)  # Body widgets can be put in this frame
        frame.grid()

        softwareOpts = [
            'Extend-NMR', 'ARIA 2', 'Auremol', 'CING', ' ECI ', 'HADDOCK',
            ' ISD ', 'PRODECOMP'
        ]

        self.tabbedFrame = TabbedFrame(guiParent,
                                       options=softwareOpts,
                                       toggleOff=False,
                                       selected=0,
                                       callback=self.toggleTab)
        self.tabbedFrame.grid(row=0, column=0, sticky='nsew')

        frames = self.tabbedFrame.frames

        # Logos
        ccpnDir = getTopDirectory()

        imageDir = os.path.join(ccpnDir, 'python', 'extendNmr', 'images')

        imageFile = os.path.join(imageDir, 'Fp6Logo.gif')
        self.fp6Logo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'CingLogo.gif')
        self.cingLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'AriaLogo.gif')
        self.ariaLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'IsdLogo.gif')
        self.isdLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'HaddockLogo.gif')
        self.haddockLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'AuremolLogo.gif')
        self.auremolLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'CcpnLogo.gif')
        self.ccpnLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'ProdecompLogo.gif')
        self.prodecompLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'MddLogo.gif')
        self.mddLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'BrukerLogo.gif')
        self.brukerLogo = Tkinter.PhotoImage(file=imageFile)
        imageFile = os.path.join(imageDir, 'MsdLogo.gif')
        self.msdLogo = Tkinter.PhotoImage(file=imageFile)

        self.initExtendNmr(frames[0])

        self.initAria(frames[1])

        self.initAuremol(frames[2])

        self.initCing(frames[3])

        self.initEci(frames[4])

        self.initHaddock(frames[5])

        self.initIsd(frames[6])

        self.initProdecomp(frames[7])

        self.initProject(self.project)

        if not self.project:
            for button in self.projButtons:
                button.disable()

        self.geometry('680x670')
Example #10
0
class EntryCompletionGui(BasePopup):

  help_url = 'http://www.ccpn.ac.uk'

  def __init__(self, root):

    self.font = DEFAULT_FONT
    # Application object needed to store application-specific data with project
    self.application = Application(name=PROGRAM_NAME)
    self.versionInfo = VERSION
    
    # Application popup is a superclass of memops.editor.BasePoup
    BasePopup.__init__(self, parent=root, title=PROGRAM_NAME,
                       location='+100+100', class_=self.application.name)

    #self.setTitle(PROGRAM_NAME)

                       
  def body(self, guiParent):

    self.geometry('800x750')

    # Ensure that the first row and column in popup expand
    guiParent.expandGrid(0,0)
    
    self.eciFrame = EntryCompletionFrame(guiParent, basePopup=self, grid=(0,0))
 
    # Add help, close buttons
    #buttonList = UtilityButtonList(self.eciFrame.tabbedFrame.sideFrame,
    #                               grid=(0,0), sticky='e')
    
    # Dictionary to store popups opened by this application - e.g. need to close upon quit
    self.popups = {}
    
    # Default font
    self.font   = 'Helvetica 10'

    # Closing the window from the desktop environment calls the proper quit
    self.protocol('WM_DELETE_WINDOW', self.quit)

    self.mainMenu    = Menu(self)
    self.projectMenu = self.makeProjectMenu()
    self.ccpNmrMenu  = self.makeCcpNmrMenu()
    self.otherMenu   = self.makeOtherMenu()
    
    # Put the main menu 
    self.config(menu=self.mainMenu)

    self.initProject()

  def makeProjectMenu(self):

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Add various options to the menu and state the functions they call
    menu.add_command(label='New',     shortcut='N', command=self.newProject)
    menu.add_command(label='Open',    shortcut='O', command=self.openProject)
    menu.add_command(label='Close',   shortcut='C', command=self.closeProject)
    menu.add_command(label='Save',    shortcut='S', command=self.saveProject)
    menu.add_command(label='Save As', shortcut='A', command=self.saveAsProject)
    menu.add_command(label='Quit',    shortcut='Q', command=self.quit)
    menu.add_command(label='Version', shortcut='V', command=self.showVersion)
    self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu)

    menu.options = ['New','Open','Close','Save','Save As','Quit','Version']  
    return menu

  def makeOtherMenu(self):
    
    # The fonts menu is a pre-created widget
    fontsMenu = FontMenu(self.mainMenu, self.setFont, sizes=(8,10,12),
                         doItalic=0, doBoldItalic=0, tearoff=0)

    # Submenu of the min menu
    menu = Menu(self.mainMenu, tearoff=0)
    # Only Fonts option so far
    menu.add_cascade(label='Fonts',          shortcut='F', menu=fontsMenu)
    self.mainMenu.add_cascade(label='Options', shortcut='O', menu=menu)

    menu.options = ['Fonts',]
    return menu

  def makeCcpNmrMenu(self):

    try:
      from ccpnmr.analysis.AnalysisPopup import AnalysisPopup
      haveAnalysis = True
    except ImportError:
      haveAnalysis = False

    try:
      from ccpnmr.format.gui.FormatConverter import FormatConverter
      from ccpnmr.format.gui.DataShifter import DataShifter
      haveFormatConv = True
    except ImportError:
      haveFormatConv = False
  
    menu = Menu(self.mainMenu, tearoff=0)
    
    if haveAnalysis:
      menu.add_command(label='Analysis',     shortcut='A', command=self.ccpNmrAnalysis)
    else:
      menu.add_command(label='Analysis ** NOT INSTALLED **',     shortcut='A', command=None)
    
    if haveFormatConv:
      menu.add_command(label='Format Converter',  shortcut='F', command=self.ccpNmrFormatConverter)
      menu.add_command(label='Data Shifter',    shortcut='D', command=self.ccpNmrDataShifter)
    else:
      menu.add_command(label='Format Converter ** NOT INSTALLED **',  shortcut='F', command=None)
      menu.add_command(label='Data Shifter ** NOT INSTALLED **',    shortcut='D', command=None)
 
    self.mainMenu.add_cascade(label='CcpNmr', shortcut='C', menu=menu)

    menu.options = ['Analysis','Format Converter','Data Shifter']  
    return menu
  
  def ccpNmrAnalysis(self, cacheSize=64):
  
    from ccpnmr.analysis.AnalysisPopup import AnalysisPopup
    analysis = AnalysisPopup(self, cache_size=cacheSize, glDirect=None)
    analysis.update_idletasks() # fast
    if self.project:
       analysis.initProject(self.project)
       
  def ccpNmrFormatConverter(self):
  
    from ccpnmr.format.gui.FormatConverter import FormatConverter
    fc = FormatConverter(self,threading=False,project=self.project)
    fc.open()
    if self.project:
      fc.initProject(self.project)
      
  def ccpNmrDataShifter(self):
    
    from ccpnmr.format.gui.DataShifter import DataShifter
    ds = DataShifter(self)
    ds.open()

  def newProject(self):

    if self.project:
      # Project already present
      if not self.closeProject():
        # If we don't close the current project do nothing
        return

    name = askString(title='Project name', prompt='Enter project name:',parent=self)

    if name:
      # Make the API Project object
      project = Implementation.MemopsRoot(name=name)
      nmrProject = project.newNmrProject(name=name)
      self.initProject(project)

  def openProject(self):

    if self.project:
      if not self.closeProject():
        return

    self.openPopup('open_project', OpenProjectPopup,
                   callback=self.initProject)

  def openPopup(self, popup_name, clazz, oldStyle=False, *args, **kw):

    popup = self.popups.get(popup_name)
  
    if (popup):
      popup.open()
    else:
      if self.project:
        analysisProfile = self.analysisProfile
      else:
        analysisProfile = None
      
      if analysisProfile:
        transient = analysisProfile.transientDialogs
      else:
        transient = True
      
      name = popup_name
      
      if (oldStyle):
        popup = self.popups[popup_name] = clazz(self, transient=transient, *args, **kw)
      else:
        popup = self.popups[popup_name] = clazz(self, project=self.project, popup_name=name,
                                                transient=transient, *args, **kw)
      # above automatically opens popup

    return popup


  def closeProject(self, queryClose = True, querySave = True):

    if queryClose:
      if not showYesNo('Close project', 'Close current project?', parent=self):
        return False

    if querySave:
      if not self.checkSaving():
        return False

    self.destroyPopups()
    self.initProject()
 
    return True

  def saveProject(self):

    self.saveFile()

  def saveAsProject(self):

    self.askSaveFile()

  def showVersion(self):

    showInfo('Version', 'Version ' + self.versionInfo, parent=self)


  def changeFont(self, analysisProfile):
  
    if analysisProfile is self.analysisProfile:
      if self.font != analysisProfile.font:
        self.font = analysisProfile.font or DEFAULT_FONT 
        self.setFont()
      
  def selectFont(self, font): # Only called from main menu option
    
    if self.project:
      self.analysisProfile.font = font    

  def setFont(self, font=None, popup=None):

    if font is None:
      font = self.font or DEFAULT_FONT 
          
    else:
      self.font = font

    if not popup:
      popup = self
    
    childList = popup.children.values()
    
    classes = [Tkinter.Button,
               Tkinter.Label,
               Tkinter.Menu,
               Tkinter.Entry,
               Tkinter.Checkbutton,
               Tkinter.Radiobutton]
    
    for child in childList:
      for clazz in classes:
        if isinstance(child, clazz):
          if hasattr(child, 'font'):
            if not child.font:
              child.config( font=font)
          else:
            child.config( font=font )
          break
    
      if isinstance(child, Tkinter.Frame):
        child.font = font
      
      elif isinstance(child, ScrolledMatrix):
        child.setFont(font)  
    
      if hasattr(child, 'children'):
        childList.extend( child.children.values() )
        
  def initProject(self, project=None):

    self.project = project

    if project:
      self.initTopObjects(self.project)
      self.project.application = self.application
      self.setFont()
      webBrowser = ProjectWebBrowser(self.top, popup=self, project=project)
      
      self.setupSoftware()
      self.eciFrame.updateAll(project)
      
    
    self.setMenuState()
  
  def setupSoftware(self):
    
     project = self.project
    
     methodStore = project.currentMethodStore or \
                   project.findFirstMethodStore() or \
                   project.newMethodStore(name=project.name)
        
     software = methodStore.findFirstSoftware(name=PROGRAM_NAME, version=VERSION)
     if not software:
       software = methodStore.newSoftware(name=PROGRAM_NAME, version=VERSION)

     software.vendorName = 'PDBe & CCPN'
     #software.vendorAddress = ''
     software.vendorWebAddress = 'http://www.ebi.ac.uk/pdbe/'
     software.details = 'The PDBe & CCPN Entry Completion Interface'
     software.tasks = ['data deposition']

  def setMenuState(self):

    if self.project:
      state = Tkinter.NORMAL
    else:
      state = Tkinter.DISABLED

    # Disable bits of the project menu if there's no project
    for option in ('Close','Save','Save As',):
      i = self.projectMenu.options.index(option)
      self.projectMenu.entryconfig(i, state=state)

    # Disable other menus if there's no project
    for menu in [self.otherMenu,]: # Include more menus in this list
      for i in range(len(menu.options)):
        menu.entryconfig(i, state=state)
      
      
  def askSaveFile(self):

    popup = self.openPopup('save_project', SaveProjectPopup)
    popup.refresh()

  def modalAskSaveFile(self):

    popup = SaveProjectPopup(self, project=self.project, dismiss_text='Cancel Quit',
                             modal=True)
    did_save = popup.did_save
    popup.destroy()

    return did_save

  def quitSaveProject(self):

    if (self.project.activeRepositories):
      return self.saveFile()
    else:
      return self.modalAskSaveFile()

  def destroyPopups(self):

    for key in self.popups.keys():
      popup = self.popups[key]
      popup.destroy()

    self.popups = {}

  def copyModifiedStorages(self):

    modifiedStorages = [storage for storage in self.project.storages if storage.isModified]
    if (self.project.isModified):
      modifiedStorages.append(self.project)

    for storage in modifiedStorages:
      self.copyStorage(storage)

  def saveFile(self):

    if not self.project:
      return False

    try:
      saveProject(self.project, createFallback=True)

      print 'successfully saved project'
      return True
    except IOError, e:
      showError('Saving file', str(e), parent=self)
      return False
Example #11
0
class ApplicationPopup(BasePopup):

    help_url = 'http://www.ccpn.ac.uk'

    def __init__(self, root, programName='ApplicationTemplate'):

        self.programName = programName
        # Application object needed to store application-specific data with project
        self.application = Application(name=programName)
        self.versionInfo = 'Version 0.00a'

        # Application popup is a superclass of memops.editor.BasePoup
        BasePopup.__init__(self,
                           parent=root,
                           title=programName,
                           location='+100+100',
                           class_=self.application.name)

    def body(self, guiParent):

        # Ensure that the first row and column in popup expand
        guiParent.grid_rowconfigure(0, weight=1)
        guiParent.grid_columnconfigure(0, weight=1, minsize=200)
        frame = Frame(guiParent)  # Body widgets can be put in this frame
        frame.grid()

        buttons = createDismissHelpButtonList(frame,
                                              dismiss_text='Quit',
                                              dismiss_cmd=self.quit,
                                              help_url=self.help_url,
                                              expands=1)
        buttons.grid(row=0, column=0, sticky=Tkinter.NSEW)

        self.helpButton = buttons.buttons[-1]
        self.helpButtonCommand = self.helpButton.buttonCommand  # the command with no project

        # Dictionary to store popups opened by this application - e.g. need to close upon quit
        self.popups = {}

        # Default font
        self.font = 'Helvetica 10'

        # Closing the window from the desktop environment calls the proper quit
        self.protocol('WM_DELETE_WINDOW', self.quit)

        self.mainMenu = Menu(self)
        self.projectMenu = self.makeProjectMenu()
        self.otherMenu = self.makeOtherMenu()

        # Put the main menu
        self.config(menu=self.mainMenu)

        self.initProject()

    def makeProjectMenu(self):

        # Submenu of the min menu
        menu = Menu(self.mainMenu, tearoff=0)
        # Add various options to the menu and state the functions they call
        menu.add_command(label='New', shortcut='N', command=self.newProject)
        menu.add_command(label='Open', shortcut='O', command=self.openProject)
        menu.add_command(label='Close',
                         shortcut='C',
                         command=self.closeProject)
        menu.add_command(label='Save', shortcut='S', command=self.saveProject)
        menu.add_command(label='Save As',
                         shortcut='A',
                         command=self.saveAsProject)
        menu.add_command(label='Quit', shortcut='Q', command=self.quit)
        menu.add_command(label='Version',
                         shortcut='V',
                         command=self.showVersion)
        self.mainMenu.add_cascade(label='Project', shortcut='P', menu=menu)

        menu.options = [
            'New', 'Open', 'Close', 'Save', 'Save As', 'Quit', 'Version'
        ]
        return menu

    def makeOtherMenu(self):

        # The fonts menu is a pre-created widget
        fontsMenu = FontMenu(self.mainMenu,
                             self.setFont,
                             sizes=(8, 10, 12),
                             doItalic=0,
                             doBoldItalic=0,
                             tearoff=0)

        # Submenu of the min menu
        menu = Menu(self.mainMenu, tearoff=0)
        # Only Fonts option so far
        menu.add_command(label='Popup Template',
                         shortcut='P',
                         command=self.popupTemplate)
        menu.add_cascade(label='Fonts', shortcut='F', menu=fontsMenu)
        self.mainMenu.add_cascade(label='Other', shortcut='O', menu=menu)

        menu.options = ['Popup Template', 'Fonts']
        return menu

    def popupTemplate(self):

        popup = self.openPopup('popup_template', PopupTemplate)

    def newProject(self):

        if self.project:
            # Project already present
            if not self.closeProject():
                # If we don't close the current project do nothing
                return

        name = askString(title='Project name',
                         prompt='Enter project name:',
                         parent=self)

        if name:
            # Make the API Project object
            project = Implementation.MemopsRoot(name=name)
            nmrProject = Nmr.NmrProject(project, name=project.name)
            self.initProject(project)

    def openProject(self):

        if self.project:
            if not self.closeProject():
                return

        self.openPopup('open_project',
                       OpenProjectPopup,
                       callback=self.initProject)

    def openPopup(self, popup_name, clazz, *args, **kw):

        popup = self.popups.get(popup_name)

        if popup:
            popup.open()

        else:
            transient = getAreDialogsTransient(self.project)
            # Below automatically opens popup
            popup = self.popups[popup_name] = clazz(self,
                                                    project=self.project,
                                                    transient=transient,
                                                    *args,
                                                    **kw)

        return popup

    def closeProject(self, queryClose=True, querySave=True):

        if queryClose:
            if (not showYesNo('Close project', 'Close current project?')):
                return False

        if querySave:
            if (not self.checkSaving()):
                return False

        self.helpButton.config(command=self.helpButtonCommand)
        self.destroyPopups()
        self.initProject()

        return True

    def saveProject(self):

        self.saveFile()

        #if (self.project.isStored):
        #  self.saveFile()
        #else:
        #  self.askSaveFile()

    def saveAsProject(self):

        self.askSaveFile()

    def showVersion(self):

        showInfo('Version', self.versionInfo, parent=self)

    def setFont(self, fontName=None, popup=None):

        if fontName is None:
            if self.project:
                # Get font specification saved as project application data
                self.font = getProjectFont(self.project)

        else:
            self.font = fontName
            if self.project:
                # Set font specification as project application data
                setProjectFont(self.project, self.font)

        if not popup:
            popup = self

        childList = popup.children.values()

        classes = [
            Tkinter.Button, Tkinter.Label, Tkinter.Menu, Tkinter.Entry,
            Tkinter.Checkbutton, Tkinter.Radiobutton
        ]

        for child in childList:
            for clazz in classes:
                if isinstance(child, clazz):
                    if hasattr(child, 'font'):
                        if not child.font:
                            child.config(font=self.font)
                    else:
                        child.config(font=self.font)
                    break

            if hasattr(child, 'children'):
                childList.extend(child.children.values())

    def initProject(self, project=None):

        self.project = project
        self.setTitle(self.programName)

        if project:
            self.project.application = self.application
            self.setFont()
            webBrowser = ProjectWebBrowser(self.top,
                                           popup=self,
                                           project=project)
            self.helpButton.config(
                command=lambda url=self.help_url: webBrowser.open(url))

        self.setMenuState()

    def setMenuState(self):

        if self.project:
            state = Tkinter.NORMAL
        else:
            state = Tkinter.DISABLED

        # Disable bits of the project menu if there's no project
        for option in ('Save', 'Save As', 'Quit'):
            i = self.projectMenu.options.index(option)
            self.projectMenu.entryconfig(i, state=state)

        # Disable other manus if there's no project
        for menu in [
                self.otherMenu,
        ]:  # Include more menus in this list
            for i in range(len(menu.options)):
                menu.entryconfig(i, state=state)

    def askSaveFile(self):

        popup = self.openPopup('save_project', SaveProjectPopup)
        popup.refresh()

    def modalAskSaveFile(self):

        popup = SaveProjectPopup(self,
                                 project=self.project,
                                 dismiss_text='Cancel Quit',
                                 modal=True)
        did_save = popup.did_save
        popup.destroy()

        return did_save

    def quitSaveProject(self):

        if (self.project.activeRepositories):
            return self.saveFile()
        else:
            return self.modalAskSaveFile()

    def destroyPopups(self):

        for key in self.popups.keys():
            popup = self.popups[key]
            popup.destroy()

        self.popups = {}

    def copyModifiedStorages(self):

        modifiedStorages = [
            storage for storage in self.project.storages if storage.isModified
        ]
        if (self.project.isModified):
            modifiedStorages.append(self.project)

        for storage in modifiedStorages:
            self.copyStorage(storage)

    def saveFile(self):

        if (not self.project):
            return False

        try:
            self.copyModifiedStorages()
            self.project.saveModified()
            print 'Successfully saved project'
            return True

        except IOError, e:
            showError('Saving file', str(e))
            return False