"""
     qtgui/selectionBrowser.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009-2011 University of York

     This library is free software: you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public License
     version 3, modified in accordance with the provisions of the 
     license to address the requirements of UK law.
 
     You should have received a copy of the modified GNU Lesser General
     Public License along with this library.  If not, copies may be 
     downloaded from http://www.ccp4.ac.uk/ccp4license.php
 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU Lesser General Public License for more details.
"""
from PyQt4 import QtCore, QtGui
import mmdb2 as mmdb
import pygl_coord,model_selection
import guiUtils,mgTreeView,mgWidgets,MGSimpleDialog
import sys,string
from global_definitions import *

MARGIN = 4
MARGIN1 = 1
NOMARGIN = 0
tabHeight = 200
tabWidth = 400


class TextEditWithFocusChangeSignal(QtGui.QTextEdit):
  def focusOutEvent(self,event):
    #print 'TextEditWithFocusChangeSignal.focusOutEvent'
    self.emit(QtCore.SIGNAL('focusOut'))
    QtGui.QTextEdit.focusOutEvent(self,event)
    event.ignore()


   

#---------------------------------------------------------------------
#---------------------------------------------------------------------
#---------------------------------------------------------------------
class selectionBrowser(MGSimpleDialog.MGSimpleDialog):
#---------------------------------------------------------------------
#---------------------------------------------------------------------
#---------------------------------------------------------------------

  operator_menu = ['Replace (NEW)',
                   'Add to (OR)',
                   'Limit (AND)',
                   'Exclude from (EXCL)', 
                   'One of (XOR)' ]
  operator_alias = ['new','or','and','excl','xor']
  
#---------------------------------------------------------------------
  def __init__(self,parent,moldata_name):
#---------------------------------------------------------------------
    MGSimpleDialog.MGSimpleDialog.__init__(self,parent)

    self.moldata_name = moldata_name
    #print "selectionBrowser moldata_name",self.moldata_name

    self.SelHandle = None
    self.immediateUpdateFromTree = 1
    self.last_invalid_cid = '' 


    self.toolWidgets = {}

    self.toolDefs = {
      'namedSelection' : {  'label' : 'saved selection',
                     'tip' : 'Restore saved selection',
                     'widget' :  namedSelectionGui,
                     'signal' : 'restore',
                     'slot' : self.restoreNamedSelection },
      'interactive' : {  'label' : 'interactive selection',
                     'tip' : 'Edit selection by picking atoms/residues/etc.',
                     'widget' :  interactiveGui },
      'altLocs'      : {  'label' : 'alternate locations',
                         'tip' : 'Alternate locations',
                         'widget' : altLocWidget } ,
      'neighb' : { 'label' : 'neighbours',
                   'tip' : 'Select atoms/residues/etc\naround a central set of atoms',
                   'widget' : neighbGui },
      'buried' : { 'label' : 'buried area',
                   'tip' : 'Select atoms or residues buried\nby contact with another set of atoms',
                   'widget' : buriedGui },
      'elementtype' : { 'label' : 'atomic elements',
                        'tip' :'Select atoms by element type',
                        'widget' : elementTypeGui },
      'restype' : { 'label' : 'residue types',
                     'tip' :'Select by residue type',
                     'widget' :resTypeGui },
      'secstr' : { 'label' : 'secondary structure elements',
                   'tip' :'Select secondary structure elements',
                   'widget' : secStrGui },     
      'property' : { 'label' :'properties (eg temp factor)',
                      'tip' : 'Select atoms by property\nsuch as Bvalue,charge,etc',
                     'widget' : propertyGui },
      'nmrModels' : {  'label' : 'NMR/symmetry models',
                        'tip' : 'Select NMR models or models\nof symmetry mates',
                       'widget' :nmrModelsGui },
      'ranges' : {  'label' : 'residue ranges',
                        'tip' : 'Select residue ranges',
                       'widget' :rangesGui }
      }
    self.toolOrder = ['','namedSelection','interactive','neighb','buried','elementtype','restype','ranges','secstr','property']
    if data(self.moldata_name).get_attribute('model_list'):
      self.toolOrder.append('nmrModels')
    if data(self.moldata_name).get('contains_hydrogen') or data(self.moldata_name).get('alt_locs'):
      self.toolOrder.append('altLocs')
    self.currentTool = ''

        

    self.draw()
    self.connect(MAINWINDOW(),QtCore.SIGNAL('atomContextMenu'),self.atomPickMenu)
    self.connect(DISPLAYTABLE().getDataObj(self.moldata_name),QtCore.SIGNAL('nofModelsChanged'),self.updateNmrModelsWidget)

    self.history = []


#---------------------------------------------------------------------
  def Close(self):
#---------------------------------------------------------------------
    if self.toolWidgets.has_key('interactive'):
      self.toolWidgets['interactive'].toggleSkeleton(0)
      self.toolWidgets['interactive'].showSkeleton.setChecked(0)
    MGSimpleDialog.MGSimpleDialog.Close(self)
      
#---------------------------------------------------------------------
  def draw(self):
#---------------------------------------------------------------------

    #print "in selectionBrowser.draw()"
    moldata = data(self.moldata_name)
    self.setWindowTitle(self.tr("Select from")+moldata.name_label)
    #self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

    
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN1)
    layout.setContentsMargins(MARGIN1,MARGIN1,MARGIN1,MARGIN1)
    

    # tree view
    self.treeFrame = QtGui.QFrame(self)
    #self.treeFrame = FrameWithFocusChangeSignal(self)
    self.treeFrame.setFrameStyle(QtGui.QFrame.Box)
    frame_layout = QtGui.QVBoxLayout()
    frame_layout.setSpacing(MARGIN1)
    frame_layout.setContentsMargins(MARGIN1,MARGIN1,MARGIN1,MARGIN1)

    line_layout =  QtGui.QHBoxLayout()
    self.atomSelectionWidget = atomSelectionGui(self,self.moldata_name,height=200,width=200)
    line_layout.addWidget(self.atomSelectionWidget)
    '''
    self.treeApply = QtGui.QPushButton('Apply',self)
    line_layout.addWidget(self.treeApply)
    '''
    frame_layout.addLayout(line_layout)


    self.treeView = mgTreeView.mgTreeView(self,moldata.treeModel)
    self.treeView.loadGroups(['monomers','metal','peptide','nucleic','solvent','solute','saccharide'])
    frame_layout.addWidget(self.treeView)

    self.treeFrame.setLayout(frame_layout)
  

    # Tools frame to contain the combineLine and tools widgets
    
    self.toolsFrame = QtGui.QFrame(self)
    self.toolsFrame.setFrameStyle(QtGui.QFrame.Box)
    toolsLayout = QtGui.QVBoxLayout()
    toolsLayout.setSpacing(MARGIN1)
    toolsLayout.setContentsMargins(MARGIN1,MARGIN1,MARGIN1,MARGIN1)
    self.toolsFrame.setLayout(toolsLayout)
    
    line_layout =  QtGui.QHBoxLayout()
    self.operationWidget = QtGui.QComboBox()  
    for item in selectionBrowser.operator_menu:
      self.operationWidget.addItem(item)    
    line_layout.addWidget(self.operationWidget)
    widget = QtGui.QLabel('current selection by',self)
    line_layout.addWidget(widget)
    #print 'SelectionBrowser fonts',self.font().pointSize(),widget.font().pointSize()
    self.toolMenu = QtGui.QComboBox(self)
    self.toolMenu.addItem(' ')
    for item in self.toolOrder[1:]:
      self.toolMenu.addItem(self.toolDefs[item]['label'])        
    self.connect(self.toolMenu,QtCore.SIGNAL('currentIndexChanged(int)'),self.handleToolMenu)
    line_layout.addWidget(self.toolMenu)
    line_layout.addStretch(5)
    layout.addLayout(line_layout)
    
    # Selection command line
    self.cidFrame = QtGui.QFrame(self)
    #self.cidFrame = FrameWithFocusChangeSignal(self)
    self.cidFrame.setFrameStyle(QtGui.QFrame.Box)
    cidLayout = QtGui.QVBoxLayout()
    cidLayout.setSpacing(MARGIN1)
    cidLayout.setContentsMargins(MARGIN1,MARGIN1,MARGIN1,MARGIN1)
    #self.cid = QtGui.QTextEdit()
    self.cid = TextEditWithFocusChangeSignal()
    self.cid.setToolTip('The selection command')
    self.cid.setWhatsThis('The selection command')
    self.cid.setMinimumHeight(30)
    #self.connect (self.cid,QtCore.SIGNAL('returnPressed()'),self.updateFromCid)
    cidLayout.addWidget(self.cid)
    '''
    line_layout = QtGui.QHBoxLayout()
    line_layout.addStretch(5)
    button = QtGui.QPushButton('Apply',self)
    self.connect(button,QtCore.SIGNAL('clicked()'),self.updateFromCid)
    line_layout.addWidget(button)
    cidLayout.addLayout(line_layout)
    '''
    self.cidFrame.setLayout(cidLayout)
    self.connect(self.cid,QtCore.SIGNAL('focusOut'),self.updateFromCid)
    

    # Load the splitter
    self.splitter = QtGui.QSplitter(QtCore.Qt.Vertical,self)
    layout.addWidget(self.splitter)
    #splitter.setMinimumSize(200,400)
    self.splitter.addWidget(self.toolsFrame)
    self.splitter.addWidget(self.treeFrame)
    self.splitter.addWidget(self.cidFrame)
    self.splitter.setStretchFactor(1,3)

    self.buttonBox = QtGui.QDialogButtonBox(self)
    self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
    button = self.buttonBox.addButton('&Clear',QtGui.QDialogButtonBox.ResetRole)
    self.connect (button,QtCore.SIGNAL('clicked()'),self.clear)
    button = self.buttonBox.addButton('&Save',QtGui.QDialogButtonBox.ActionRole)
    self.connect (button,QtCore.SIGNAL('clicked()'),self.handleSave)
    button = self.buttonBox.addButton('Clos&e',QtGui.QDialogButtonBox.DestructiveRole)
    self.connect (button,QtCore.SIGNAL('clicked()'),self.Close)
    button = self.buttonBox.addButton('&Help',QtGui.QDialogButtonBox.HelpRole)
    self.connect (button,QtCore.SIGNAL('clicked()'),self.Help)
    button = self.buttonBox.addButton('&Apply',QtGui.QDialogButtonBox.ApplyRole)
    self.connect (button,QtCore.SIGNAL('clicked()'),self.Apply)
    layout.addWidget(self.buttonBox)

    #print 'buttonBox.buttons',self.buttonBox.buttons()
    for button in self.buttonBox.buttons():
      #print 'button font',self.font().pointSize(),button.font().pointSize()
      button.setFont(self.font())
      button.update()
      #print 'button font',button.font().pointSize()


    self.setLayout(layout)

    self.connectTreeSignals(2)
    self.connect(self.cid,QtCore.SIGNAL('textChanged()'),self.appendHistoryCid)

      
    self.UnClose()

#---------------------------------------------------------------------------
  def updateNmrModelsWidget(self):
#---------------------------------------------------------------------------
    '''
    The 'nmr' model have been edited - need to update options in nmrModelsWidget
    and update the selection
    '''
    if not getattr(self,'SelHandle',None): return
    if not self.toolWidgets.get('nmrModels',None): return
    self.toolWidgets['nmrModels'].draw()
    self.toolWidgets['nmrModels'].setParams(self.SelHandle.getSelParams())


#---------------------------------------------------------------------------
  def openToolForCurrentSelection(self):
#---------------------------------------------------------------------------
    if not getattr(self,'SelHandle',None): return
    selparams = self.SelHandle.getSelParams()
    mode = selparams.get('select','')
    if not mode: return
    #print 'selectionBrowser.openToolForCurrentSelection',mode
    self.changeTool(mode)
    if self.toolOrder.count(mode):
      self.toolMenu.setCurrentIndex(self.toolOrder.index(mode))

#----------------------------------------------------------------------------
  def setSelHandle(self,SelHandle=None):
#----------------------------------------------------------------------------
    if not SelHandle: return
    self.SelHandle = SelHandle
    self.updateWidgets()

    self.setParams(SelHandle.getSelParams())

#----------------------------------------------------------------------------
  def getSelHandle(self):
#----------------------------------------------------------------------------
    return self.SelHandle

#----------------------------------------------------------------------------
  def setParams(self,params={},**kw):
#----------------------------------------------------------------------------
    #print "selectionBrowser.setParams",params
    for name,gui in self.toolWidgets.items():
      gui.setParams(params)
    
#----------------------------------------------------------------------------
  def updateWidgets(self):
#----------------------------------------------------------------------------
    # Update - possibly after auto save/restore
    #print "SelectionBrowser.update",self.SelHandle,self.SelHandle.getNofAtoms()
    self.updateTreeView()
    self.updateToolWidgets()
    self.updateCid()


#----------------------------------------------------------------------------
  def connectTreeSignals(self,mode=1):
#----------------------------------------------------------------------------
    # Connect/disconnect signals from tree view widget
    if mode>0:    
      if self.immediateUpdateFromTree:
        self.connect(self.treeView.selectionModel(),QtCore.SIGNAL('selectionChanged(QItemSelection,QItemSelection)'),self.updateFromTreeView)
      else:
        #self.connect(self.treeApply,QtCore.SIGNAL('clicked()'),self.updateFromTreeView)
        self.connect(self.treeView,QtCore.SIGNAL('changed'),self.appendHistoryTree)
        self.connect(self.treeView,QtCore.SIGNAL('focusOut'),self.updateFromTreeView)   
      self.connect(self.atomSelectionWidget,QtCore.SIGNAL('changed'),self.appendHistoryTree)
      self.connect(self.atomSelectionWidget,QtCore.SIGNAL('changed'),self.updateFromTreeView)

      '''
       elif mode == 1:
         self.treeView.blockSignals(False)
         self.atomSelectionWidget.blockSignals(False)
       elif mode == -1:
         self.treeView.blockSignals(True)
         self.atomSelectionWidget.blockSignals(True)
      '''

    
    elif mode<0:
      
      self.treeView.blockSignals(True)
      self.atomSelectionWidget.blockSignals(True)
      if self.immediateUpdateFromTree:
        self.disconnect(self.treeView.selectionModel(),QtCore.SIGNAL('selectionChanged(QItemSelection,QItemSelection)'),self.updateFromTreeView)
      else:
        #self.disconnect(self.treeApply,QtCore.SIGNAL('clicked()'),self.updateFromTreeView)
        self.disconnect(self.treeView,QtCore.SIGNAL('changed'),self.appendHistoryTree)
        self.disconnect(self.treeView,QtCore.SIGNAL('focusOut'),self.updateFromTreeView)   
      self.disconnect(self.atomSelectionWidget,QtCore.SIGNAL('changed'),self.appendHistoryTree)
      self.disconnect(self.atomSelectionWidget,QtCore.SIGNAL('changed'),self.updateFromTreeView)
      self.treeView.blockSignals(False)
      self.atomSelectionWidget.blockSignals(False)
     
        
  def appendHistoryCid(self):
    self.appendHistory('cid')
  def appendHistoryTree(self):
    self.appendHistory('tree')

#----------------------------------------------------------------------------
  def appendHistory(self,item):
#----------------------------------------------------------------------------
    #print 'selectionBrowser.appendHistory',item
    label = { 'tree' : 'the tree view',
              'cid' : 'the text command' }
    if item == 'tool':
      self.history = []
    else:
      if (len(self.history) and (self.history[-1]==item)): return
      self.history.append(item)

      '''
      if len(self.history):
        self.historyWarning = QtGui.QMessageBox(self)
        self.historyWarning.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.historyWarning.setText('Warning - you have made changes to '+label[self.history[-1]]+'.\nDo you want to apply the changes')
        b = self.historyWarning.addButton('Do nothing',QtGui.QMessageBox.RejectRole)
        self.connect(b,QtCore.SIGNAL('released()'),self.handleWarningIgnore)
        b = self.historyWarning.addButton('Apply',QtGui.QMessageBox.AcceptRole)
        self.connect(b,QtCore.SIGNAL('released()'),self.handleWarningSave)
        self.historyWarning.show()
        self.historyPending = item
      else:       
        self.history.append(item)
      '''

 

  def handleWarningSave(self):
    #print 'handleWarning'
    self.Apply()
    item = getattr(self,'historyPending','')
    if item: self.history.append(item)

  def handleWarningIgnore(self):
    self.history = []
    item = getattr(self,'historyPending','')
    if item: self.history.append(item)
  

#----------------------------------------------------------------------------
  def Apply(self,mode=''):
#----------------------------------------------------------------------------
    print 'Apply',self.history
    if not mode and self.history: mode = self.history[-1]
    if mode:
      if self.history[-1] == 'cid':
        self.updateFromCid()
      else:
        self.updateFromTreeView()
      self.history = []
    
#----------------------------------------------------------------------------
  def updateTreeView(self):
#----------------------------------------------------------------------------
    # Update the TreeView with mmdb selHnd from self.SelHandle
    # beware need to disconnect signal that selection is changed
    self.connectTreeSignals(-1)
    done = 0
    
    self.treeView.clearSelection()
    self.atomSelectionWidget.setParams({'atomtype':''})

    
    if self.SelHandle:
      # Try if the selection os a simple group command such as 'peptide' or 'solvent'
      rv= self.treeView.setGroupSelection(self.SelHandle.getCommand())
      if not rv:
         self.atomSelectionWidget.setParams({'atomtype':''})
         done = 1

      else:
        treecom = self.SelHandle.getCommand(internal=1)
        #print 'updateTreeView',treecom
        # Try if its an atomSelectionWidget commands (eg 'catrace')
        if not treecom:
          # Probably did not parse correctly
          done = 1
        elif not treecom[0]:
          atm_rv = self.isAtomSelection(treecom)
          #print 'atm_rv',atm_rv
          if atm_rv:
            self.atomSelectionWidget.setParams({'atomtype':atm_rv[1]})
            self.treeView.setGroupSelection(atm_rv[0])
            done = 1
        
        elif treecom[0] == 'and':
          # Try if its a combination of  atomSelectionWidget commands (eg 'catrace')
          # and something else
          rv1 = self.isAtomSelection(treecom[1])
          rv2 = self.isAtomSelection(treecom[2])
          sele_defn = []
          #print 'isAtomSelection',rv1,rv2
          if rv1:
            self.atomSelectionWidget.setParams({'atomtype':rv1[1]})
            sele_defn = treecom[2]
          elif rv2:
            self.atomSelectionWidget.setParams({'atomtype':rv2[1]})
            sele_defn = treecom[1]
          if sele_defn:
            #print 'sele_defn',sele_defn
            parse_rv=data(self.moldata_name).parse_selection(sele_defn)
            #print 'parse_rv',parse_rv
            if not parse_rv[0]:
              self.treeView.loadMMDBSelection(parse_rv[1])
              done = 1
              data(self.moldata_name).molHnd.DeleteSelection(parse_rv[1])

      if not done:
        self.treeView.loadMMDBSelection(self.SelHandle.getSelHnd())
        
    self.connectTreeSignals(1)

#----------------------------------------------------------------------
  def isAtomSelection(self,command):
#----------------------------------------------------------------------
    if not len(command)==2 or not command[0]==None: return ()
    if atomSelectionGui.type_commands['PROTEIN'].count(command[1]):
      return ('peptide',command[1])
    elif atomSelectionGui.type_commands['NUCLEIC'].count(command[1]):
      return ('nucleic',command[1])
    else:
      return ()

#----------------------------------------------------------------------
  def handleToolMenu(self,index):
#----------------------------------------------------------------------
    #print 'handleToolMenu',index
    mode = self.toolOrder[index]
    if mode != self.currentTool: self.changeTool(mode)

#----------------------------------------------------------------------
  def changeTool(self,mode):
#----------------------------------------------------------------------
    if mode and not self.toolDefs.has_key(mode): return
    #print 'into changeTool splitter.size', self.splitter.sizes()
    self.closeTool()
    if not mode:
      #self.toolsFrame.resize()
      return
    if not self.toolWidgets.has_key(mode):
      self.drawTool(mode)
    self.openTool(mode)
    #self.toolsFrame.resize()

#----------------------------------------------------------------------
  def drawTool(self,mode):
#----------------------------------------------------------------------
    if not self.toolDefs.has_key(mode): return
    self.toolWidgets[mode] = self.toolDefs[mode]['widget'](self,self.moldata_name)
    self.updateToolWidgets(mode)
    if self.toolDefs[mode].has_key('signal') and self.toolDefs[mode].has_key('slot'):
      self.connect(self.toolWidgets[mode],QtCore.SIGNAL(self.toolDefs[mode]['signal']), self.toolDefs[mode]['slot'])
    else:
      # This is the default signal-slot
      self.connect(self.toolWidgets[mode],QtCore.SIGNAL('accepted()'),guiUtils.partial(self.updateFromToolWidget,mode))
    
    self.updateToolWidgets(mode)
    
#----------------------------------------------------------------------
  def closeTool(self):
#----------------------------------------------------------------------
    if not self.currentTool: return
    if self.toolWidgets.has_key(self.currentTool):
      self.toolWidgets[self.currentTool].setVisible(0)
      self.toolsFrame.layout().removeWidget( self.toolWidgets[self.currentTool])
      self.currentTool = ''

#----------------------------------------------------------------------
  def openTool(self,mode):
#----------------------------------------------------------------------
    if self.toolWidgets.has_key(mode):
      self.toolsFrame.layout().addWidget( self.toolWidgets[mode])
      self.toolWidgets[mode].setVisible(1)
      self.currentTool = mode
      sizes = self.splitter.sizes()
      #print 'openTool splitter.size', sizes
      if sizes[0]==0:
        if sizes[1]>10:
          self.splitter.setSizes([sizes[1]/2,sizes[1]/2,sizes[2]])
        else:
          self.splitter.setSizes([(sizes[1]+sizes[2])/2,sizes[1]/2,sizes[2]/2])
#----------------------------------------------------------------------
  def updateToolWidgets(self,mode=''):
#----------------------------------------------------------------------
    # Update the tab widget GUis with params from self.SelHandle
    if not self.SelHandle: return
    params = self.SelHandle.getSelParams()
    # Update the GUIS
    if mode:
      if self.toolWidgets.has_key(mode):
        self.toolWidgets[mode].setParams(params)
    else:
      for name,gui in self.toolWidgets.items():
        gui.setParams(params)
   
    
#---------------------------------------------------------------------------
  def updateCid(self):
#---------------------------------------------------------------------------
    command = self.SelHandle.getCommand()
    #print "updateCid command",command
    self.disconnect(self.cid,QtCore.SIGNAL('textChanged()'),self.appendHistoryCid)
    self.cid.setText(command)
    self.connect(self.cid,QtCore.SIGNAL('textChanged()'),self.appendHistoryCid)


#----------------------------------------------------------------------
  def updateFromTreeView(self):
#----------------------------------------------------------------------
    status,command = self.treeView.getSelectionCommand()
    #print "updateFromTreeView",status,command, self.atomSelectionWidget.getSelection()
    if status:
      command = self.atomSelectionWidget.getSelection()
    else:
      atomtype = self.atomSelectionWidget.getSelection()
      if atomtype and atomtype != 'all':
        if command:
          command = atomtype + ' and {'+command+'}'
        else:
          command = atomtype
    #print "updateFromTreeView command",command
    self.SelHandle.setCommand(command)
    self.updateCid()
    self.apply()
      
#----------------------------------------------------------------------
  def updateFromToolWidget(self,mode=''):
#----------------------------------------------------------------------
    # Update browser based on input to one of the tab widgets
    #print 'updateFromToolWidget',mode
    # First get the tab widget to return its selection in the
    # form of a SelHandle 
    widget = self.toolWidgets.get(mode,None)
    if not widget: return
    widgetSelHandle = widget.getSelHandle()
    if not widgetSelHandle: return
    
    op = self.getOperation()
    params =widget.getParams()
    if op == 'new':
      self.SelHandle.setSelParams(params)
    else:
      if params.has_key('select'): del params['select']   
      self.SelHandle.setSelParams(params,apply=0)
      self.SelHandle.mergeSelection(SelHandle=widgetSelHandle,op=op)
    #print "combined nAtoms",self.SelHandle.getNofAtoms()

    # Update tree and cid
    self.updateTreeView()
    self.updateCid()
    self.apply()
    self.appendHistory('tool')
 
    return 0

  
#----------------------------------------------------------------------
  def updateFromAtomSelection(self):
#----------------------------------------------------------------------
    self.SelHandle.setSelParams(self.atomSelectionWidget.getParams(),apply=0)
    self.updateFromTreeView()
    
  
#----------------------------------------------------------------------
  def getOperation(self):
#----------------------------------------------------------------------
    icur = self.operationWidget.currentIndex()
    #print "getOperation icur",icur
    return selectionBrowser.operator_alias[icur]

#--------------------------------------------------------------------
  def updateFromCid(self):
#--------------------------------------------------------------------
    '''
    Handle command entered by user
    '''
    import copy
    cid = str(self.cid.toPlainText())
    if cid and cid == self.last_invalid_cid: return
    # So does it make sense??
    rv = data(self.moldata_name).parse_selection(command = cid, test =1)
    #print 'updateFromCid',rv
    if rv[0]:
      QtGui.QMessageBox.warning(self,'Error in selection command',rv[1])
      self.last_invalid_cid = copy.deepcopy(cid)
    elif rv[1] == 0:
      QtGui.QMessageBox.warning(self,'Error in selection command','No atoms selected')
      self.last_invalid_cid = copy.deepcopy(cid)
    else:
      self.last_invalid_cid = ''
      self.SelHandle.setCommand(cid)
      #print "handleCidEntered nAtoms",self.SelHandle.getNofAtoms()
      self.updateTreeView()
      self.apply()
        
#---------------------------------------------------------------------------
  def Help(self):
#---------------------------------------------------------------------------
    HELPBROWSER().loadMgHelp('selection.html')



#---------------------------------------------------------------------------
  def apply(self):
#---------------------------------------------------------------------------
    #print "in selectionBrowser.apply()"
    self.emit(QtCore.SIGNAL("accepted()"))

#---------------------------------------------------------------------------
  def getCid(self):
#---------------------------------------------------------------------------
    return str(self.cid.toPlainText())
  

#---------------------------------------------------------------------------
  def restoreNamedSelection(self):
#---------------------------------------------------------------------------
    if not self.toolWidgets.has_key('namedSelection'): return
    set,name = self.toolWidgets['namedSelection'].list_widget.selectedItem()
    if name:
      self.SelHandle.restoreSelection(name,op=self.getOperation())
      self.updateTreeView()
      self.updateCid()
      self.apply()

#---------------------------------------------------------------------------
  def handleSave(self):
#---------------------------------------------------------------------------
    self.save_dialog = ModelInfoSave(self,info='user_selection',sets = [self.moldata_name,'generic'])
    self.connect( self.save_dialog,QtCore.SIGNAL('save'),self.save)
   
#---------------------------------------------------------------------------
  def save(self):
#---------------------------------------------------------------------------
    set,label = self.save_dialog.selectedItem()
    #print "selectionBrowser.save",set,label
    if label:
      self.SelHandle.saveSelection (name=label,save_mode=set,overwrite=1)
      DISPLAYTABLE().getDataObj(self.moldata_name).handleSavedSelection(set)
      self.save_dialog.close()
    #if hasattr(self,'namedSelection'): self.namedSelection.list_widget.populate()

    
#---------------------------------------------------------------------------
  def handleDoubleClick(self,index):
#---------------------------------------------------------------------------
    self.emit(QtCore.SIGNAL("doubleClicked()"))


#---------------------------------------------------------------------------
  def clear(self):
#---------------------------------------------------------------------------
    #atomtype = self.atomTypeWidget.getSelection()
    #if atomtype and atomtype != 'all':
    # self.SelHandle.setCommand(atomtype)
    #else:
    self.atomSelectionWidget.selection.setCurrentIndex(0)
    self.SelHandle.setCommand('')
    self.connectTreeSignals(-1)
    self.treeView.clearSelection()
    self.connectTreeSignals(1)
    self.updateCid()
    self.apply()
   
#---------------------------------------------------------------------------
  def undo(self):
#---------------------------------------------------------------------------
    self.SelHandle.popHistory()
    self.updateTreeView()
    self.updateCid()
    self.updateToolWidgets()
    self.apply()

#---------------------------------------------------------------------------
  def atomPickMenu(self,pickevent=None):
#---------------------------------------------------------------------------
    #print "selectionBrowser.atomPickMenu"
    if not self.isVisible() or self.currentTool!='interactive': return
    dobj = pickevent.getDataObj()
    if not dobj: return
    if not dobj.name == self.moldata_name: return
    name = str(self.objectName())
    menu = pickevent.getContextMenu()
    if not menu: return
    guiUtils.populateMenu(self,menu,[['Select ('+self.getOperation()+') this',name+'range_2',name+'atom',name+'side',name+'CA+side',name+'main',name+'residue',name+'range_1',name+'SSE',name+'chain']],self.getActionDef,info = { 'pickevent' : pickevent } )

#----------------------------------------------------------------------
  def getActionDef(self,name,**info):
#----------------------------------------------------------------------
    #print "ModelColourEditor.getActionDef",name,info
    name = name[len(str(self.objectName())):]
    pickevent=info.get('pickevent','')
    if not pickevent: return

    args = [name,pickevent.getLabel(format='unique')]
    if name == 'atom':
      return dict ( text = 'Atom',
                    tip = 'Select this atom',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
    if name == 'residue':
      return dict ( text = 'Residue',
                    tip = 'Select this residue',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
    if name == 'main':
      return dict ( text = 'Main chain',
                    tip = 'Select this main chain',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
                    )
    if name == 'side':
      return dict ( text = 'Side chain',
                    tip = 'Select this side chain',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
    if name == 'CA+side':
      return dict ( text = 'CA+side chain',
                    tip = 'Select CA & side chain',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
            
    if name == 'chain':
      return dict ( text = 'Chain',
                    tip = 'Selected this chain',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
    if name == 'SSE':
      return dict ( text = 'Secondary structure',
                    tip = 'Selected secondary structure',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
    if name == 'range_1':
      return dict ( text = 'Start range',
                    tip = 'Select first residue in a range',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
    if name == 'range_2':
      if not hasattr(self,'selectPickedRangeStart'): return {}
      return dict ( text = 'Range from '+self.selectPickedRangeStart,
                    tip = 'Select end residue in a range',
                    slot = [self.selectPickedAtom,args],
                    deleteLater = 1
            )
    else:
      return {}
    

#----------------------------------------------------------------------
  def selectPickedAtom(self,args=[]):
#----------------------------------------------------------------------
    #print "selectionBrowser.selectPickedAtom",args
    name,atom_id = args
    if name == 'atom':
      selection = atom_id
    if ['residue','range_1','main','side','CA+side'].count(name):
      selection= data(self.moldata_name).convertAtomID (out = 'residue', atomID =atom_id )
      if ['main','side','CA+side'].count(name):
        selection = '{ '+name+' and '+selection+' }'
    elif ['chain'].count(name):
      selection= data(self.moldata_name).convertAtomID (out = 'chain', atomID =atom_id )     
    elif name == 'range_2':
      res2 = data(self.moldata_name).convertAtomID (out = 'residue', atomID =atom_id )
      #selection = data(self.moldata_name).interpretRanges(self.selectPickedRangeStart,atom_id)[1]
      # Try to get these the right way round
      nr1,pr1 = data(self.moldata_name).interpretResidueID(self.selectPickedRangeStart)
      nr2,pr2 = data(self.moldata_name).interpretResidueID(res2)
      if nr1==1 and nr2==1:
        if pr1.index < pr2.index:
          selection = self.selectPickedRangeStart + '-' + string.split(res2,'/')[-1]
        else:
          selection = res2 + '-' +   string.split(self.selectPickedRangeStart,'/')[-1]
      else: 
        selection = self.selectPickedRangeStart + '-' + string.split(res2,'/')[-1]
      del self.selectPickedRangeStart
    elif name == 'SSE':
      selection = data(self.moldata_name).getSSE(atom_name=atom_id)
    #print "colourPickedAtom selection",selection
        
    if name == 'range_1':
      self.selectPickedRangeStart = selection
      return
    else:
      op = self.getOperation()
      self.SelHandle.mergeSelection(command=selection,op=op)
      self.updateTreeView()
      self.updateCid()

      self.apply()


#---------------------------------------------------------------------------
  def update(self):
#---------------------------------------------------------------------------
    '''
    Update the gui - usually after a back/forward status change
    '''
    print 'SelectionBrowser.update'
    self.updateWidgets()

#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class altLocWidget(QtGui.QFrame):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------

  def __init__(self,parent=None,moldata_name=''):
    self.moldata_name = moldata_name
    QtGui.QFrame.__init__(self,parent)
    frame_layout = QtGui.QVBoxLayout()
    frame_layout.setSpacing(MARGIN)
    frame_layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    self.alt_loc = {}
    self.show_hydrogen = None
    
    if data(self.moldata_name).get('contains_hydrogen') or data(self.moldata_name).get('alt_locs'):
      frame_layout.addWidget(QtGui.QLabel('Show',self))

      if data(self.moldata_name).get('contains_hydrogen'):
        self.show_hydrogen = QtGui.QCheckBox('Hydrogen atoms',self)
        self.show_hydrogen.setChecked(1)
        self.connect(self.show_hydrogen,QtCore.SIGNAL('clicked()'),self.handleChange)
        frame_layout.addWidget(self.show_hydrogen)
        
                             
      if data(self.moldata_name).get('alt_locs'):
        self.alt_loc['no_alt'] = QtGui.QCheckBox('No alternate location',self)
        self.alt_loc['no_alt'].setChecked(1)
        self.connect(self.alt_loc['no_alt'],QtCore.SIGNAL('clicked()'),self.handleChange)
        frame_layout.addWidget(self.alt_loc['no_alt'])
        for item in data(self.moldata_name).get('alt_locs'):
          self.alt_loc[item] =  QtGui.QCheckBox(item,self)
          self.alt_loc[item].setChecked(1)
          self.connect(self.alt_loc[item],QtCore.SIGNAL('clicked()'),self.handleChange)
          frame_layout.addWidget(self.alt_loc[item])

      frame_layout.addStretch(5)
      line_layout = QtGui.QHBoxLayout()
      apply_button = QtGui.QPushButton('Apply',self)
      line_layout.addStretch(5)
      line_layout.addWidget(apply_button)
      self.connect(apply_button,QtCore.SIGNAL('clicked()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
      frame_layout.addLayout(line_layout)
        
    self.setLayout(frame_layout)


#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------
    pars = {}
    if self.show_hydrogen: pars['nothydrogen'] = 1 - int(self.show_hydrogen.isChecked())
    if len(self.alt_loc)>0:
      pars = { 'select' : 'alt_locs',
               'alt_locs' : [] }
      for item in ['no_alt','A','B','C','D']:
        if self.alt_loc.has_key(item) and self.alt_loc[item].isChecked():
          pars['alt_locs'].append(item)
    #print 'altLocFrame.getParams',pars
    return pars

#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------
    if params.has_key('nothydrogen') and self.show_hydrogen:
      self.show_hydrogen.setChecked(1-params['nothydrogen'])
    if params.has_key('alt_locs') and len(self.alt_loc)>0:      
      for key,widget in self.alt_loc.items():
        widget.setChecked(params['alt_locs'].count(key))


#---------------------------------------------------------------------------
  def getSelection(self):
#---------------------------------------------------------------------------
    actions = []
    if self.show_hydrogen and not self.show_hydrogen.isChecked():
      actions.append(['[H]','excl'])
    if len(self.alt_loc)>0:
      nex = 0
      for key,widget in self.alt_loc.items():
        if not widget.isChecked(): nex = 1
      # Only add some altLoc selection if some altLoc has been excluded
      if nex:
        sele = '/*/*/*,*/*:'
        for item in ['no_alt','A','B','C','D']:
          if self.alt_loc.has_key(item) and self.alt_loc[item].isChecked():
            if item == 'no_alt':
              sele = sele + ' ,'
            else:
              sele = sele + item + ','
        actions.append([sele[0:-1],'and'])
    return actions    
      
#---------------------------------------------------------------------------
  def handleChange(self):
#---------------------------------------------------------------------------
    #self.emit(QtCore.SIGNAL('accepted()'))
    pass
  

#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'atomtypes'
    rv = selHnd.setSelParams(pars)
    
    #print 'altLocWidget getSelHandle rv',rv,selHnd.getNofAtoms()

    return selHnd

#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class secStrGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------

  secstr_menu = ['No structure','Beta strand','Beta bulge','3-turn', \
                 '4-turn','5-turn','Alpha helix','Beta bridge','bend']
  #secstr_alias = ['mmut.SSE_None', 'mmut.SSE_Strand', 'mmut.SSE_Bulge',
  #                'mmut.SSE_3Turn','mmut.SSE_4Turn',  'mmut.SSE_5Turn',
  #                'mmut.SSE_Helix','mmut.SSE_Bridge','mmut.SSE_Bend']
  #secstr_enum = [str(SSE_None), str(SSE_Strand), str(SSE_Bulge), \
  #        str(SSE_3Turn), str(SSE_4Turn), str(SSE_5Turn), str(SSE_Helix),str(SSE_Bridge),str(SSE_Bend) ]
  secstr_dssp = [ ' ', 'E', 'E' , 'G', 'T', 'I', 'H','B','S']

  
  def __init__(self,parent,moldata_name,height=200,width=400):

    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    molobj = data(self.moldata_name)
    secstr_ranges = molobj.get_attribute('secstr_list')
    secstr_items = []
    for item in secstr_ranges:
      secstr_items.append([item,item])
    #print "secstr_items",secstr_items
    secstr_types = [['beta strand',[QtCore.QRegExp('^S')]],['alpha helix',[QtCore.QRegExp('^H')]]]
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    secStrWidget = mgWidgets.mgGroupSelector(self,groups = secstr_types,items = secstr_items,reMatch=1)
    secStrWidget.setObjectName('secStr')

    self.connect(secStrWidget,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    layout.addWidget(secStrWidget)
    self.setLayout(layout)
    self.show()


    
#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------
    if params.has_key('secstr'):
      self.findChild(QtGui.QWidget,'secStr').setSelection(params['secstr'])

#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------
    secstr_list = self.findChild(QtGui.QWidget,'secStr').getSelection()
    pars = { 'select' : 'peptide', 'secstr' :secstr_list }
    if len(secstr_list) == 0:
      pars = { 'select' : 'none' }
    
    return pars
  
#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
   
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'secstr'
    rv = selHnd.setSelParams(pars)
    sele_list = self.findChild(QtGui.QWidget,'secStr').getSelection()
    #print "secStrGui.getSelHandle sele_list",sele_list
    if  sele_list:
      command = sele_list[0][2:]
      for item in sele_list[1:]:
        command = command + ' or ' + item[2:]
      #print "command",command
      selHnd.setCommand(command)
    #print 'secStrGui getSelHandle rv',rv

    return selHnd

    
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class neighbGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------

  neighb_group_menu = ['atoms','CA trace','main/side chains','main chain','side chains','CA+side chains','residues','chains','models','solvent/monomers']
  neighb_group_alias = ['atom','catrace','main_side','main','side','CA+side','residue','chain','model','solvent_monomers']
  
  def __init__(self,parent,moldata_name):

    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    molobj = data(self.moldata_name )
    
    neighbLayout = QtGui.QVBoxLayout()
    neighbLayout.setSpacing(MARGIN)
    neighbLayout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    seleLabel =  QtGui.QLabel('Select',self)
    
    seleGroup = QtGui.QComboBox(self)
    seleGroup.setObjectName('neighb_group')
    seleGroup.addItems(neighbGui.neighb_group_menu)
   
    radLabel = QtGui.QLabel('within',self)
    rad = QtGui.QDoubleSpinBox(self)
    rad.setObjectName('neighb_rad')
    rad.setRange(0.0,100.0)
    rad.setSingleStep(0.5)
    rad.setDecimals(1)
    
    aroundLabel = QtGui.QLabel('of selection..',self)
  
    seleLine = QtGui.QHBoxLayout()
    seleLine.addWidget(seleLabel)
    seleLine.addWidget(seleGroup)
    seleLine.addWidget(radLabel)
    seleLine.addWidget(rad)
    seleLine.addWidget(aroundLabel)
    seleLine.addStretch()

    if molobj:
      neighbSel = mgWidgets.mgSelectionCombo(self,multi=1)
      neighbSel.setCurrentDataObj(self.moldata_name)
      neighbSel.setObjectName('neighb_sel')
    #self.connect(neighbSel,QtCore.SIGNAL("doubleClicked()"),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))

    #neighbLine =  QtGui.QHBoxLayout()
    #neighbLine.addWidget(neighbSel)

    excl_frame = QtGui.QFrame()
    excl_frame.setFrameStyle(QtGui.QFrame.Box)
    exclLayout = QtGui.QGridLayout()
    exclLayout.setSpacing(MARGIN)
    exclLayout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    includeLabel =  QtGui.QLabel('Include',self)
    hbonding =  QtGui.QCheckBox('non-Hbonding groups',self)
    hbonding.setObjectName('neighb_hb')
    central = QtGui.QCheckBox('the central selection',self)
    central.setObjectName('neighb_excl')
    solvent = QtGui.QCheckBox('solvent',self)
    solvent.setObjectName('neighb_excl_solvent')
    #sym = QtGui.QCheckBox('symmetry related mates')
    #sym.setObjectName('neighb_sym')
    exclLayout.addWidget(includeLabel,0,0,1,1)
    exclLayout.addWidget(central,1,0,1,2)
    exclLayout.addWidget(solvent,1,2,1,2)
    exclLayout.addWidget(hbonding,2,0,1,2)
    #exclLayout.addWidget(sym,2,2,1,2)
    excl_frame.setLayout(exclLayout)

    applyLine = QtGui.QHBoxLayout()
    neighbApply = QtGui.QPushButton('Select neighbours',self)
    self.connect(neighbApply,QtCore.SIGNAL('clicked()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    self.connect(neighbSel,QtCore.SIGNAL('returnPressed()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    applyLine.addStretch()
    applyLine.addWidget(neighbApply)
    
    neighbLayout.addLayout(seleLine)
    neighbLayout.addWidget(neighbSel)
    neighbLayout.addWidget(excl_frame)
    neighbLayout.addLayout(applyLine)
    neighbLayout.addStretch()
  
    self.setLayout(neighbLayout)

#-----------------------------------------------------------------------
  def setParams(self,pars={},**kw):
#-----------------------------------------------------------------------
    pars.update(kw)
    
    self.findChild(QtGui.QWidget,'neighb_rad').setValue(float(pars.get('neighb_rad',5.0)))
    group = pars.get('neighb_group','residue')
    self.findChild(QtGui.QWidget,'neighb_group').setCurrentIndex(neighbGui.neighb_group_alias.index(group))
    self.findChild(QtGui.QWidget,'neighb_hb').setCheckState(guiUtils.checkState(1-pars.get('neighb_hb',0)))
    self.findChild(QtGui.QWidget,'neighb_excl').setCheckState(guiUtils.checkState(1-pars.get('neighb_excl',1)))
    self.findChild(QtGui.QWidget,'neighb_excl_solvent').setCheckState(guiUtils.checkState(1-pars.get('neighb_excl_solvent',1)))
    #self.findChild(QtGui.QWidget,'neighb_sym').setCheckState(guiUtils.checkState(pars.get('neighb_sym',0)))
    
    self.findChild(QtGui.QWidget,'neighb_sel').setParams({ 'selection' : pars.get('neighb_sel','')
                                                             } )
    molname = pars.get('neighb_mol','')
    if not molname: molname = self.moldata_name
    self.findChild(QtGui.QWidget,'neighb_sel').setCurrentDataObj(molname)
    
#------------------------------------------------------------------------
  def getParams(self):
#------------------------------------------------------------------------    
    neighb_sel = str(self.findChild(QtGui.QWidget,'neighb_sel').text())
    neighb_rad = float(self.findChild(QtGui.QWidget,'neighb_rad').value())
    neighb_group =  guiUtils.fromMenu(str(self.findChild(QtGui.QWidget,'neighb_group').currentText()),neighbGui.neighb_group_menu,neighbGui.neighb_group_alias)
    neighb_excl = 1-guiUtils.fromCheckState(self.findChild(QtGui.QWidget,'neighb_excl').checkState())
    neighb_excl_solvent =  1- guiUtils.fromCheckState(self.findChild(QtGui.QWidget,'neighb_excl_solvent').checkState())
    neighb_hb =  1 - guiUtils.fromCheckState(self.findChild(QtGui.QWidget,'neighb_hb').checkState())
    #neighb_sym = guiUtils.fromCheckState(self.findChild(QtGui.QWidget,'neighb_sym').checkState())
    neighb_mol = self.findChild(QtGui.QWidget,'neighb_sel').getCurrentDataObj().name
    if neighb_mol == self.moldata_name: neighb_mol = ''
    return dict (
        select = 'neighb',
        neighb_sel = neighb_sel,
        neighb_mol = neighb_mol,
        neighb_group = neighb_group,
        neighb_rad = neighb_rad,
        neighb_excl = neighb_excl,      
        neighb_excl_solvent = neighb_excl_solvent,
        neighb_hb = neighb_hb )
        #neighb_sym = neighb_sym)

    
#------------------------------------------------------------------------
  def getSelHandle(self):
#------------------------------------------------------------------------
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'neighb'
    #print "neighbGui.getSelHandle",pars
    rv = selHnd.setSelParams(pars)
    
    #print 'getSelHandle rv',rv

    return selHnd
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class buriedGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------

  buried_group_menu = ['atoms','residues']
  buried_group_alias = ['atom','residue']
  
  def __init__(self,parent,moldata_name):

    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    molobj = data(self.moldata_name )
    
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    
    line_layout = QtGui.QHBoxLayout()
    widget =  QtGui.QLabel('Select',self)
    line_layout.addWidget(widget)
    seleGroup = QtGui.QComboBox(self)
    seleGroup.setObjectName('buried_group')
    seleGroup.addItems(buriedGui.buried_group_menu)
    line_layout.addWidget(seleGroup)
    widget =  QtGui.QLabel('in..',self)
    line_layout.addWidget(widget)
    line_layout.addStretch(5)
    layout.addLayout(line_layout)

    if molobj:
      Sel = mgWidgets.mgSelectionCombo(self,molobj.treeModel)
      Sel.setObjectName('buried_and_selection')
      layout.addWidget(Sel)
    
    line_layout = QtGui.QHBoxLayout()
    widget = QtGui.QLabel('With more than',self)
    line_layout.addWidget(widget)
    rad = QtGui.QDoubleSpinBox(self)
    rad.setObjectName('buried_area')
    rad.setRange(0.0,20.0)
    rad.setSingleStep(0.2)
    rad.setDecimals(1)
    line_layout.addWidget(rad)
    widget = QtGui.QLabel('A2 buried by..',self)
    line_layout.addWidget(widget)
    line_layout.addStretch(5)
    layout.addLayout(line_layout)
  
    if molobj:
      Sel = mgWidgets.mgSelectionCombo(self,molobj.treeModel,multi=1)
      Sel.setObjectName('buried_sel')
      layout.addWidget(Sel)

    applyLine = QtGui.QHBoxLayout()
    buriedApply = QtGui.QPushButton('Select buried region',self)
    self.connect(buriedApply,QtCore.SIGNAL('clicked()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    applyLine.addStretch()
    applyLine.addWidget(buriedApply)
    layout.addLayout(applyLine)
    
    layout.addStretch() 
    self.setLayout(layout)

#-----------------------------------------------------------------------
  def setParams(self,pars={},**kw):
#-----------------------------------------------------------------------
    #print 'buriedGui.setParams',pars
    pars.update(kw)
    
    self.findChild(QtGui.QWidget,'buried_area').setValue(float(pars.get('buried_area',2.0)))
    
    group = pars.get('buried_group','atom')
    self.findChild(QtGui.QWidget,'buried_group').setCurrentIndex(buriedGui.buried_group_alias.index(group))
    
    molobj = data(pars.get('buried_mol',''))
    if molobj: self.findChild(QtGui.QWidget,'buried_sel').setCurrentDataObj( molobj)
    self.findChild(QtGui.QWidget,'buried_sel').setParams({ 'selection' : pars.get('buried_sel','')})

    self.findChild(QtGui.QWidget,'buried_and_selection').setParams({ 'selection' : pars.get('buried_and_selection','')} )


#------------------------------------------------------------------------
  def getParams(self):
#------------------------------------------------------------------------    

    pars =  dict (
        select = 'buried',
        buried_and_selection = str(self.findChild(QtGui.QWidget,'buried_and_selection').text()),
        buried_sel = str(self.findChild(QtGui.QWidget,'buried_sel').text()),
        buried_mol = self.findChild(QtGui.QWidget,'buried_sel').getCurrentDataObj().name,
        buried_group = guiUtils.fromMenu(str(self.findChild(QtGui.QWidget,'buried_group').currentText()),buriedGui.buried_group_menu,buriedGui.buried_group_alias),
        buried_area = float(self.findChild(QtGui.QWidget,'buried_area').value())
        )
    #print 'buriedGui.getParams',pars
    return pars

    
#------------------------------------------------------------------------
  def getSelHandle(self):
#------------------------------------------------------------------------
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'buried'
    #print "neighbGui.getSelHandle",pars
    rv = selHnd.setSelParams(pars)
    
    #print 'getSelHandle rv',rv

    return selHnd


#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class atomTypeGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  
  def __init__(self,parent,moldata_name,height=200,width=400):

    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)
    atom_names = []
    atom_groups = []

    '''
    set_type = [['amino_acid','generic'],['nucleic_acid','generic']]
    for montype,s in set_type:
      names,codes,groups = MODELINFO().get_protocol_menu(\
       type=montype, set=s)
      
      for n in range(0,min(len(codes),len(names))):
        if not mon_names.count([codes[n],names[n]]):
          mon_names.append([codes[n],names[n]])
            
      for item in groups.items():
        if not mon_groups.count([item[0],item[1]]):
          mon_groups.append([item[0],item[1]])
    '''

    layout = QtGui.QHBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    atomTypeWidget = mgWidgets.mgGroupSelector(self,groups = atom_groups,items = atom_names, height=height,width=width)

    atomTypeWidget.setObjectName('atomType')
    self.connect(atomTypeWidget,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    layout.addWidget(atomTypeWidget)
    self.setLayout(layout)


#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------
    return  { 'select' : 'atomtypes',
       'atomtypes' :self.findChild(QtGui.QWidget,'atomType').getSelection() }

#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------
    if params.has_key('atomtypes'):
      self.findChild(QtGui.QWidget,'atomType').setSelection(params['atomtypes'])

#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'atomtypes'
    rv = selHnd.setSelParams(pars)
    
    #print 'resTypeGui getSelHandle rv',rv

    return selHnd

#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class elementTypeGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  
  def __init__(self,parent,moldata_name,height=200,width=400):

    QtGui.QWidget.__init__(self,parent)
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    self.moldata_name = moldata_name
    names = ['C','N','O']
    names.extend(data(self.moldata_name).get_attribute('element_list'))
    ele_names = []
    for item in names: ele_names.append([item,item])
    ele_groups = []

    typeWidget = mgWidgets.mgGroupSelector(self,groups = ele_groups,items = ele_names, height=height,width=width)

    typeWidget.setObjectName('elementType')
    self.connect(typeWidget,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    typeWidget.show()
    layout.addWidget(typeWidget)
    self.setLayout(layout)
    self.show()


#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------
    return  { 'select' : 'elementtypes',
              'elementtypes' :
              self.findChild(QtGui.QWidget,'elementType').getSelection() }

#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------
    if params.has_key('elementtypes'):
      self.findChild(QtGui.QWidget,'elementType').setSelection(params['elementtypes'])

#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'elementtypes'
    rv = selHnd.setSelParams(pars)
    
    #print 'resTypeGui getSelHandle rv',rv

    return selHnd

#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class resTypeGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  
  def __init__(self,parent,moldata_name,height=200,width=400):

    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)
    set_type = []
    mon_names = []
    mon_groups = []
    if moldata:
      for moltype,montype in [ [ 'PROTEIN','amino_acid'],
                             ['NUCLEIC', 'nucleic_acid']]:
        if moldata.molecule_type.count(moltype):
          set_type.append([montype,moldata.name_label])
    else:
        set_type = [['amino_acid','generic'],['nucleic_acid','generic']]
    for montype,s in set_type:
      names,codes,groups = MODELINFO().get_protocol_menu(\
       type=montype, set=s)
      
      for n in range(0,min(len(codes),len(names))):
        if not mon_names.count([codes[n],names[n]]):
          mon_names.append([codes[n],names[n]])
            
      for item in groups.items():
        if not mon_groups.count([item[0],item[1]]):
          mon_groups.append([item[0],item[1]]) 

    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)

    resTypeWidget = mgWidgets.mgGroupSelector(self,groups = mon_groups,items = mon_names, height=height,width=width)

    resTypeWidget.setObjectName('resType')
    self.connect(resTypeWidget,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    layout.addWidget(resTypeWidget)
    self.setLayout(layout)
    self.show()
    
#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------
    return  { 'select' : 'restypes',
         'restypes' : self.findChild(QtGui.QWidget,'resType').getSelection() }

#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------
    if params.has_key('restypes'):
      self.findChild(QtGui.QWidget,'resType').setSelection(params['restypes'])

#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'restypes'
    rv = selHnd.setSelParams(pars)
    
    #print 'resTypeGui getSelHandle rv',rv

    return selHnd
  
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class chainsGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  
  def __init__(self,parent,moldata_name,height=200,width=400):

    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)
    set_type = []
    chain_names = []
    chain_groups = []

    if moldata:
      chain_list = moldata.get_attribute('chain_list')
      
    import string
    for chn in chain_list: chain_names.append([string.rstrip(chn,'/'),chn])
    #print 'chainsGui.chain_names',chain_names

    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)


    chainWidget = mgWidgets.mgGroupSelector(self,groups = chain_groups,items = chain_names, height=height,width=width)

    chainWidget.setObjectName('chains')
    self.connect(chainWidget,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    layout.addWidget(chainWidget)
    self.setLayout(layout)

    self.show()


#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------
     return  {  'select' : 'chains',
                'chains' : self.findChild(QtGui.QWidget,'chains').getSelection() }

#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------
    if params.has_key('chains'):
      self.findChild(QtGui.QWidget,'chains').setSelection(params['chains'])

#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    pars['select'] = 'chains'
    rv = selHnd.setSelParams(pars)
    

    return selHnd


#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class namedSelectionGui(QtGui.QFrame):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  
  
  def __init__(self,parent,moldata_name,save=0,close=0,delete=1,height=200,width=200):

    QtGui.QFrame.__init__(self,parent)
    self.setFrameStyle(QtGui.QFrame.Box)
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)

    #self.setMaximumWidth(width)

    if save:
      label =  QtGui.QLabel('Save/restore selections',self)
    else:
      label =  QtGui.QLabel('Restore selection',self)
    self.list_widget = ModelInfoTree(sets=[moldata.name_label,'generic'],info='user_selection',parent=self)
    self.list_widget.setObjectName('list')
    self.list_widget.setToolTip('List of saved named atom selections')
    self.connect(self.list_widget,QtCore.SIGNAL('doubleClicked(QModelIndex)'),guiUtils.partial(self.emit,QtCore.SIGNAL('restore')))
    

    restore_widget =  QtGui.QPushButton('Restore')
    restore_widget.setToolTip('Restore the highlighted named selection')
    self.connect(restore_widget,QtCore.SIGNAL('released()'),guiUtils.partial(self.emit,QtCore.SIGNAL('restore')))
    if save:
      save_widget = QtGui.QPushButton('Save')
      save_widget.setToolTip('Save the current selection')
      self.connect(save_widget,QtCore.SIGNAL('released()'),self.handleSave)
      
    if delete:
      delete_widget = QtGui.QPushButton('Delete')
      delete_widget.setToolTip('Delete the current selection')
      self.connect(delete_widget,QtCore.SIGNAL('released()'),self.handleDelete)

    if close:
      close_widget = QtGui.QPushButton('Close')
      close_widget.setToolTip('Close this window')
      self.connect(close_widget,QtCore.SIGNAL('released()'),guiUtils.partial(self.emit,QtCore.SIGNAL('close')))      

    layout = QtGui.QGridLayout()
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)
    layout.setSpacing(MARGIN)

    layout.addWidget(label,0,0,1,3)
    layout.addWidget(self.list_widget,1,0,1,3)
    #if save: layout.addWidget(save_widget,2,1,1,1)
    if delete: layout.addWidget(delete_widget,2,1,1,1)
    #if close: layout.addWidget(close_widget,2,2,1,1)
    layout.addWidget(restore_widget,2,0,1,1)
    self.setLayout(layout)

    self.list_widget.populate()

    self.connect(DISPLAYTABLE().getDataObj(self.moldata_name),QtCore.SIGNAL('savedNamedSelection'),
                 self.list_widget.populate)
    
#----------------------------------------------------------------------
  def handleSave(self):
#----------------------------------------------------------------------
    # Prompt user for name for saved selection
    if hasattr(self,'save_dialog'):
      self.save_dialog.show()
      self.save_dialog.raise_()
    else:
      self.save_dialog = ModelInfoSave(parent=self,info='user_selection',sets=[self.moldata_name,'generic'])
      self.connect(self.save_dialog,QtCore.SIGNAL('save'),guiUtils.partial(self.emit,QtCore.SIGNAL('save')))     
      self.save_dialog.show()

#----------------------------------------------------------------------
  def handleDelete(self):
#----------------------------------------------------------------------
    set,label = self.list_widget.selectedItem()
    if not label: return
    gui = ModelInfoDelete(self,info='user_selection',set=set,label=label)
    self.connect(gui,QtCore.SIGNAL('deleted'), self.list_widget.populate)

  def getParams(self):
    return {}
  def setParams(self,params):
    pass

  def getSelection(self):
    return self.list_widget.selectedItem()
    

class mgLineEdit(QtGui.QLineEdit):

  def __init__(self,parent=None):
    QtGui.QLineEdit.__init__(self,parent)

  def keyReleaseEvent(self,event):
    #print "keyReleaseEvent",event.key()
    if event.key()!=QtCore.Qt.Key_Return:
      event.ignore()
      
  def keyPressEvent(self,event):
    #print "keyPressEvent",event.key()
    if event.key()!=QtCore.Qt.Key_Return:
      event.ignore()


#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class atomSelectionGui(QtGui.QFrame):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------

  type_commands = {
    'PROTEIN' : ['main','side','catrace','CA+side','peptide_link','ssbond'],
    'NUCLEIC' : ['backbone','sugar_ring','base','trace'] }
  
#-----------------------------------------------------------------------    
  def __init__(self,parent,moldata_name,height=200,width=200):
#-----------------------------------------------------------------------    

    QtGui.QFrame.__init__(self,parent)
    #self.setFrameStyle(QtGui.QFrame.Box)
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)
    #self.setMaximumWidth(width)
    
    layout = QtGui.QHBoxLayout(self)
    layout.setContentsMargins(NOMARGIN,NOMARGIN,NOMARGIN,NOMARGIN)
    layout.setSpacing(MARGIN)
    
    self.show_hydrogen = 0
     
    layout.addWidget(QtGui.QLabel('Show',self))
    self.selection = QtGui.QComboBox(self)
    self.selection.setEditable(0)
    self.selection.setMinimumContentsLength(10)
    self.selection.addItem('all',QtCore.QVariant(''))
    self.connect(self.selection,QtCore.SIGNAL('currentIndexChanged(int)'),self.appy)
    layout.addWidget(self.selection)
    layout.addWidget(QtGui.QLabel('of..',self))
    molecule_type = moldata.get('molecule_type')
    for mtype in ['PROTEIN','NUCLEIC']:
      if molecule_type.count(mtype):
        for com in atomSelectionGui.type_commands[mtype]:
          label = model_selection.SELECTION_LABELS.get(com,'')
          self.selection.addItem(label,QtCore.QVariant(com))

    '''
    # This is not used - use show_hydrogen widget in the general tab
    if moldata.contains_hydrogen:      
      layout.addWidget(QtGui.QLabel('atoms and',self))
      self.show_hydrogen = QtGui.QCheckBox('hydrogens',self)
      layout.addWidget(self.show_hydrogen)
    else:
      layout.addWidget(QtGui.QLabel('atoms',self))
    '''
    
    layout.addStretch(5)

    self.setLayout(layout)
    self.show()
           
#-----------------------------------------------------------------------    
  def appy(self,state):
#-----------------------------------------------------------------------    
    #print "atomSelectionGui.apply",state
    self.emit(QtCore.SIGNAL('changed'))

#-----------------------------------------------------------------------    
  def getParams(self):
#-----------------------------------------------------------------------    
    pars = { 'atomtype' : str(self.selection.itemData(self.selection.currentIndex()).toString()) }
    if self.show_hydrogen: pars['nothydrogen'] = 1 - int(self.show_hydrogen.isChecked())
    #print "atomSelectionGui.getParams",pars
    return pars

 #-----------------------------------------------------------------------    
  def setParams(self,params={}):
#-----------------------------------------------------------------------
    #print 'atomSelectionGui params',params
    if params.has_key('atomtype'):
      for ii in range(0,self.selection.count()):
        #print 'atomSelectionGui.setParams',ii,self.selection.itemData(ii).toString()
        if str(self.selection.itemData(ii).toString())==params['atomtype']:
          self.selection.setCurrentIndex(ii)
          break
    if params.has_key('nothydrogen') and self.show_hydrogen:
      self.show_hydrogen.setChecked(1-params['nothydrogen'])
      
#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    import model_selection
    SelHandle = model_selection.SelHandle(self.moldata_name)
    rv = SelHandle.setSelParams(self.getParams())
    return SelHandle

#---------------------------------------------------------------------------
  def getSelection(self):
#---------------------------------------------------------------------------
    import string
    sele = string.strip(str(self.selection.itemData(self.selection.currentIndex()).toString()))
    if self.show_hydrogen:
      nothydrogen =  1 - int(self.show_hydrogen.isChecked())
      if nothydrogen:
        if sele:
          sele = sele + ' excl /*/*/*,*/*[H];*'
        else:
          sele = 'all excl /*/*/*,*/*[H];*'
    return sele

#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class interactiveGui(QtGui.QFrame):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  
#-----------------------------------------------------------------------    
  def __init__(self,parent,moldata_name,height=200,width=200):
#-----------------------------------------------------------------------    

    QtGui.QFrame.__init__(self,parent)
    self.setFrameStyle(QtGui.QFrame.Box)
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)
    #self.setMaximumWidth(width)
    
    layout = QtGui.QVBoxLayout()
    layout.setContentsMargins(NOMARGIN,NOMARGIN,NOMARGIN,NOMARGIN)
    layout.setSpacing(MARGIN)
    
    layout.addWidget(QtGui.QLabel('Interactive selection',self))
    
    line_layout = QtGui.QHBoxLayout()             
    self.showSkeleton = QtGui.QCheckBox('Show',self)
    line_layout.addWidget(self.showSkeleton)      
    self.selection = QtGui.QComboBox(self)
    self.selection.addItem('all atom')
    self.selection.addItem('trace')
    self.selection.setEditable(0)
    line_layout.addWidget(self.selection)
    line_layout.addWidget(QtGui.QLabel('skeleton',self))
    layout.addLayout(line_layout)
                     
    self.connect(self.showSkeleton,QtCore.SIGNAL('toggled(bool)'),self.toggleSkeleton)
    self.connect(self.selection,QtCore.SIGNAL('currentIndexChanged(int)'),self.setSelection)
    
    self.setLayout(layout)
    self.show()

#-----------------------------------------------------------------------    
  def setSelection(self):
#-----------------------------------------------------------------------
    if not hasattr(self,'skeletonDispobj'): return
    
    sele = str(self.selection.currentText())
    if sele == 'trace':
      self.skeletonDispobj.SelHandle.setSelParams(selparams = { 'select' : 'cid' ,
                                                                'cid' : 'catrace or nucleic or monomers' } )
    else:
      self.skeletonDispobj.SelHandle.setSelParams(selparams = { 'select' : 'all' } )
    self.skeletonDispobj.set_reapply_selection()
    import rebuild
    rebuild.UpdateDisplay()

#-----------------------------------------------------------------------    
  def toggleSkeleton(self,state):
#-----------------------------------------------------------------------    
    #print "interactiveGui.toggleSkeleton",state
    if hasattr(self,'skeletonDispobj'):
      self.skeletonDispobj.delete()
      del self.skeletonDispobj
    if state:
      import model

      sele = str(self.selection.currentText())
      if sele == 'trace':
        selparams = { 'select' : 'catrace' }
      else:
        selparams = { 'select' : 'all' }
      self.skeletonDispobj = model.MolDisp (self.moldata_name, \
               selparams = selparams , styleparams= { 'style_mode' : 'THINBONDS' },
               master_application=self,display_table_visible=0)
      
    import rebuild
    rebuild.UpdateDisplay()

  def setParams(self,params):
    pass

#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    
class Property(QtGui.QWidget):
#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    

  property_menu = ['Temperature factor','Occupancy', \
                   'X coordinate','Y coordinate','Z coordinate', \
                   'Atom SAS', 'Residue SAS','Atom buried area','Residue buried area',
                   'Serial number' ]

  property_alias = ['B','OCC','X','Y','Z','ATOM_SAS','RES_SAS', \
                    'ATOM_BURIED','RES_BURIED', 'SERIAL' ]
  property_short = ['Temp','Occ','X','Y','Z','SAS','SAS', \
                    'Buried','Buried', 'Serial' ]
  lt_menu = ['<','<=']
  gt_menu = ['<','<=','==']
  
  #property_enum =  [PROPERTY_B,PROPERTY_OCC, \
  #                  PROPERTY_X,PROPERTY_Y,PROPERTY_Z,
  #                  PROPERTY_ATOM_SAS,PROPERTY_RES_SAS,
  #                  PROPERTY_ATOM_CONTACT, PROPERTY_RES_CONTACT,
  #                  PROPERTY_SERIAL]

  def __init__(self,parent=None,moldata_name='',width=400):

    super(Property,self).__init__(parent)
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)
    self.widgetWidth = width
    self.setMaximumWidth(self.widgetWidth)
    layout = QtGui.QHBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(NOMARGIN,NOMARGIN,NOMARGIN,NOMARGIN)
    minWidget = QtGui.QLineEdit()
    #minWidget.setMaximumWidth(100)
    #minWidget.setMinimumWidth(100)
    minWidget.setObjectName('property_gt_value')
    self.validator = QtGui.QDoubleValidator(self)
    minWidget.setValidator(self.validator)
    minOpWidget = QtGui.QComboBox()
    minOpWidget.setObjectName('property_gt_op')
    for item in Property.gt_menu:
      minOpWidget.addItem(item)
    propWidget =  QtGui.QComboBox()
    propWidget.setObjectName('property')
    #propWidget.setMaximumWidth(propWidget.fontMetrics().width('Residue buried area')+2)
    ii=-1
    for item in Property.property_menu:
      ii = ii +1
      propWidget.addItem(item)
      propWidget.setItemData(ii,QtCore.QVariant(Property.property_alias[ii]))
    maxOpWidget =  QtGui.QComboBox()
    maxOpWidget.setObjectName('property_lt_op')
    for item in Property.lt_menu:
      maxOpWidget.addItem(item)
    maxWidget = QtGui.QLineEdit()
    #maxWidget.setMaximumWidth(100)
    #maxWidget.setMinimumWidth(100)
    maxWidget.setObjectName('property_lt_value')
    maxWidget.setValidator(self.validator)

    layout.addWidget(minWidget,1)
    layout.addWidget(minOpWidget)
    layout.addWidget(propWidget,1)
    layout.addWidget(maxOpWidget)
    layout.addWidget(maxWidget,1)

    self.setLayout(layout)

#-----------------------------------------------------------------------
  def setDefault(self):
#-----------------------------------------------------------------------
    self.findChild(QtGui.QWidget,'property_gt_value').setText('')
    self.findChild(QtGui.QWidget,'property_gt_op').setCurrentIndex(0)
    self.findChild(QtGui.QWidget,'property').setCurrentIndex(0)
    self.findChild(QtGui.QWidget,'property_lt_value').setText('')
    self.findChild(QtGui.QWidget,'property_lt_op').setCurrentIndex(0)

'''
#-----------------------------------------------------------------------
  def setParams(self,params={},**kw):
#-----------------------------------------------------------------------
    params.update(kw)
    if params.has_key('property_gt_value'):
      self.findChild(QtGui.QWidget,'property_gt_value').setText(params['property_gt_value'])
    if Property.gt_menu.count(params.get('property_gt_op','')):
      ic = Property.gt_menu.index(params['property_gt_op'])
      self.findChild(QtGui.QWidget,'property_gt_op').setCurrentIndex(ic)
    if Property.property_menu.count(params.get('property','')):
      ic = Property.property_menu.index(params['property'])
      self.findChild(QtGui.QWidget,'property').setCurrentIndex(ic)
    if Property.lt_menu.count(params.get('property_lt_op','')):
      ic = Property.lt_menu.index(params['property_lt_op'])
      self.findChild(QtGui.QWidget,'property_lt_op').setCurrentIndex(ic)
    if params.has_key('property_lt_value'):
      self.findChild(QtGui.QWidget,'property_lt_value').setText(params['property_lt_value'])

    
#-----------------------------------------------------------------------    
  def getParams(self):
#-----------------------------------------------------------------------    
    pars = {}
    pars['property_gt_value']= str(self.findChild(QtGui.QWidget,'property_gt_value').text())
    icur = self.findChild(QtGui.QWidget,'property_gt_op').currentIndex()
    pars['property_gt_op'] = Property.gt_menu[icur]
    icur = self.findChild(QtGui.QWidget,'property').currentIndex()
    pars['property'] = Property.property_alias[icur]
    icur = self.findChild(QtGui.QWidget,'property_lt_op').currentIndex()
    pars['property_lt_op'] = Property.lt_menu[icur]
    pars['property_lt_value'] = str(self.findChild(QtGui.QWidget,'property_lt_value').text())
    return pars
'''

#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class propertyGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  
  def __init__(self,parent,moldata_name):
    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(NOMARGIN,NOMARGIN,NOMARGIN,NOMARGIN)

    joinLine = QtGui.QWidget()
    joinLayout =  QtGui.QHBoxLayout()
    joinLabel= QtGui.QLabel('Select atoms that satisfy',self)
    joinAny = QtGui.QRadioButton('any or',self)
    joinAny.setObjectName('joinAny')
    joinAll = QtGui.QRadioButton('all criteria',self)
    joinAll.setObjectName('joinAll')
    joinGroup = QtGui.QButtonGroup()
    joinGroup.addButton(joinAny)
    joinGroup.addButton(joinAll)
    joinAny.setChecked(1)
    joinLayout.addWidget(joinLabel)
    joinLayout.addWidget(joinAny)
    joinLayout.addWidget(joinAll)
    joinLayout.addStretch(5)
    joinLine.setLayout(joinLayout)
    layout.addWidget(joinLine)
    
    #self.exFrame = mgWidgets.extendingFrame(self,widget=Property,height=height-30,width=width)
    self.exFrame = mgWidgets.extendingFrame(self,widget=Property,width=self.parent().width()-20)
    layout.addWidget(self.exFrame)
    layout.addStretch()
    self.exFrame.show()

    self.setLayout(layout)
    
    self.connect(self.exFrame,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))

    
#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------

    pars = self.exFrame.getParams ({ 'property_gt_value': [],
              'property_gt_op' : [],
              'property' : [],
              'property_lt_value': [],
              'property_lt_op' : [] } )
    
    if self.findChild(QtGui.QRadioButton,'joinAny').isChecked():
      pars['property_join'] = 'or'
    else:
      pars['property_join'] = 'and'
    pars['select'] = 'property'
    return pars

#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------

    #print "propertyGui.setParams",params
    join = params.get('property_join','or') == 'or'
    self.findChild(QtGui.QRadioButton,'joinAny').setChecked(join)
    self.findChild(QtGui.QRadioButton,'joinAll').setChecked(1-join)

    pars = {}
    for key in ['property','property_gt_value','property_lt_value','property_gt_op','property_lt_op']:
      if params.has_key(key): pars[key] = params.get(key)
    if not len(pars.keys()):
      self.exFrame.setNofLines(0)
    else:
      self.exFrame.setParams(pars)

    '''
    property = params.get('property',[])
    property_gt_value = params.get('property_gt_value',[])
    property_gt_op = params.get('property_gt_op',[])
    property_lt_value = params.get('property_lt_value',[])
    property_lt_op = params.get('property_lt_op',[])

    self.exFrame.setNofLines(max(len(property),1))
    if len(property) == 0:
      self.exFrame.getLine(0).setDefault()
    else:
      for ii in range(0,len(property)):
        self.exFrame.getLine(ii).setParams( {
          'property' : property[ii],
          'property_gt_value' : property_gt_value[ii],
          'property_gt_op' : property_gt_op[ii],
          'property_lt_value' : property_lt_value[ii],
          'property_lt_op' : property_lt_op[ii] } )
    '''

#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    import model_selection
    pars = self.getParams()
    pars['select'] = 'property'

    SelHandle = model_selection.SelHandle(self.moldata_name)
    rv = SelHandle.setSelParams(pars)
    
    #print 'propertyGui getSelHandle rv',rv

    return SelHandle
  
#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    
class SelRange(QtGui.QWidget):
#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    
#-----------------------------------------------------------------------    


  def __init__(self,parent=None,moldata_name='',width=400):

    super(SelRange,self).__init__(parent)
    #print 'SelRange parent',parent
    self.moldata_name = moldata_name
    moldata = data(self.moldata_name)
    self.widgetWidth = width
    self.setMaximumWidth(self.widgetWidth)
    layout = QtGui.QHBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(NOMARGIN,NOMARGIN,NOMARGIN,NOMARGIN)
    widget = mgWidgets.mgAtomPicker(self,MolData_name=self.parent().moldata_name,mode='range',blank=1)
    widget.setObjectName('ranges')
    layout.addWidget(widget)
    

    self.setLayout(layout)

#-----------------------------------------------------------------------
  def setDefault(self):
#-----------------------------------------------------------------------
    self.findChild(QtGui.QWidget,'ranges').reset()


#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class rangesGui(QtGui.QWidget):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
  ranges_qualifier_menu = ['peptide','main chain','side chain']
  ranges_qualifier_alias = ['','main','side']
  ranges_neighb_invert_menu = ['with','with no']
  ranges_neighb_invert_alias = [0,1]
  ranges_neighb_qualifier_menu = ['atoms','main chain atoms','side chain atoms']
  ranges_neighb_qualifier_alias = ['all','main','side']
  
  def __init__(self,parent,moldata_name):
    QtGui.QWidget.__init__(self,parent)
    self.moldata_name = moldata_name
    
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(NOMARGIN,NOMARGIN,NOMARGIN,NOMARGIN)
    

    line_layout = QtGui.QHBoxLayout()
    self.ranges_extend = QtGui.QRadioButton('Extend ranges to CA of neighbouring residues',self)
    self.ranges_extend.setToolTip('Extend range to join neatly to ribbon or worm display objects')
    line_layout.addWidget(self.ranges_extend)
    line_layout.addWidget(QtGui.QLabel('Select'))
    self.ranges_qualifier = QtGui.QComboBox(self)
    for item in rangesGui.ranges_qualifier_menu:
      self.ranges_qualifier.addItem(item)
    line_layout.addWidget(self.ranges_qualifier)
    line_layout.addStretch(5)
    layout.addLayout(line_layout)

    frame_margin = 1
    frame =  QtGui.QGroupBox('Find ranges in neighbourhood of ',self)
    frame_layout =  QtGui.QVBoxLayout()
    frame_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)
    frame_layout.setSpacing(frame_margin)
    
    molobj = data(self.moldata_name)
    line_layout = QtGui.QHBoxLayout()
    line_layout.addWidget(QtGui.QLabel('Find ranges of residues',self))
    self.ranges_neighb_invert = QtGui.QComboBox(self)
    for item in rangesGui.ranges_neighb_invert_menu:
      self.ranges_neighb_invert.addItem(item)
    line_layout.addWidget(self.ranges_neighb_invert)
 
    self.ranges_neighb_qualifier = QtGui.QComboBox(self)
    for item in rangesGui.ranges_neighb_qualifier_menu:
      self.ranges_neighb_qualifier.addItem(item)
    line_layout.addWidget(self.ranges_neighb_qualifier)
    line_layout.addWidget(QtGui.QLabel('within',self))
    self.ranges_neighb_cutoff = QtGui.QDoubleSpinBox(self)
    self.ranges_neighb_cutoff.setRange(0.0,100.0)
    self.ranges_neighb_cutoff.setSingleStep(0.5)
    self.ranges_neighb_cutoff.setDecimals(1)
    self.ranges_neighb_cutoff.setValue(4.0)
    line_layout.addWidget(self.ranges_neighb_cutoff)
    line_layout.addWidget(QtGui.QLabel('of',self))
    line_layout.addStretch(5)
    frame_layout.addLayout(line_layout)

    line_layout = QtGui.QHBoxLayout()
    self.ranges_neighb_selection = mgWidgets.mgSelectionCombo(self,multi=1)
    self.ranges_neighb_selection.setCurrentDataObj(self.moldata_name)
    line_layout.addWidget(self.ranges_neighb_selection)
    frame_layout.addLayout(line_layout)

    line_layout = QtGui.QHBoxLayout()
    button = QtGui.QPushButton('Find ranges around selection',self)
    line_layout.addStretch(5)
    line_layout.addWidget(button)
    frame_layout.addLayout(line_layout)
    self.connect(button,QtCore.SIGNAL('clicked(bool)'),self.selectNeighb)

    frame.setLayout(frame_layout)
    layout.addWidget(frame)
    
    #self.exFrame = mgWidgets.extendingFrame(self,widget=Property,height=height-30,width=width)
    #self.exFrame = mgWidgets.extendingFrame(self,widget=SelRange,width=self.parent().width()-20)
    self.exFrame = mgWidgets.extendingFrame(self,widget=SelRange,ifClear=1)
    layout.addWidget(self.exFrame)
    layout.addStretch()
    self.exFrame.show()
       

    self.setLayout(layout)
    
    self.connect(self.exFrame,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))

    
#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------

    pars = self.exFrame.getParams ({ 'ranges': []
               } )
    pars['select'] = 'ranges'
    pars['ranges_extend'] = int(self.ranges_extend.isChecked())
    pars['ranges_qualifier'] = rangesGui.ranges_qualifier_alias[self.ranges_qualifier.currentIndex()]
    
    #print 'rangesGui.getParams',pars
    return pars

#---------------------------------------------------------------------------
  def getNeighbParams(self):
#---------------------------------------------------------------------------
    model = self.ranges_neighb_selection.getCurrentDataObj().name
    if model == self.moldata_name: model = ''
    pars = {
      'ranges_neighb_cutoff' : self.ranges_neighb_cutoff.value(),
      'ranges_neighb_selection' : self.ranges_neighb_selection.text(),
      'ranges_neighb_invert' : self.ranges_neighb_invert_alias[self.ranges_neighb_invert.currentIndex()],
      'ranges_neighb_qualifier'  : self.ranges_neighb_qualifier_alias[self.ranges_neighb_qualifier.currentIndex()],
      'ranges_neighb_model' : model }
    return pars

#---------------------------------------------------------------------------
  def setParams(self,params={},**kw):
#---------------------------------------------------------------------------
    params.update(kw)
    #print "rangesGui.setParams",params
    for key,value in params.items():
      
      if ['ranges_extend'].count(key):
          getattr(self,key).setChecked(value)
        
      elif key =='ranges':
        if not len(value):
          self.exFrame.setNofLines(0)
        else:
          pars = {'ranges':[]}
          for item in value: pars['ranges'].append(item)
          self.exFrame.setParams(pars)

      elif ['ranges_qualifier','ranges_neighb_qualifier','ranges_neighb_invert'].count(key):
        alias_list =  getattr(self,key+'_alias')
        if alias_list.count(value):
          getattr(self,key).setCurrentIndex(alias_list.index(value))

      elif key == 'ranges_neighb_model':
        if value.strip():
          self.ranges_neighb_selection.setCurrentDataObj(value)
        else:
          self.ranges_neighb_selection.setCurrentDataObj(self.moldata_name)
       
      elif key == 'ranges_neighb_selection':
        getattr(self,key).setText(value)
                                                                      
     
      elif key == 'ranges_neighb_cutoff':
        getattr(self,key).setValue(value)

#---------------------------------------------------------------------------
  def getSelHandle(self):
#---------------------------------------------------------------------------
    import model_selection
    pars = self.getParams()
    pars.update(self.getNeighbParams())
    pars['select'] = 'ranges'

    SelHandle = model_selection.SelHandle(self.moldata_name)
    rv = SelHandle.setSelParams(pars)
    
    #print 'rangesGui getSelHandle rv',rv

    return SelHandle

#---------------------------------------------------------------------------
  def selectNeighb(self,**kw):
#---------------------------------------------------------------------------
    pars = self.getNeighbParams()
    #print 'selectNeighb',pars
    rv = data(self.moldata_name).selectNeighbRanges(cid=pars['ranges_neighb_selection'],model=pars['ranges_neighb_model'],maxd=pars['ranges_neighb_cutoff'],group=pars['ranges_neighb_qualifier'],invert=pars['ranges_neighb_invert'])
    #print 'selectNeighb rv',rv
    if rv[0]:
      QtGui.QMessageBox.warning(self,'Error in selecting ranges in neighbourhood',rv[1])
    else:
      pars = self.exFrame.getParams ({ 'ranges': [] } )
      for item in rv[1]:
        pars['ranges'].append(item)
      self.exFrame.setParams(pars)
      self.emit(QtCore.SIGNAL('accepted()'))
      
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
class nmrModelsGui(QtGui.QFrame):
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------

  
  def __init__(self,parent,moldata_name,height=200,width=400):

    QtGui.QFrame.__init__(self,parent)
    self.moldata_name = moldata_name
    self.setFrameStyle(QtGui.QFrame.Box)
    self.draw()



#---------------------------------------------------------------------------
  def draw(self):
#---------------------------------------------------------------------------

    layout = self.layout()
    if layout:
      self.show()
      return
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(MARGIN)
    layout.setContentsMargins(MARGIN,MARGIN,MARGIN,MARGIN)
    molobj = data(self.moldata_name)
    if molobj:
      model_list = molobj.get_attribute('model_list')
    else:
      model_list=[]
    mlist = []
    for item in model_list: mlist.append([item,item])
    #print "nmrModelsGui",model_list
    self.modelWidget = mgWidgets.mgGroupSelector(self,items = mlist,height=tabHeight,width=tabWidth,reMatch=0)
    self.connect(self.modelWidget,QtCore.SIGNAL('accepted()'),guiUtils.partial(self.emit,QtCore.SIGNAL('accepted()')))
    layout.addWidget(self.modelWidget)
    self.setLayout(layout)
    self.show()

#---------------------------------------------------------------------------
  def setParams(self,params={}):
#---------------------------------------------------------------------------
    if params.has_key('nmr_models'):
      molobj = data(self.moldata_name)
      #print "setParams nmr_models",params['nmr_models']
      outlist = []
      for item in params['nmr_models']:
        symid = molobj.model_symmetry.modelSymid(item[1:])
        if symid:
          outlist.append(item+' '+symid)
        else:
          outlist.append(item)
      #print 'nmrModelsGui.setParams',params,outlist
      self.modelWidget.setSelection(outlist)

#---------------------------------------------------------------------------
  def getParams(self):
#---------------------------------------------------------------------------
    # Beware removing any symid that is added after the model number
    models = self.modelWidget.getSelection()
    outlist = []
    for item in models: outlist.append(item.split()[0])
    print 'nmrModelsGui.getParams',outlist
    return  {'nmr_models' : outlist }
  
#---------------------------------------------------------------------------
  def getSelHandle(self):
#--------------------------------------------------------------------------- 
    
    selHnd = model_selection.SelHandle(self.moldata_name)
    pars = self.getParams()
    #pars['select'] = 'nmr_models'
    rv = selHnd.setSelParams(pars)
    
    #print 'nmrModelsGui getSelHandle rv',rv

    return selHnd


  
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#----------------------------------------------------------------------
class ModelInfoTree(QtGui.QTreeWidget):
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#----------------------------------------------------------------------

#----------------------------------------------------------------------
  def __init__(self,info='',sets=['generic'],parent=None):
#----------------------------------------------------------------------
    QtGui.QTreeWidget.__init__(self,parent)
    self.headerItem().setHidden(1)
    self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
    self.info = info
    self.sets = sets


#----------------------------------------------------------------------
  def populate(self):
#----------------------------------------------------------------------
    root = self.invisibleRootItem()
    status = {}
    if root and self.invisibleRootItem().childCount():
      for i in range(0,self.invisibleRootItem().childCount()):
        item = root.child(i)
        status[str(item.text(0))] = item.isExpanded()
    #print "populate status",status
    self.clear()
    for set in self.sets:
      top =  QtGui.QTreeWidgetItem ( [set] )
      if set == 'generic':    
        top.setText(0,'All models')
      else:
        top.setText(0,set)
      top.setChildIndicatorPolicy(QtGui.QTreeWidgetItem.ShowIndicator)
      #print "ModelInfoTree.populate top",set
      self.addTopLevelItem(top)
      retval,defn = MODELINFO().get_info(set = [set],info=self.info)
      #print "ModelInfoTree.loadSchemes",self.info,set,retval,defn
      if not retval:
        #print "ModelInfoTree.populate keys",defn.keys()
        item_list = defn.keys()
        item_list.sort()
        for item in item_list:
            line = QtGui.QTreeWidgetItem ([item] )
            line.setText(0,item)
            top.addChild(line)
      if status.has_key(top):
        top.setExpanded(status[top])
      else:
        top.setExpanded(1)       

#----------------------------------------------------------------------
  def selectedItem(self):
#----------------------------------------------------------------------
      item = self.currentItem()
      if not item or not item.parent(): return '',''
      #print "get colour_scheme", str(item.text(0)),  str(item.parent().text(0))
      parent = str(item.parent().text(0))
      if parent == 'All models':
        return 'generic',str(item.text(0))
      else:
        return  parent,str(item.text(0))

#----------------------------------------------------------------------
#----------------------------------------------------------------------
#----------------------------------------------------------------------
class ModelInfoSave(QtGui.QDialog):
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#----------------------------------------------------------------------
  DEFAULT_SAVE_GENERIC = 0
#----------------------------------------------------------------------
  def __init__(self,parent=None,info='',sets=['generic'],label='scheme'):
#----------------------------------------------------------------------
      QtGui.QDialog.__init__(self,parent)
      self.info = info
      self.sets = sets
      layout = QtGui.QVBoxLayout()
      line_layout = QtGui.QHBoxLayout()
      widget = QtGui.QLabel('Save '+label+' for',self)
      line_layout.addWidget(widget)
      self.save_to =  QtGui.QComboBox(self)
      generic_item = -1
      for item in sets:
        if item == 'generic':
          self.save_to.addItem('All models')
          generic_item = self.save_to.count()-1
        else:
          self.save_to.addItem(data(item).name_label)
      if ModelInfoSave.DEFAULT_SAVE_GENERIC and generic_item>=0:
        self.save_to.setCurrentIndex(generic_item)
        
      self.save_to.setToolTip('Save the colour scheme to be used by one model or all models?')
      line_layout.addWidget(self.save_to)
      layout.addLayout(line_layout)

      line_layout = QtGui.QHBoxLayout()
      widget = QtGui.QLabel(label+' name',self)
      line_layout.addWidget(widget)
      self.save_label =  QtGui.QComboBox(self)
      self.save_label.setEditable(1)
      line_layout.addWidget(self.save_label)
      layout.addLayout(line_layout)

      line_layout = QtGui.QHBoxLayout()
      line_layout.addStretch(5)
      widget =  QtGui.QPushButton('Save',self)
      line_layout.addWidget(widget)
      self.connect(widget,QtCore.SIGNAL('released()'),self.save)
      layout.addLayout(line_layout)

      self.setLayout(layout)
      
      self.populate()
      self.save_label.setCurrentIndex(0)
      self.show()

#----------------------------------------------------------------------
  def populate(self):
#----------------------------------------------------------------------   
    self.save_label.clear()
    self.save_label.addItem('')
    keys = []
    for item in self.sets:
      if item == 'generic':
        retval,defn = MODELINFO().get_info(set ='generic',info=self.info)
      else:
        retval,defn = MODELINFO().get_info(set =data(item).name_label,info=self.info)
      if not retval: keys.extend(defn.keys())

    for item in keys:
      self.save_label.addItem(item)

#----------------------------------------------------------------------   
  def save(self):
#----------------------------------------------------------------------
    if str(self.save_to.currentText()) == 'All models':
      ModelInfoSave.DEFAULT_SAVE_GENERIC = 1
    else:
      ModelInfoSave.DEFAULT_SAVE_GENERIC = 0
    self.emit(QtCore.SIGNAL('save'))

#----------------------------------------------------------------------   
  def selectedItem(self):
#----------------------------------------------------------------------   
    save_to = str(self.save_to.currentText())
    save_label = str(self.save_label.currentText())
    if save_to == 'All models': save_to = 'generic'
    #print "ModelInfoSave.selectedItem",save_to,save_label
    return save_to,save_label

#----------------------------------------------------------------------   
#----------------------------------------------------------------------   
#----------------------------------------------------------------------   
class ModelInfoDelete(QtGui.QDialog):
#----------------------------------------------------------------------   
#----------------------------------------------------------------------   
#----------------------------------------------------------------------   

#----------------------------------------------------------------------   
  def __init__(self,parent,set='',label='',info=''):
#----------------------------------------------------------------------   
    QtGui.QDialog.__init__(self,parent)
    self.set = set
    self.label = label
    self.info = info
    self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    layout = QtGui.QVBoxLayout()
    widget = QtGui.QLabel('Remove labelled selection: '+label,self)
    layout.addWidget(widget)
    widget = QtGui.QDialogButtonBox(self)
    widget.addButton(QtGui.QDialogButtonBox.Ok)
    widget.addButton(QtGui.QDialogButtonBox.Cancel)
    layout.addWidget(widget)
    self.connect(widget,QtCore.SIGNAL('accepted()'),self.delete)
    self.connect(widget,QtCore.SIGNAL('rejected()'),self.close)
    
    self.setLayout(layout)      
    self.show()

#----------------------------------------------------------------------   
  def delete(self):
#----------------------------------------------------------------------   
    MODELINFO().delete_info(set=[self.set],info=self.info,
                                key=self.label)
    self.emit(QtCore.SIGNAL('deleted'))
    self.close()

#----------------------------------------------------------------------   
#----------------------------------------------------------------------   
#----------------------------------------------------------------------   
class cidGui(QtGui.QDialog):
#----------------------------------------------------------------------   
#----------------------------------------------------------------------   
#----------------------------------------------------------------------   

  def __init__(self,parent=None,cid = ''):
    QtGui.QDialog.__init__(self,parent)
    #self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    layout = QtGui.QVBoxLayout()
    self.message = QtGui.QLabel(self)
    layout.addWidget(self.message)
    
    self.cidWidget = QtGui.QTextEdit(self)
    layout.addWidget(self.cidWidget)
  
    widget = QtGui.QDialogButtonBox(self)
    button = widget.addButton(QtGui.QDialogButtonBox.Apply)
    self.connect(button,QtCore.SIGNAL('clicked()'),guiUtils.partial(self.emit,QtCore.SIGNAL('apply')))
    button = widget.addButton(QtGui.QDialogButtonBox.Close)
    self.connect(button,QtCore.SIGNAL('clicked()'),self.close)
    '''
    button = widget.addButton('Revert selection',QtGui.QDialogButtonBox.ResetRole)
    self.connect(button,QtCore.SIGNAL('clicked()'),guiUtils.partial(self.emit,QtCore.SIGNAL('revert')))
    '''
    layout.addWidget(widget)
    
    self.setLayout(layout)
    self.setCid(cid)
    self.show()

  def setMessage(self,text=''):
    self.message.setText(text)
    
  def setCid(self,text=''):
    self.cidWidget.setText(text)

