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

     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 sys
import copy
import MGSimpleDialog, mgWidgets, guiUtils
from global_definitions import *


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

  def __init__(self,parent):

    MGSimpleDialog.MGSimpleDialog.__init__(self,parent)
    self.setWindowTitle('Superpose models')
    margin = 0    
    layout = QtGui.QVBoxLayout()
    if sys.platform == "darwin":
      layout.setContentsMargins(margin,margin,margin,margin)
      layout.setSpacing(margin)
    self.scrollarea = QtGui.QScrollArea(self)
    layout.addWidget(self.scrollarea)
    self.superpose_gui = superposeGui(self)
    self.scrollarea.setWidget(self.superpose_gui)
    self.scrollarea.setWidgetResizable(1) 
    self.scrollarea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

    # Button box
    button_box = QtGui.QDialogButtonBox(self)
    button_box.setOrientation(QtCore.Qt.Horizontal)
    for name,label,role,slot in [['superpose','Superpose',QtGui.QDialogButtonBox.ActionRole,self.superpose_gui.apply],
                 ['undo','Undo',QtGui.QDialogButtonBox.ActionRole,self.superpose_gui.undo],
                 ['export','Export matches',QtGui.QDialogButtonBox.ActionRole,self.superpose_gui.openExport],
                 ['list','List results',QtGui.QDialogButtonBox.ActionRole,self.superpose_gui.listResults],
                 ['showaxis','Show axes',QtGui.QDialogButtonBox.ActionRole,self.superpose_gui.showAxes],
                 ['save','Save all data files',QtGui.QDialogButtonBox.ActionRole,self.superpose_gui.saveFiles],
                 ['close','Close',QtGui.QDialogButtonBox.RejectRole,self.Close],
                 ['help','Help',QtGui.QDialogButtonBox.HelpRole,self.superpose_gui.help]]:
      button = button_box.addButton(label,role)
      button.setObjectName(name)
      button.setAutoDefault(0)
      self.connect(button,QtCore.SIGNAL('clicked()'),slot)
      setattr(self,name,button)
    if sys.platform == "darwin":
      bmargin = 10
      blayout = QtGui.QVBoxLayout()
      blayout.addWidget(button_box)
      blayout.setContentsMargins(bmargin,bmargin,bmargin,bmargin)
      blayout.setSpacing(bmargin)
      layout.addLayout(blayout)
    else:
      layout.addWidget(button_box)
    self.connect(self.superpose_gui,QtCore.SIGNAL('enableSave'),self.enableSave)

    
    self.setLayout(layout)
    self.setMinimumSize(self.superpose_gui.width()+self.scrollarea.verticalScrollBar().height(),400)
    self.UnClose()
    self.CreateMenuEntry()
    self.enableSave()
    
  def Close(self):
    self.superpose_gui.Close()
    MGSimpleDialog.MGSimpleDialog.Close(self)

  def UnClose(self):
    self.superpose_gui.UnClose()
    MGSimpleDialog.MGSimpleDialog.UnClose(self)

#-------------------------------------------------------------------------
  def enableSave(self):
#-------------------------------------------------------------------------
    for model in Appl('Superpose').supModel.keys():
      molobj = data(model)
      if molobj and  molobj.molHnd.GetIsTransformed():
        self.save.setEnabled(1)
        self.undo.setEnabled(1)
        self.showaxis.setEnabled(1)
        return
    self.save.setEnabled(0)
    self.undo.setEnabled(0)
    self.showaxis.setEnabled(0)

  
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
class superposeGui(QtGui.QWidget):
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
  show_menu =  [ 'No show']
  show_alias = [ 'noshow' ]

  methods_menu = [ ['ssm', 'Gesamt/SSM', 'Automatic match and superpose fragments/secondary structure elements'],
                #  ['lsq', 'Selected residues', 'Superpose selected residues in two models'],
                  ['close', 'Match close residues', 'Match and superpose residues close to those selected in the fixed model'],
                  ['interactive', 'User defined matches', 'Select matching atom, monomers,residues or ranges of residues']]

  def __init__(self,parent):
    QtGui.QWidget.__init__(self,parent)
    #print 'superposeGui.__init__ parent',parent
    self.block_showMatch = 0
    self.block_update = 0
    self.model_list = []
    self.multiSaveWidget = None
    frame_margin = 3
    layout = QtGui.QGridLayout()


    
    frame = QtGui.QGroupBox('Superpose method',self)
    frame_layout = QtGui.QHBoxLayout()
    self.method_group = QtGui.QButtonGroup(self)
    for item in superposeGui.methods_menu:
      widget = QtGui.QRadioButton(item[1],self)
      widget.setObjectName(item[0])
      widget.setToolTip(item[2])
      self.method_group.addButton(widget)
      frame_layout.addWidget(widget)
    frame.setLayout(frame_layout)
    layout.addWidget(frame,0,0,1,2)
    self.connect(self.method_group,QtCore.SIGNAL("buttonClicked(int)"),guiUtils.partial(self.update,'method'))

    frame =  QtGui.QGroupBox('Fixed and moving models',self)
    frame_layout =  QtGui.QVBoxLayout()
    if sys.platform == "darwin": frame_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)
    if sys.platform == "darwin": frame_layout.setSpacing(frame_margin)
    for name,label,tip in [ ['fixed','Fixed model','Fixed model - matches and atom selections shown for this model'],
                            ['show_equiv_mol','Highlighted model','The matches and selected atoms are displayed for this moving model' ]]:
      line = QtGui.QHBoxLayout()
      setattr(self,name+'_label',QtGui.QLabel(label))
      line.addWidget(getattr(self,name+'_label'))
      widget =  mgWidgets.mgDataObjCombo(parent=self,object_type='MolData')
      widget.setObjectName(name)
      widget.setToolTip(tip)
      widget.setCurrentDataObj(getattr(Appl('Superpose'),name,''))
      line.addWidget(widget)
      self.connect(widget,QtCore.SIGNAL("currentIndexChanged(int)"),guiUtils.partial(self.update,name))
      #line.addStretch()
      frame_layout.addLayout(line)
    # Exclude the fixed model from the show_equiv_mol combobox
    widget.setExcludeDataObjList([getattr(Appl('Superpose'),'fixed','')])
    frame.setLayout(frame_layout)
    layout.addWidget(frame,1,0)
    
    # Appearance of matches
    frame =  QtGui.QGroupBox('Display of matches',self)
    frame_layout =  QtGui.QVBoxLayout()
    if sys.platform == "darwin": frame_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)
    if sys.platform == "darwin": frame_layout.setSpacing(frame_margin)
    line =  QtGui.QHBoxLayout()
    widget = QtGui.QCheckBox("Show matches with ",self)
    widget.setObjectName('show_equivalents')
    widget.setToolTip('Dashed lines between matched atoms of the fixed and one selected moving model')
    self.connect(widget,QtCore.SIGNAL("stateChanged(int)"),guiUtils.partial(self.update,'show_equivalents'))
    line.addWidget(widget)
    widget = QtGui.QCheckBox("distance labels",self)
    self.connect(widget,QtCore.SIGNAL("stateChanged(int)"),guiUtils.partial(self.update,'show_distances'))
    widget.setObjectName('show_distances')
    widget.setToolTip('Show inter-atomic distance for matched atoms')
    line.addWidget(widget)
    widget = mgWidgets.mgColourCombo(self)
    widget.setObjectName('conn_colour')
    self.connect(widget,QtCore.SIGNAL("currentIndexChanged(int)"),guiUtils.partial(self.update,'conn_colour'))
    line.addWidget(widget)
    frame_layout.addLayout(line)
    
    line =  QtGui.QHBoxLayout()
    widget = QtGui.QCheckBox("Highlight selected atoms",self)
    widget.setToolTip('If limited set of atoms selected highlight them with pyramids')
    widget.setObjectName('show_mask')
    self.connect(widget,QtCore.SIGNAL("stateChanged(int)"),guiUtils.partial(self.update,'show_mask'))
    line.addWidget(widget)
    for item in ['fixed_mask_colour','moving_mask_colour']:
      widget = mgWidgets.mgColourCombo(self)
      widget.setObjectName(item)
      line.addWidget(widget)
      self.connect(widget,QtCore.SIGNAL("currentIndexChanged(int)"),guiUtils.partial(self.update,item))
      
    frame_layout.addLayout(line)
    
    frame.setLayout(frame_layout)
    layout.addWidget(frame,1,1)
    

    self.ssm_frame = QtGui.QGroupBox('Options',self)
    frame_layout =  QtGui.QVBoxLayout()
    if sys.platform == "darwin": frame_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)
    if sys.platform == "darwin": frame_layout.setSpacing(frame_margin)
    line = QtGui.QHBoxLayout()
    self.ssm_gesamt_combo = QtGui.QComboBox()
    line.addWidget(QtGui.QLabel('Method:',self))
    self.ssm_gesamt_combo.addItems(["SSM","Gesamt"])
    self.connect(self.ssm_gesamt_combo,QtCore.SIGNAL("currentIndexChanged(const QString&)"),guiUtils.partial(self.update,'submethod'))
    line.addWidget(self.ssm_gesamt_combo)
    line.addStretch(5)
    frame_layout.addLayout(line) 
    frame_layout.addStretch(5)
    self.ssm_frame.setLayout(frame_layout)
    self.ssm_frame.hide()
    
    self.interactive_frame = QtGui.QGroupBox('User defined matches options',self)
    frame_layout =  QtGui.QVBoxLayout()
    if sys.platform == "darwin": frame_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)
    if sys.platform == "darwin": frame_layout.setSpacing(frame_margin)
    line = QtGui.QHBoxLayout()
    line.addWidget(QtGui.QLabel('Apply superpose to',self))
    self.apply_interactive_all = QtGui.QButtonGroup(self)
    for ii,item in  [[0,'the moving model'],[1,'all active models']]:
      widget = QtGui.QRadioButton(item,self)
      self.apply_interactive_all.addButton(widget,ii)
      line.addWidget(widget)
    self.connect(self.apply_interactive_all,QtCore.SIGNAL('buttonClicked(int)'),guiUtils.partial(self.update,'apply_interactive_all'))
    line.addStretch(5)
    frame_layout.addLayout(line)
    line = QtGui.QHBoxLayout()
    line.addWidget(QtGui.QLabel('For selected residues and ranges match',self))
    frame_layout.addLayout(line)
    widget = QtGui.QComboBox(self)
    widget.setObjectName('selected_atoms_mode')
    self.connect(widget,QtCore.SIGNAL('currentIndexChanged(int)'),guiUtils.partial(self.update,'selected_atoms_mode'))
    import Superpose
    for item in Superpose.Superpose.selected_atoms_mode_menu:
      widget.addItem(item)
    line = QtGui.QHBoxLayout()
    line.addWidget(widget)
    widget = QtGui.QLineEdit(self)
    widget.setObjectName('selected_atoms_selection')
    self.connect(widget,QtCore.SIGNAL('editingFinished()'),guiUtils.partial(self.update,'selected_atoms_selection'))
    line.addWidget(widget)
    line.addWidget(QtGui.QLabel('atoms',self))
    line.addStretch(5)
    frame_layout.addLayout(line)
    frame_layout.addStretch(5)
    self.interactive_frame.setLayout(frame_layout)
    self.interactive_frame.hide()


    self.close_residues_frame =  QtGui.QGroupBox('Close residues options',self)
    frame_layout =  QtGui.QVBoxLayout()
    if sys.platform == "darwin": frame_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)
    if sys.platform == "darwin": frame_layout.setSpacing(frame_margin)
    line = QtGui.QHBoxLayout()
    line.addWidget(QtGui.QLabel('Close atoms must have same name and ..',self))
    frame_layout.addLayout(line)
    line = QtGui.QHBoxLayout()
    line.addWidget(QtGui.QLabel('Residue max inter',self))
    widget = QtGui.QLineEdit(self)
    widget.setObjectName('close_atoms_central_atom')
    widget.setMaxLength(4)
    line.addWidget(widget)
    self.connect(widget,QtCore.SIGNAL('editingFinished()'),guiUtils.partial(self.update,'close_atoms_central_atom'))
    line.addWidget(QtGui.QLabel('distance',self))
    widget =  QtGui.QDoubleSpinBox(self)
    widget.setObjectName('close_atoms_res_cutoff')
    widget.setRange(0.5,10.0)
    widget.setSingleStep(0.5)
    self.connect(widget,QtCore.SIGNAL('valueChanged(double)'),guiUtils.partial(self.update,'close_atoms_res_cutoff'))
    line.addWidget(widget)
    line.addWidget(QtGui.QLabel('Max interatomic distance',self))
    widget =  QtGui.QDoubleSpinBox(self)
    widget.setObjectName('close_atoms_cutoff')
    self.connect(widget,QtCore.SIGNAL('valueChanged(double)'),guiUtils.partial(self.update,'close_atoms_cutoff'))
    widget.setRange(0.5,10.0)
    widget.setSingleStep(0.5)
    line.addWidget(widget)
    line.addStretch(5)
    frame_layout.addLayout(line)
    self.close_residues_frame.setLayout(frame_layout)
    self.close_residues_frame.hide()
    
    # Draw the model frame to list the models
    self.model_frame = QtGui.QGroupBox('Models to superpose',self)
    model_layout = QtGui.QGridLayout (self.model_frame)
    if sys.platform == "darwin": model_layout.setSpacing(frame_margin)
    if sys.platform == "darwin": model_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)

    self.model_frame_label = {}
    for item,label in modelForSuperpose.label.items():
      self.model_frame_label[item] = QtGui.QLabel(label,self)
      self.model_frame_label[item].setToolTip(modelForSuperpose.tooltips[item])
    self.model_frame.setLayout(model_layout)
    self.model_frame.hide()
        
    #self.fixed_group = QtGui.QButtonGroup(self)
    #self.moving_group = QtGui.QButtonGroup(self)
    
    # Interactive selection frame
    self.interactive_selection_frame =  QtGui.QGroupBox('User defined matches',self)
    inter_layout =  QtGui.QGridLayout ()
    if sys.platform == "darwin": inter_layout.setContentsMargins(frame_margin,frame_margin,frame_margin,frame_margin)
    if sys.platform == "darwin": inter_layout.setSpacing(frame_margin)
    self.interactive_selection_frame.setLayout(inter_layout)
    self.editMatchesFrame = None
    #self.drawEditMatchesFrame()
    self.interactive_selection_frame.hide()
    
    self.setLayout(layout)

    Appl('Superpose').initiallise_status()
    self.findChild(QtGui.QRadioButton,Appl('Superpose').method).setChecked(1)

    self.connect(DISPLAYTABLE(),QtCore.SIGNAL('addDataObj'),self.handleChangedModels)
    self.connect(DISPLAYTABLE(),QtCore.SIGNAL('deleteDataObj'),self.handleChangedModels)
    self.connect(DISPLAYTABLE(),QtCore.SIGNAL('loadAllDataObj'),self.handleChangedModels)
    self.connect(DISPLAYTABLE(),QtCore.SIGNAL('update'),self.handleChangedModels)


#-------------------------------------------------------------------------
  def handleChangedModels(self):
#-------------------------------------------------------------------------
    self.loadModelFrame()
    for item in ['fixed','show_equiv_mol']:
      widget = self.findChild(mgWidgets.mgDataObjCombo,item)
      if widget:
        # This mgDataObjCombo should get updated independently but we need to
        # be sure that it is already done
        widget.resetMenu()
        mol = getattr(Appl('Superpose'),item)
        #print 'superposeGui.handleChangedModels',item,mol
        if mol: widget.setCurrentDataObj(mol)

    Appl('Superpose').set_default_fixed()
    self.update('show_equivalents')
    self.update('show_distances')
    self.findChild(mgWidgets.mgDataObjCombo,item).setExcludeDataObjList([getattr(Appl('Superpose'),'fixed','')])
    self.drawEditMatchesFrame()
    # Force redraw of model_frame because of select all with chain .. combo.
    method = str(self.method_group.checkedButton().objectName())
    self.handleChangedMethod(method)

    dataobjs = get_dataobj(object_type='MolData')
    firstChains = None
    allChains = []
    for o in dataobjs:
          if hasattr(o,"chains") and firstChains == None:
            firstChains = copy.deepcopy(o.chains)
            allChains = copy.deepcopy(o.chains)
          if hasattr(o,"chains") and firstChains != None:
            for ch in allChains[:]:
              if not ch in o.chains:
                 allChains.remove(ch)
    allChains.insert(0,"")
    self.selectAllChainCombo.clear()
    self.selectAllChainCombo.addItems(allChains)

#-------------------------------------------------------------------------
  def selectChainInAllModels(self,chain):
#-------------------------------------------------------------------------
    row = 0
    for model in self.model_list:
        row = row + 1
        widget = self.model_frame.findChild(modelForSuperpose,'superpose'+model)
        if widget:
          if hasattr(widget,"selection"):
            if hasattr(widget.selection,"setText"):
              if chain == "":
                widget.selection.setText(chain)
              else:
                widget.selection.setText(chain+"/")

#-------------------------------------------------------------------------
  def handleChangedMethod(self,method):
#-------------------------------------------------------------------------
    
    if method == 'close':
      columns = modelForSuperpose.close_columns
    else:
      columns = modelForSuperpose.columns
 
    row = 0
    # Set the model frame column titles
    #print 'handleChangedMethod',self.model_frame_label.keys()
    for item,widget in self.model_frame_label.items():
      col = columns.get(item,-1)
      if col>=0:
        widget.setVisible(1)
        self.model_frame.layout().addWidget(widget,row,col)
      else:
        widget.setVisible(0)
    
    # Show appropriate columns for each model
    for model in self.model_list:
        row = row + 1
        widget = self.model_frame.findChild(modelForSuperpose,'superpose'+model)
        if widget: widget.layoutWidgets(row=row,columns=columns)

    if not hasattr(self,"selectAllChainWidget"):
        self.selectAllChainWidget = QtGui.QWidget()
        selectAllChainLayout = QtGui.QHBoxLayout()
        self.selectAllChainWidget.setLayout(selectAllChainLayout)
        selectAllChainLabel1 = QtGui.QLabel("(or select chain ")
        selectAllChainLabel2 = QtGui.QLabel(" in all objects)")
        self.selectAllChainCombo = QtGui.QComboBox()
        dataobjs = get_dataobj(object_type='MolData')
        firstChains = None
        allChains = []
        for o in dataobjs:
          if hasattr(o,"chains") and firstChains == None:
            firstChains = copy.deepcopy(o.chains)
            allChains = copy.deepcopy(o.chains)
          if hasattr(o,"chains") and firstChains != None:
            for ch in allChains[:]:
              if not ch in o.chains:
                 allChains.remove(ch)
        allChains.insert(0,"")
        self.selectAllChainCombo.clear()
        self.selectAllChainCombo.addItems(allChains)
        selectAllChainLayout.addWidget(selectAllChainLabel1)
        selectAllChainLayout.addWidget(self.selectAllChainCombo)
        selectAllChainLayout.addWidget(selectAllChainLabel2)
        spacer = QtGui.QSpacerItem(200,5)
        selectAllChainLayout.addItem(spacer)
        self.connect(self.selectAllChainCombo,QtCore.SIGNAL("currentIndexChanged(const QString&)"),self.selectChainInAllModels)

    if method == 'ssm' or method == 'close':
      self.model_frame.layout().addWidget(self.selectAllChainWidget,row+1,2)

    if method == 'interactive' and (not self.editMatchesFrame):
      self.drawEditMatchesFrame()
  

    for mode,frame in [ [ ['ssm','close'], self.model_frame],
                         [ ['interactive'], self.interactive_selection_frame ]]:
      idx = self.layout().indexOf(frame)
      if mode.count(method):
        if idx<0:
          frame.show()
          self.layout().addWidget(frame,2,0,1,2)
      else:    
        if idx>=0:
          frame.hide()
          self.layout().removeWidget(frame)


    # Toggle options frames
    for mode,frame in  [ [ 'ssm', self.ssm_frame],
                        # ['lsq',self.selected_residues_frame],
                         ['close',self.close_residues_frame],
                         ['interactive', self.interactive_frame ]] :
      idx = self.layout().indexOf(frame)
      if method == mode:
        if idx<0:
          frame.show()
          self.layout().addWidget(frame,3,0,1,2)
      else:    
        if idx>=0:
          frame.hide()
          self.layout().removeWidget(frame)

    show_equiv_mol_label_text = { 'ssm' : 'Highlighted model',
                          'close' : 'Highlighted model',
                          'interactive' : 'Moving model' }
    
    self.show_equiv_mol_label.setText(show_equiv_mol_label_text[mode])

    '''
    if method == 'interactive':
      moving_mol = Appl('Superpose').show_equiv_mol
      widget = self.model_frame.findChild(modelForSuperpose,'superpose'+moving_mol)
      if widget:
        widget.moving.setChecked(1)
    else:
      widget = self.moving_group.checkedButton()
      #print 'superposeGui.handleChangedMethod moving_group',widget
      if widget:
        model = str(widget.parent().objectName())[9:]
        #print 'superposeGui.handleChangedMethod moving_group',model
        self.findChild(mgWidgets.mgDataObjCombo,'show_equiv_mol').setCurrentDataObj(model)
    '''
      
    self.redraw()

    
#-------------------------------------------------------------------------
  def Close(self):
#-------------------------------------------------------------------------
    #print 'superposeGui.Close'
    self.disconnect(DISPLAYTABLE(),QtCore.SIGNAL("DisplayTableChanged"),self.loadModelFrame)
    self.disconnect(MAINWINDOW(),QtCore.SIGNAL('atomContextMenu'),self.handleAtomPick)
    Appl('Superpose').close()
    import rebuild
    rebuild.UpdateDisplay(auto_save=0)

    self.hide()
    

#-------------------------------------------------------------------------
  def UnClose(self):
#-------------------------------------------------------------------------
    #print 'superposeGui.UnClose'
    self.loadModelFrame()
    self.initialiseParams()
    self.connect(DISPLAYTABLE(),QtCore.SIGNAL("DisplayTableChanged"),self.loadModelFrame)
    self.connect(MAINWINDOW(),QtCore.SIGNAL('atomContextMenu'),self.handleAtomPick)
    self.handleChangedMethod(Appl('Superpose').method)
    Appl('Superpose').unclose()
    import rebuild
    rebuild.UpdateDisplay(auto_save=0)
    self.show()
    
#-------------------------------------------------------------------------
  def help(self):
#-------------------------------------------------------------------------
    HELPBROWSER().loadMgHelp('superpose.html')


#-------------------------------------------------------------------------
  def loadModelFrame(self):
#-------------------------------------------------------------------------
    '''
    Load models from Appl('Superpose') into the model frame
    '''

    new_model_list = []
    for item in get_dataobj(object_type='MolData'):
      new_model_list.append(item.name)

    #Are there any loaded models that should be deleted?
    del_list = []
    for model in self.model_list:
      if not new_model_list.count(model): del_list.append(model)
    #print "superposeGui.loadModelFrame del_list",del_list
    for model in del_list:
      Appl('Superpose').handle_delete_MolData(model)
      widget = self.findChild(modelForSuperpose,'superpose'+model)
      if widget:
        widget.delete()
      self.model_list.remove(model)

    row = self.model_frame.layout().rowCount() - 1
    # Load any new models
    
    for model in new_model_list:
      if not self.model_list.count(model):
        rv = Appl('Superpose').add_MolData(model)
        if not rv:
          row = row+1
          widget = modelForSuperpose(self.model_frame,name=model,
                    layout = self.model_frame.layout(),row=row)
          self.connect(widget.match,QtCore.SIGNAL('currentIndexChanged(int)'),guiUtils.partial(self.showMatch,model))
          #self.connect(widget.on,QtCore.SIGNAL('stateChanged(int)'),guiUtils.partial(self.checkActiveModels,model))
          #print "superposeGui.loadModelFrame",model,row,widget
          self.model_list.append(model)
     
    
#-------------------------------------------------------------------------
  def initialiseParams(self):
#-------------------------------------------------------------------------
    #Set the method

    self.block_update = 1
    
    widget = self.findChild(QtGui.QRadioButton,Appl('Superpose').method)
    if widget: widget.setChecked(1)
    
    for item in ['show_equivalents','show_distances','show_mask']:
      widget = self.findChild(QtGui.QCheckBox,item)
      if widget:
        widget.setChecked(getattr(Appl('Superpose'),item))

    for item in ['conn_colour','fixed_mask_colour','moving_mask_colour']:
      widget = self.findChild(mgWidgets.mgColourCombo,item)
      if widget:
        colour = getattr(Appl('Superpose'),item)
        if colour: widget.set_colour(colour)
        
    for item in ['fixed','show_equiv_mol']:
      widget = self.findChild(mgWidgets.mgDataObjCombo,item)
      if widget:
        mol = getattr(Appl('Superpose'),item)
        if mol: widget.setCurrentDataObj(mol)

    for item in ['close_atoms_res_cutoff','close_atoms_cutoff']:
      widget = self.findChild(QtGui.QDoubleSpinBox,item)
      if widget: widget.setValue(getattr(Appl('Superpose'),item))
    for item in [ 'close_atoms_central_atom']:
      widget = self.findChild(QtGui.QLineEdit,item)
      if widget: widget.setText(getattr(Appl('Superpose'),item))
      
    widget = self.findChild(QtGui.QComboBox,'selected_atoms_mode')
    if widget: widget.setCurrentIndex(Appl('Superpose').selected_atoms_mode_alias.index(Appl('Superpose').selected_atoms_mode))

    widget = self.findChild(QtGui.QLineEdit,'selected_atoms_selection')
    if widget:
      widget.setText(Appl('Superpose').get_user_selected_atoms())
      if Appl('Superpose').selected_atoms_mode == 'user':
        widget.show()
      else:
        widget.hide()

    
    self.apply_interactive_all.button(0).setChecked(1-Appl('Superpose').apply_interactive_all)
    self.apply_interactive_all.button(1).setChecked(Appl('Superpose').apply_interactive_all)

    for model_name in self.model_list:
      widget = self.findChild(modelForSuperpose,'superpose'+model_name)
      if widget:
        params = Appl('Superpose').supModel[model_name].getparams()
        widget.setParams(params)

    self.block_update = 0
    
#-------------------------------------------------------------------------
  def getModelRow(self,model):
#-------------------------------------------------------------------------
    if self.model_list.count(model):
      return  self.model_list.index(model) + 1
    else:
      return -1


#-------------------------------------------------------------------------
  def update(self,mode=''):
#-------------------------------------------------------------------------
    #print 'superposeGui.update',mode
    if self.block_update: return
    redraw = 0
    params = {}
    if mode == 'method':
      new_method = str(self.method_group.checkedButton().objectName())
      old_method =  Appl('Superpose').method
      Appl('Superpose').setparams(method=new_method)

      self.handleChangedMethod(new_method)

    elif ['conn_colour','fixed_mask_colour','moving_mask_colour'].count(mode):
      widget =  self.findChild(mgWidgets.mgColourCombo,mode)
      if not widget: return
      colour = widget.get_colour()
      Appl('Superpose').set_colour(mode=mode,colour=colour)
      redraw = 1

    elif ['fixed','show_equiv_mol'].count(mode):
      widget = self.findChild(mgWidgets.mgDataObjCombo,mode)
      if not widget: return
      model_name = widget.getCurrentDataObj().name
      if mode == 'fixed':
        Appl('Superpose').set_fixed(model_name)
        widget = self.findChild(mgWidgets.mgDataObjCombo,'show_equiv_mol')
        if widget:
          widget.setExcludeDataObjList([getattr(Appl('Superpose'),'fixed','')])
          mol = getattr(Appl('Superpose'),'show_equiv_mol')
          if mol: widget.setCurrentDataObj(mol)

      else:
        Appl('Superpose').set_show_equiv_mol(model_name)


      # Redraw the editMatchesFrame
      self.drawEditMatchesFrame()


      redraw = 1
    elif mode == 'show_equivalents':
      widget = self.findChild(QtGui.QCheckBox,mode)
      if not widget: return
      Appl('Superpose').set_show_equivalents(int(widget.isChecked()))
      redraw = 1
    elif mode == 'show_mask':
      widget = self.findChild(QtGui.QCheckBox,mode)
      if not widget: return
      Appl('Superpose').set_show_mask(int(widget.isChecked()))
      redraw = 1
    elif ['close_atoms_res_cutoff','close_atoms_cutoff'].count(mode):
      widget = self.findChild(QtGui.QDoubleSpinBox,mode)
      if not widget: return
      params[mode] =  float(widget.value())
    elif ['close_atoms_central_atom'].count(mode):
      widget = self.findChild(QtGui.QLineEdit,mode)
      if not widget: return
      params[mode] =  str(widget.text())
    elif mode == 'selected_atoms_mode':
       widget = self.findChild(QtGui.QComboBox,mode)
       if not widget: return
       params[mode] = Appl('Superpose').selected_atoms_mode_alias[int(widget.currentIndex())]
       select_widget = self.findChild(QtGui.QLineEdit,'selected_atoms_selection')
       if select_widget:
         if params[mode]=='user':
           select_widget.show()
         else:
           select_widget.hide()
    elif  mode == 'selected_atoms_selection':
      widget = self.findChild(QtGui.QLineEdit,'selected_atoms_selection')
      params[mode] = str(widget.text())

    elif mode == 'apply_interactive_all':
      params['apply_interactive_all'] = int(self.apply_interactive_all.checkedId())

    elif mode == 'submethod':
      Appl('Superpose').setparams(submethod=str(self.ssm_gesamt_combo.currentText().toUtf8()).lower())
      for model in self.model_list:
        widget = self.findChild(modelForSuperpose,'superpose'+model)
        if hasattr(widget,"match"):
          if str(self.ssm_gesamt_combo.currentText().toUtf8()).lower() == "gesamt":
            widget.match.setEnabled(False)
          else:
            widget.match.setEnabled(True)

    if params: Appl('Superpose').setparams(params)
    
    if redraw: self.redraw()

    
#-------------------------------------------------------------------------
  def redraw(self):
#-------------------------------------------------------------------------
       import rebuild
       rebuild.UpdateDisplay(auto_save=0)

#-------------------------------------------------------------------------
  def drawEditMatchesFrame(self,matchID=-1):
#-------------------------------------------------------------------------
      #print 'drawEditMatchesFrame', Appl('Superpose').fixed, Appl('Superpose').show_equiv_mol
      if self.editMatchesFrame:
        self.editMatchesFrame.deleteLater()
        self.interactive_selection_frame.layout().removeWidget(self.editMatchesFrame)
        self.editMatchesFrame = None
      if Appl('Superpose').fixed and Appl('Superpose').show_equiv_mol:
        self.editMatchesFrame = editMatchesFrame(self,Appl('Superpose').fixed,Appl('Superpose').show_equiv_mol)
        self.interactive_selection_frame.layout().addWidget(self.editMatchesFrame)
        #self.connect(self.editMatchesFrame,QtCore.SIGNAL('matchesChanged'),self.redraw)
        #self.editMatchesFrame.loadSelectMatch()
        #self.editMatchesFrame.setMatchId(matchID)
 
#-------------------------------------------------------------------------
  def apply(self):
#-------------------------------------------------------------------------
    self.update()
    for widget in self.findChildren(modelForSuperpose):
       widget.handleSelection()
    mode = str(self.method_group.checkedButton().objectName())
    if mode == 'ssm': 
      multi_models= Appl('Superpose').checkForMultiModels()
      if multi_models:
        text = 'The following structures have atoms in more than one NMR/symmetry model selected.\n'
        for item in multi_models:
          text = text + item + '\n'
        text = text + 'Do you want to continue'
        retval = QtGui.QMessageBox.question(self,'Multiple NMR/symmetry models selected',text,
                             QtGui.QMessageBox.Yes|QtGui.QMessageBox.No,QtGui.QMessageBox.Yes)
        if retval == QtGui.QMessageBox.No: return
    rv = Appl('Superpose').apply()
    if not rv[0]:
      if mode == 'ssm':
        self.updateMatches()
      else:
        self.clearMatches()

      self.updateRMS()
      self.redraw()
      self.emit(QtCore.SIGNAL('enableSave'))
      self.update()
      self.handleChangedMethod(Appl('Superpose').method)
    elif rv[1]:
      QtGui.QMessageBox.warning(None,self.windowTitle(),'Superpose failed.\n'+rv[1])

#-------------------------------------------------------------------------
  def undo(self):
#-------------------------------------------------------------------------
    self.update()
    rv = Appl('Superpose').undo()

    self.emit(QtCore.SIGNAL('enableSave'))
    if not rv:
      import rebuild
      rebuild.UpdateDisplay(auto_save=0)

#-------------------------------------------------------------------------
  def showAxes(self):
#-------------------------------------------------------------------------
    import pygl_coord
    import mmdb2 as mmdb
    supData = Appl('Superpose').get_data()
    models = Appl('Superpose').getparams()['superposeModels']

    for d in supData:
       if hasattr(d,"has_key") and d.has_key('moving') and d.has_key('fixed') and d.has_key('matrix'):
         name = d['moving']+'_to_'+d['fixed']
         mat = d['matrix'].split()
         matvals = []
         for val in mat:
           matvals.append(float(val))
           m =  pygl_coord.matrix(4,4,matvals)
	
         axisPoint = pygl_coord.GetAxisAndPointFromMatrix(m)
         p1 = axisPoint.point()
         p2 = axisPoint.point() + axisPoint.axis()
         if models.has_key(d['fixed']) and models.has_key(d['moving']) and models[d['fixed']].has_key('selection') and models[d['moving']].has_key('selection'):
           if 1:#try:
             rv_fixed =  get_dataobj(name = models[d['fixed']]['MolData_name'])[0].parse_selection(defn=[None,models[d['fixed']]['selection']])
             rv_moving =  get_dataobj(name = models[d['moving']]['MolData_name'])[0].parse_selection(defn=[None,models[d['moving']]['selection']])
             if rv_fixed[0] == 0:
               selH_fixed = rv_fixed[1]
             else:
               selH_fixed = None
             if rv_moving[0] == 0:
               selH_moving = rv_moving[1]
             else:
               selH_moving = None
           else:#except:
               selH_fixed = None
               selH_moving = None
         else:
               selH_fixed = None
               selH_moving = None

         fixed_molHnd = data(d['fixed'])
         moving_molHnd = data(d['moving'])
         p3 = None
         if hasattr(fixed_molHnd,"molHnd"):
           if selH_fixed:
             rt = fixed_molHnd.molHnd.CentreOfMass(selH_fixed)
           else:
             fixed_selHnd = fixed_molHnd.molHnd.NewSelection()
             fixed_molHnd.molHnd.Select(fixed_selHnd,mmdb.STYPE_ATOM,0,'*', mmdb.ANY_RES,'*',mmdb.ANY_RES,'*','*',"CA","C",'*',mmdb.SKEY_NEW)
             rt = fixed_molHnd.molHnd.CentreOfMass(fixed_selHnd)
           rtd = mmdb.realtype_to_double(rt)
           p3 = pygl_coord.Cartesian(rtd)
         else:
           return
         if hasattr(moving_molHnd,"molHnd"):
           if selH_moving:
             rt = moving_molHnd.molHnd.CentreOfMass(selH_moving)
           else:
             moving_selHnd = moving_molHnd.molHnd.NewSelection()
             moving_molHnd.molHnd.Select(moving_selHnd,mmdb.STYPE_ATOM,0,'*', mmdb.ANY_RES,'*',mmdb.ANY_RES,'*','*',"CA","C",'*',mmdb.SKEY_NEW)
             rt = moving_molHnd.molHnd.CentreOfMass(moving_selHnd)
           rtd = mmdb.realtype_to_double(rt)
           p4 = pygl_coord.Cartesian(rtd)
         else:
           return

         if p3:
           import VisRotTrans
           vis = VisRotTrans.RotTransMatrixVisFromPointAndMatrix(m.Inverse(),p3)
           #vis = VisRotTrans.RotTransMatrixVisFromPointAndMatrix(m,p3)
           vis.draw()

         intersect = pygl_coord.DistanceBetweenTwoLines(p1,p2,p3,p4)
         begin = axisPoint.point() + axisPoint.axis()*(intersect[1]-30)
         end = axisPoint.point() + axisPoint.axis()*(intersect[1]+30)

         import time
         vectorText = """
#Definition of vectors for display with CCP4mg
"""
         vectorText += "#Created on "+time.asctime()
         vectorText += """

data_VECTORS


loop_
_tags.name
_tags.annotation
"""
         vectorText += '"'+name+'"  " "' 
         vectorText += """


"""
         vectorText += """
loop_
_vector.tag
_vector.start_x
_vector.start_y
_vector.start_z
_vector.end_x
_vector.end_y
_vector.end_z
_vector.label
"""
         vectorText += '"'+name+'" '+str(begin.get_x())+' '+str(begin.get_y())+' '+str(begin.get_z())+' '+str(end.get_x())+' '+str(end.get_y())+' '+str(end.get_z())+' ""\n' 
         fname = name+"_Superpose.vector"
         import mgWidgets
         directory = mgWidgets.MGFileDialog.last_directory
         import os
         if not directory:
            directory = os.environ["HOME"]
         fnameFull = os.path.join(directory,fname)

         if 0:
          try:
           f = open(fnameFull,"w")
           f.write(vectorText)
           f.close()
           import MGApplication
           mainwin = MGApplication.GetMainWindow()
           mainwin.openFile(fnameFull)
          except:
           print "Failed to write vector info:"
           print
           print vectorText
           print
           print "to file",fnameFull
           QtGui.QMessageBox.critical(None, "Failed to write vector file", "Failed to write vector info to file "+fnameFull, QtGui.QMessageBox.Ok )


#-------------------------------------------------------------------------
  def listResults(self):
#-------------------------------------------------------------------------
    rv = Appl('Superpose').list_data()
    #print "superposeGui.list_data",rv
    if rv:
      widget = FILEVIEWER().loadText(rv,'Superpose')
      if widget:
        widget.setFont(style='fixed_width')

   
#-------------------------------------------------------------------------
  def clearMatches(self):
#-------------------------------------------------------------------------
    #print 'clearMatches'
    self.block_showMatch = 1
    for model in self.model_list:
      widget = self.findChild(modelForSuperpose,'superpose'+model)
      widget.match.clear()
      widget.match.hide()
    self.block_showMatch = 0

#-------------------------------------------------------------------------
  def updateMatches(self):
#-------------------------------------------------------------------------
    self.block_showMatch = 1
    for model in self.model_list:
      widget = self.findChild(modelForSuperpose,'superpose'+model)
      widget.match.clear()
      params= Appl('Superpose').supModel[model].getmatchesinfo()
      #print 'updateMatches',model, nmatch,best,current
      if params.get('nof_matches',0):
        for item in range(params['nof_matches']):
           widget.match.addItem(str(item+1))
        if params['nof_matches']>1:  widget.match.addItem('best')
        widget.match.addItem('undo')
        widget.match.setCurrentIndex(widget.match.findText(str(params.get('displayed_match'))))
        widget.match.show()
      else:
        widget.match.hide()
        
    self.block_showMatch = 0

#-------------------------------------------------------------------------
  def updateRMS(self):
#-------------------------------------------------------------------------
    if Appl('Superpose').method == 'interactive':
      self.editMatchesFrame.updateRMS()
    else:
      for model in self.model_list:
        params= Appl('Superpose').supModel[model].getmatchesinfo()
        widget = self.findChild(modelForSuperpose,'superpose'+model)
        widget.rms.setText(str(params.get('rms','')))

#-------------------------------------------------------------------------
  def showMatch(self,model):
#-------------------------------------------------------------------------
    if self.block_showMatch: return
    widget = self.findChild(modelForSuperpose,'superpose'+model)
    if not widget: return
    gui_idx = widget.match.currentText()
    #print 'superposeGui.showMatch',model,gui_idx,nmatch,best,current
    app_idx = Appl('Superpose').handle_change_match(model,gui_idx)
    self.updateMatches()
    self.updateRMS()
    
    import rebuild
    rebuild.UpdateDisplay(auto_save=0)


#-------------------------------------------------------------------------
  def openExport(self):
#-------------------------------------------------------------------------
    if not hasattr(self,'export_gui'):
      import displayTableObjects
      self.export_gui = displayTableObjects.exportGui(self,data_type='Superpose matches')
      self.connect(self.export_gui,QtCore.SIGNAL('save'),self.export)
    self.export_gui.show()

#-------------------------------------------------------------------------
  def export(self):
#-------------------------------------------------------------------------
    #print 'superposeGui.export'
    exfile = self.export_gui.getFile()
    import string
    comments = string.split(self.export_gui.getComments(),'/n')
    if exfile:
      supModel = Appl('Superpose').supModel.get(Appl('Superpose').show_equiv_mol,None)
      if supModel:
        rv = supModel.export_matches(filename=exfile,comments = comments)
        if (not rv[0]) and self.export_gui.getReload():
          import VectorsDispobj
          new_data = VectorsDispobj.openvectorfile(filename=exfile)
          if new_data:
            DISPLAYTABLE().addDataObj(object_type=new_data.object_type,name=new_data.name,
                   label=getattr(new_data,'name_label',''),getDispObj=1)
      else:
        rv = [1,'Error finding data for model '+Appl('Superpose').show_equiv_mol]
    if rv[0]:
      QtGui.QMessageBox.warning(None,self.windowTitle(),rv[1])
    self.export_gui.close()
      
          

#------------------------------------------------------------------------
  def handleAtomPick(self,pickevent=None):
#------------------------------------------------------------------------
    if not pickevent: return
    molobj = pickevent.getDataObj()
    if not molobj: return
    SUP = Appl('Superpose')
    if ( not SUP.method == 'interactive') or (not [SUP.fixed,SUP.show_equiv_mol].count(molobj.name)):
      return 
    #else:
      #other_molobj= data([SUP.fixed,SUP.show_equiv_mol][1-[SUP.fixed,SUP.show_equiv_mol].index(molobj.name)])
    menu = pickevent.getContextMenu()
    if not menu: return
    import guiUtils
    select_menu = ['Superpose: select this']
    end_range_menu = SUP.get_unfinished_range(molobj)
    #print 'handleAtomPick end_range_menu',end_range_menu
    for item in end_range_menu:
      select_menu.append('superpose_select_range_'+str(item[0]))
    select_menu.extend(['superpose_select_atom','superpose_select_monomer','superpose_select_main','superpose_select_side','superpose_select_residue','superpose_select_start'])
    match_menu_items =  SUP.get_unmatched_menu(molobj)
    #print 'handleAtomPick match_menu_items',match_menu_items
    if match_menu_items:
      match_menu = ['Superpose: match this to']
      for item in match_menu_items:
        match_menu.append('superpose_match_'+item[1]+'_'+str(item[0]))
    else:
      match_menu = []
    #undo_menu = ['Superpose edit:','superpose_clear_all','superpose_clear_unmatched','superpose_undo_last']
    guiUtils.populateMenu(self,menu,[select_menu,match_menu,'superpose_undo_last'],self.getActionDef,info = { 'pickevent' : pickevent })
    

#------------------------------------------------------------------------
  def getActionDef(self,name,pickevent=None,**kw):
#------------------------------------------------------------------------
    molobj = pickevent.getDataObj()
    if not molobj: return
    label = pickevent.getLabel(format='full')
    isPeptide = 0
    pAtoms = pickevent.getPickedAtoms()
    if pAtoms and pAtoms[0].residue.isAminoacid():isPeptide = 1

    info = (name,molobj.name,label)
    if name == 'superpose_select_atom':
      return dict ( text = 'Atom',
                    tip = 'Select this atom',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )
    if name == 'superpose_select_monomer':
      return dict ( text = 'Monomer',
                    tip = 'Select this monomer',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )
    if name == 'superpose_select_main' and isPeptide:    
      return dict ( text = 'Main chain',
                    tip = 'Select the main chain atoms of this residue',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )
    if name == 'superpose_select_side' and isPeptide:    
      return dict ( text = 'Side chain',
                    tip = 'Select the side chain atoms of this residue',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )
    if name == 'superpose_select_residue':    
      return dict ( text = 'Residue',
                    tip = 'Select all atoms of this residue',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )
    if name == 'superpose_select_start':    
      return dict ( text = 'Start residue range',
                    tip = 'Select range of residues starting here',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )
    if name[0:22] == 'superpose_select_range':
      ii = int(name[23:])
      menu = Appl('Superpose').get_unfinished_range(molobj)
      for item in menu:
        if item[0] == ii:
          return dict ( text = item[1],
                    tip = 'End range of residues here',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )
    if name[0:15] == 'superpose_match':
      #print 'getActionDef superpose_match',name
      mode,ii = name[16:].split('_')
      ii = int(ii)
      menu = Appl('Superpose').get_unmatched_menu(molobj)
      for item in menu:
        if item[0] == ii and item[1]==mode:
          return dict ( text = item[2],
                    tip = 'Match to these atom(s) or residue(s)',
                    deleteLater = 1,
                    slot = [self.pickSelect,info] )

    if name == 'superpose_clear_unmatched':
      return dict ( text = 'Clear unmatched selections',
                    tip = 'Remove any selections in either model',
                    slot =  [self.pickSelect,info] )
    
    if name == 'superpose_clear_all':
      return dict ( text = 'Clear all selections/matches',
                    tip = 'Remove any selections in either model',
                    slot =  [self.pickSelect,info] )

    if name == 'superpose_undo_last':
      return dict ( text = 'Undo last selection/match',
                    tip = 'Undo the previous selection or match',
                    slot =  [self.pickSelect,info] )

    return {}
    
#------------------------------------------------------------------------
  def pickSelect(self,info=[],**kw):
#------------------------------------------------------------------------
    #print 'pickSelect',info
    name,molobj_name,label = info
    matchID = -1
    if name[0:22] == 'superpose_select_range':
      matchID=Appl('Superpose').handle_atom_popup(end_range=int(name[23:]),MolData_name=molobj_name,
                                          atomID = label)
    
    elif name[0:16] == 'superpose_select':
      matchID=Appl('Superpose').handle_atom_popup(select=name[17:],MolData_name=molobj_name,
                                          atomID = label)    
    elif name[0:15] == 'superpose_match':
      mode,match = name[16:].split('_')
      matchID=Appl('Superpose').handle_atom_popup(match=int(match),MolData_name=molobj_name,
                                          atomID = label,mode=mode)

    elif name == 'superpose_clear_unmatched':
       Appl('Superpose').handle_atom_popup(clear_unmatched = 1)
       
    elif name == 'superpose_clear_all':
       Appl('Superpose').handle_atom_popup(clear_all = 1)
       
    elif name == 'superpose_undo_last':
       Appl('Superpose').handle_atom_popup(undo_last = 1)
       
    import rebuild
    rebuild.UpdateDisplay()
    if getattr(self,'editMatchesFrame',None):
      self.editMatchesFrame.loadSelectMatch()
      self.editMatchesFrame.setMatchId(matchID)

    
    
#-------------------------------------------------------------------------
  def saveFiles(self):
#-------------------------------------------------------------------------
    DataObj_changed = []
    DataObj_unchanged = []
    for model,supModel in Appl('Superpose').supModel.items():
      molobj = data(model)
      if molobj:
        if molobj.molHnd.GetIsTransformed():
          DataObj_changed.append(model)
        else:
          DataObj_unchanged.append(model)
    #print 'superpose.Gui.saveFiles',DataObj_changed,'unchanged:',DataObj_unchanged
    if not self.multiSaveWidget:
      import saveDataFiles
      self.multiSaveWidget = saveDataFiles.saveDataFiles(self,
           application_tag='superpose',title='Save coordinates after superpose')
    self.multiSaveWidget.setDataObj(DataObj_changed=DataObj_changed,DataObj_unchanged=DataObj_unchanged)
    self.multiSaveWidget.show()
    self.connect( self.multiSaveWidget,QtCore.SIGNAL('saved_files'),guiUtils.partial(self.emit,QtCore.SIGNAL('enableSave')))
    self.connect( self.multiSaveWidget,QtCore.SIGNAL('saved_files'),self.updateDataObjLabels)

#-------------------------------------------------------------------------
  def updateDataObjLabels(self):
#-------------------------------------------------------------------------
    #print 'superposeGui.updateDataObjLabels'
    for widget in self.findChildren(modelForSuperpose):
      widget.setNameLabel()

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

  label = {    'name_label' : '',
               'on' : 'Active',
               'fixed': 'Fixed',
               'visible' : 'Matches',
               'selection': 'Selection',
               'show_mask' : 'Mask',
               'match' : 'Show match',
               'rms' : 'RMS' }
  columns = { 'name_label' : 0,
              'on' : 1,
              'fixed' : -1,
              'visible' : -1,
              'selection' : 2,
              'show_mask' : -1,
              'match' : 3,
              'rms' : 4 }
  
  close_columns = { 'name_label' : 0,
              'on' : 1,
              'fixed' : -1,
              'visible' : -1,
              'selection' : 2,
              'show_mask' : -1,
              'match' : -1,
              'rms' : 3 }
 
  tooltips = { 'name_label' : '',
               'on' : 'Superpose this model?',
               'fixed': 'Select one fixed model',
               'visible' : 'Show matches to fixed model',
               'selection': 'Select set of atoms to be superposed',
               'show_mask' : 'Highlight the selected atoms',
               'match' : 'Show alternative superposition',
               'rms' : 'RMS distance between overlapped atoms in fixed and this model' }
            
  def __init__(self,parent=None,name='',layout=None,row=0):
    QtGui.QWidget.__init__(self,parent)

    self.setObjectName('superpose'+name)

    '''
    self.fixed = QtGui.QRadioButton(self)
    self.fixed.setToolTip(modelForSuperpose.tooltips['fixed'])
    self.parent().parent().fixed_group.addButton(self.fixed)
    self.connect(self.fixed,QtCore.SIGNAL('clicked(bool)'),self.handleFixed)

    self.visible = QtGui.QCheckBox(self)
    self.visible.setToolTip(modelForSuperpose.tooltips['visible'])
    self.connect(self.visible,QtCore.SIGNAL('clicked(bool)'),self.handleVisible)
    '''

    self.on = QtGui.QCheckBox(self)
    self.on.setToolTip(modelForSuperpose.tooltips['on'])
    self.connect(self.on,QtCore.SIGNAL('clicked(bool)'),self.handleOn)
    
    self.name_label = QtGui.QLabel('',self)
    self.setNameLabel()

    self.selection = mgWidgets.mgSelectionCombo(self,data(name).treeModel,selectionWidgets=['chains','neighb','namedSelection'],highlightPending=1)
    self.selection.setToolTip(modelForSuperpose.tooltips['selection'])
    self.connect(self.selection,QtCore.SIGNAL('changed'),self.handleSelection)

    
    self.show_mask = QtGui.QCheckBox(self)
    self.show_mask.setToolTip(modelForSuperpose.tooltips['show_mask'])
    self.connect(self.show_mask,QtCore.SIGNAL('clicked(bool)'),self.handleShowMask)
    

    self.match = QtGui.QComboBox(self)
    self.match.setToolTip(modelForSuperpose.tooltips['match'])
    self.match.setVisible(0)

    self.rms = QtGui.QLabel(self)
    self.rms.setToolTip(modelForSuperpose.tooltips['rms'])
    self.rms.setVisible(0)

    self.layoutWidgets(row=row,columns=modelForSuperpose.columns)


  def delete(self):
    layout = self.parent().layout()
    for item in ['on','name_label','selection','show_mask','match','rms']:
      widget = getattr(self,item)
      #widget.hide()
      #layout.removeWidget(widget)
      #widget.deleteLater()
      widget.close()
    self.deleteLater()


  def layoutWidgets(self,layout=None,row=-1,columns={}):
    if layout is None: layout = self.parent().layout()
    for key,col in columns.items():
      widget = getattr(self,key,None)
      #print 'layoutWidgets',key,row,col,widget,layout
      if widget:
        if col>=0:
          widget.setVisible(1)
          layout.addWidget(widget,row,col)
        else:
          widget.setVisible(0)

    
  def setParams(self,params={},**kw):
    #print "modelForSuperpose.setParams",self.objectName(),params
    if params.has_key('on'): self.on.setChecked(params['on'])

    '''
    if params.has_key('show'):
      if superposeGui.show_alias.count(params['show']):
        getattr(self,'show').setCurrentIndex( superposeGui.show_alias.index(params['show']))
    '''
    if params.has_key('selection'):
      widget = getattr(self,'selection',None)
      if widget:
        widget.setText(params['selection'])
        widget.updateTreeView()


  def getParams(self):
    params = {}
    #for item in ['fixed','equiv','on']:
    for item in ['fixed','on']:
      if  getattr(self,item,None):
        params[item] = getattr(self,item).isChecked()
    #params['show'] = superposeGui.show_alias[getattr(self,'show').currentIndex()]
    params['selection']=getattr(self,'selection').text()
    #print "modelForSuperpose.getParams",self.objectName(),params
    return params

    
  def handleFixed(self,state):
    Appl('Superpose').set_fixed(str(self.objectName())[9:])
    import rebuild
    rebuild.UpdateDisplay(auto_save=0)

      
  def handleVisible(self,state):
    #print 'handleVisible',self.objectName(),state
    target = Appl('Superpose').GetSuperposeModel(str(self.objectName())[9:])
    if target: target.set_visibility(int(state))
    import rebuild
    rebuild.UpdateDisplay(auto_save=0)

  def handleMoving(self,state):
    #print 'handleMoving',self.objectName(),state
    Appl('Superpose').setparams(show_equiv_mol=str(self.objectName())[9:])
    
  def row(self):
    return self.parent().parent().getModelRow(str(self.objectName())[9:])
  

  def handleShowMask(self,state):
    #print 'handleShowMask',self.objectName(),state
    target = Appl('Superpose').GetSuperposeModel(str(self.objectName())[9:])
    if target: target.set_show_mask(int(state))

    import rebuild
    rebuild.UpdateDisplay(auto_save=0)

  def handleSelection(self):
    #print "modelForSuperpose.handleSelection",getattr(self,'selection').text()
    target = Appl('Superpose').GetSuperposeModel(str(self.objectName())[9:])
    if target: target.setparams(on=int(self.on.isChecked()),selection=str(getattr(self,'selection').text()))
    import rebuild
    rebuild.UpdateDisplay(auto_save=0)
    
  def handleOn(self,state):
    target = Appl('Superpose').GetSuperposeModel(str(self.objectName())[9:])
    if target: target.setparams(on=int(self.on.isChecked()))


  def setNameLabel(self):
    dobj = data(self.objectName()[9:])
    if dobj:       
      self.name_label.setText(dobj.get_label())


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

  mode_menu = ['Residue','Residue range','Atom','Monomer']
  mode_alias = ['residue','range','atom','monomer']
  picker_mode = ['residue','range','atom','residue']

  def __init__(self,parent):
    QtGui.QWidget.__init__(self,parent)
    #print "interactiveSuperposeMatch parent",parent
    
    layout = QtGui.QHBoxLayout()
    layout.setContentsMargins(0,0,0,0)
    layout.setSpacing(0)
    
    widget = QtGui.QComboBox(self)
    widget.setObjectName('mode')
    for item in interactiveSuperposeMatch.mode_menu:
      widget.addItem(item)
    widget.setToolTip('Limit superposition to atoms')
    self.connect(widget,QtCore.SIGNAL('currentIndexChanged(int)'),self.handleChangeMode)
    layout.addWidget(widget)

    #abstractModel = data(self.parent().fixed_MolData_name).treeModel
    #widget = mgWidgets.mgSelectionCombo(self,abstractModel,selectionWidgets=['namedSelection','neighb','chains'])
    widget = mgWidgets.mgAtomPicker(self,self.parent().fixed_MolData_name,'residue')
    widget.setObjectName('fixed_selection_command')
    widget.setToolTip('Select residue(s) or atoms in fixed model')
    layout.addWidget(widget)
    
    widget = mgWidgets.mgAtomPicker(self,self.parent().MolData_name,'range')
    #abstractModel = data(self.parent().MolData_name).treeModel
    #widget = mgWidgets.mgSelectionCombo(self,abstractModel,selectionWidgets=['namedSelection','neighb','chains'])
    widget.setObjectName('moving_selection_command')
    widget.setToolTip('Select residue(s) or atoms in moving model')
    layout.addWidget(widget)
    
    self.setLayout(layout)

  def setDefault(self):
    self.findChild(QtGui.QComboBox,'mode').setCurrentIndex(0)
    #self.findChild(mgWidgets.mgSelectionCombo,'fixed_selection_command').clear()
    #self.findChild(mgWidgets.mgSelectionCombo,'moving_selection_command').clear()
    self.findChild(mgWidgets.mgAtomPicker,'fixed_selection_command').clear()
    self.findChild(mgWidgets.mgAtomPicker,'moving_selection_command').clear()

  def handleChangeMode(self,imode):
    #print 'interactiveSuperposeMatch.handleChangeMode',imode
    mode = interactiveSuperposeMatch.picker_mode[imode]
    self.findChild(mgWidgets.mgAtomPicker,'fixed_selection_command').setMode(mode)
    self.findChild(mgWidgets.mgAtomPicker,'moving_selection_command').setMode(mode)
    
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
class interactiveSuperposeGui(QtGui.QFrame):
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------

  def __init__(self,parent,MolData_name,fixed_MolData_name):
    QtGui.QFrame.__init__(self,parent)
    self.MolData_name = MolData_name
    self.fixed_MolData_name = fixed_MolData_name
    layout = QtGui.QVBoxLayout()
    self.exframe = mgWidgets.extendingFrame(self,interactiveSuperposeMatch,
                        nLines=1,ifApply=1,ifEditable=1,ifClear=1,width=0)

    layout.addWidget(self.exframe)
    self.setLayout(layout)
    
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#----------------------------------------------------------------------
class editMatchesFrame(QtGui.QFrame):
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#----------------------------------------------------------------------
        mode_alias = ['atom','side','main','residue','range','range_same_seqid','monomer','selection','selection_close']
        mode_menu = ['atom','side chain','main chain','residue','residue range','range with same seq id','monomer','selection','close atoms in selection']
        picker_mode = ['atom','side','main','residue','range','range','residue','selection','selection']

        def __init__(self,parent=None,fixed_MolData_name='',MolData_name='',matchId=-1):
                QtGui.QFrame.__init__(self,parent)
                self.fixed_MolData_name = fixed_MolData_name
                self.MolData_name = MolData_name
                self.matchId=-1
                self.copyMatchGui = None
                self.signalsBlocked = 0
                
		layout = QtGui.QGridLayout(self)
                layout.setSpacing(2)
                layout.setContentsMargins(2,2,2,2)
                
                self.selectMatch= QtGui.QListWidget(self)
                self.selectMatch.setFont(QtGui.QFont('Courier',12))
                self.selectMatch.setToolTip('List of matching atoms/residues/monomers\ndouble click line to toggle onn/off')
                self.selectMatch.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)


                #edit_button = QtGui.QPushButton('Edit selected match',self)
                #self.connect(edit_button,QtCore.SIGNAL('clicked()'),self.resetEditMatch)
                new_button = QtGui.QPushButton('Create new match',self)
                self.connect(new_button,QtCore.SIGNAL('clicked()'),self.handleNew)
                copy_button = QtGui.QPushButton('Copy matches from..',self)
                self.connect(copy_button,QtCore.SIGNAL('clicked()'),self.copyMatches)
                delete_button = QtGui.QPushButton('Delete selected match',self)
                self.connect(delete_button,QtCore.SIGNAL('clicked()'),self.deleteMatch)
                delete_all_button = QtGui.QPushButton('Delete all matches',self)
                self.connect(delete_all_button,QtCore.SIGNAL('clicked()'),self.deleteAll)
                delete_unmatched_button = QtGui.QPushButton('Delete incomplete matches',self)
                self.connect(delete_unmatched_button,QtCore.SIGNAL('clicked()'),guiUtils.partial(self.deleteAll,1))
                
                #save_button = QtGui.QPushButton('Save this match',self)
                #self.connect(save_button,QtCore.SIGNAL('clicked()'),self.Apply)

                editLayout= QtGui.QGridLayout()
                editLayout.addWidget(self.selectMatch,0,0,5,1)
                #editLayout.addWidget(edit_button,0,1)
                editLayout.addWidget(new_button,0,1)
                editLayout.addWidget(copy_button,1,1)
                editLayout.addWidget(delete_button,2,1)
                editLayout.addWidget(delete_all_button,3,1)
                editLayout.addWidget(delete_unmatched_button,4,1)
                layout.addLayout(editLayout,0,0)


		pickerLayout = QtGui.QVBoxLayout()

                line_layout = QtGui.QHBoxLayout()
                self.onCheckBox = QtGui.QCheckBox('Use match of mode ',self)
                line_layout.addWidget(self.onCheckBox)

                self.modeCombo = QtGui.QComboBox(self)
                for item in editMatchesFrame.mode_menu:
                  self.modeCombo.addItem(item)
                self.modeCombo.setToolTip('Choose a match mode')
                line_layout.addWidget(self.modeCombo)
                #line_layout.addWidget(save_button)
                '''
                self.closeCheckBox = QtGui.QCheckBox('Select close atoms for model without selection',self)
                line_layout.addWidget(self.closeCheckBox)
                '''
                line_layout.addStretch(5)
                self.rmsLabel = QtGui.QLabel(' ')
                line_layout.addWidget(self.rmsLabel)
                pickerLayout.addLayout(line_layout)

                fixedLabel = QtGui.QLabel(self.tr("Fixed model"))
		movingLabel = QtGui.QLabel(self.tr("Moving model"))

                line_layout = QtGui.QHBoxLayout()
		line_layout.addWidget(fixedLabel)
                pickerLayout.addLayout(line_layout)

                
                self.fixedLayout = QtGui.QHBoxLayout()
                self.fixedAtomPicker =  mgWidgets.mgAtomPicker(MolData_name=self.fixed_MolData_name,blank=1)
                
                abstractModel = data(self.fixed_MolData_name).treeModel
                self.fixedSelectionCombo = mgWidgets.mgSelectionCombo(self,abstractModel,selectionWidgets=['namedSelection','neighb','chains'])
                self.fixedSelectionCombo.hide()                
                self.fixedLayout.addWidget(self.fixedAtomPicker)
                pickerLayout.addLayout(self.fixedLayout)
                

                line_layout = QtGui.QHBoxLayout()
                line_layout.addWidget(movingLabel)
                pickerLayout.addLayout(line_layout)

                
                self.movingLayout = QtGui.QHBoxLayout()
                self.movingAtomPicker =  mgWidgets.mgAtomPicker(MolData_name=self.MolData_name,blank=1)

                self.movingLayout.addWidget(self.movingAtomPicker)
                
                abstractModel = data(self.MolData_name).treeModel
                self.movingSelectionCombo = mgWidgets.mgSelectionCombo(self,abstractModel,selectionWidgets=['namedSelection','neighb','chains'])
                self.movingSelectionCombo.hide()              
                pickerLayout.addLayout(self.movingLayout)
                
 
		layout.addLayout(pickerLayout,1,0)

                # Set default mode to 'range'
                self.handleChangeMode(editMatchesFrame.mode_alias.index('range'))
                self.connect(self.modeCombo,QtCore.SIGNAL('currentIndexChanged(int)'),self.handleChangeMode)


                self.loadSelectMatch()
                if self.selectMatch.count()>0:
                  self.setMatchId(0)
                else:
                  self.handleNew()
                #self.updateDisplay()


                self.connect(self.selectMatch,QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'),
                             self.changeMatchOn)
                self.connect(self.selectMatch,QtCore.SIGNAL('itemClicked(QListWidgetItem*)'),self.changeMatchId)
                self.connect(self.selectMatch,QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'),self.selectMatchMenu)
                self.connect(self.modeCombo,QtCore.SIGNAL('currentIndexChanged(int)'),self.Apply) 
                self.connect(self.fixedAtomPicker,QtCore.SIGNAL("AtomChanged"),self.Apply)
                self.connect(self.fixedSelectionCombo,QtCore.SIGNAL("changed"),self.Apply)               
                self.connect(self.onCheckBox,QtCore.SIGNAL("clicked(bool)"),self.clickedMatchOn) 
                self.connect(self.movingAtomPicker,QtCore.SIGNAL("AtomChanged"),self.Apply)
                self.connect(self.movingSelectionCombo,QtCore.SIGNAL("changed"),self.Apply)               

                  

		#self.setLayout(layout)

        def selectMatchMenu(self,point):
          #print 'selectMatchMenu',point
          pass

        def handleChangeMode(self,imode=-1):
          #print 'handleChangeMode',imode
          self.blockWidgetSignals(1)
          if imode<0:
            mode = editMatchesFrame.picker_mode[self.modeCombo.currentIndex()]
          else:
            mode = editMatchesFrame.picker_mode[imode]
            self.modeCombo.setCurrentIndex(imode)
          if ['selection','selection_close'].count(mode):
            self.toggleSeleWidget(self.fixedLayout,self.fixedSelectionCombo,self.fixedAtomPicker)
            self.toggleSeleWidget(self.movingLayout,self.movingSelectionCombo,self.movingAtomPicker)
          else:
            self.toggleSeleWidget(self.fixedLayout,self.fixedAtomPicker,self.fixedSelectionCombo)
            self.toggleSeleWidget(self.movingLayout,self.movingAtomPicker,self.movingSelectionCombo)
            if mode == 'range_same_seqid': mode = 'range'
            self.fixedAtomPicker.setMode(mode)
            self.movingAtomPicker.setMode(mode)
          self.blockWidgetSignals(0)

        def toggleSeleWidget(self,layout,on_widget,off_widget):   
          on_widget.show()
          off_widget.hide()
          layout.removeWidget(off_widget)
          layout.addWidget(on_widget)

        def changeMatchId(self,listItem):
          row = self.selectMatch.row(listItem)
          self.setMatchId(row)

        def changeMatchOn(self,listItem):
          #Called when the list widget clicekd to toggle match
          row = self.selectMatch.row(listItem)
          #print 'editMatchesFrame.changeMatchOn',listItem,row
          matchObject = Appl('Superpose').GetSuperposeModelMatch(self.MolData_name,row)
          if not matchObject: return
          on = matchObject.getparams().get('on',-1)
          if on>=0:
              matchObject.setparams( { 'on' : 1-on} )
              self.recolourRow(row,1-on)
              self.updateDisplay()

        def clickedMatchOn(self,status):
          # Called when check box clicked
          row = self.getMatchId()
          matchObject = Appl('Superpose').GetSuperposeModelMatch(self.MolData_name,row)
          if not matchObject: return
          on = int(self.onCheckBox.isChecked())      
          matchObject.setparams( { 'on' : on} )
          self.recolourRow(row,on)
          self.updateDisplay()


        def recolourRow(self,row,on):
          #print 'recolourRow',row,on
          brush = self.selectMatch.item(row).foreground()
          if on:
            brush.setColor(QtCore.Qt.black)
          else:
            brush.setColor(QtCore.Qt.lightGray)
          self.selectMatch.item(row).setForeground(brush)
          

        def handleNew(self):
          supModel = Appl('Superpose').GetSuperposeModel(self.MolData_name)
          newId = supModel.new_match()
          #print 'handleNew',newId
          self.setMatchId(newId)
          self.loadSelectMatch()
          self.setRow(newId)
          

        '''
	def handleDTChanged(self):
          self.startAtomPicker.dataCombo.clear()
          self.endAtomPicker.dataCombo.clear()
          self.startAtomPicker.dataCombo.populateMenu(object_type='MolData',parent=self.startAtomPicker)
          self.endAtomPicker.dataCombo.populateMenu(object_type='MolData',parent=self.endAtomPicker)
        '''

	def Apply(self):
          #print 'editMatchesFrame.Apply'
          supModel = Appl('Superpose').GetSuperposeModel(self.MolData_name)
          saveId = self.getMatchId()
          #if saveId<0: saveId = supModel.new_match()
          matchObject = Appl('Superpose').GetSuperposeModelMatch(self.MolData_name,saveId)
          #print 'editMatchesFrame.Apply',saveId,matchObject,self.getParams()
          if matchObject:
            matchObject.setparams(self.getParams())
            '''
            if matchObject.mode == 'range':
              rv = matchObject.setEndOfRange(matchObject.get('mode'),self.fixed_MolData_name,self.MolData_name)
              if rv[0] == 1:
                QtGui.QMessageBox.warning(None,self.windowTitle(),rv[1])
            '''
            self.loadSelectMatch(saveId)
            self.emit(QtCore.SIGNAL('matchesChanged'))
            self.updateDisplay(saveId)

        def updateDisplay(self,saveId=-1):
          supModel = Appl('Superpose').GetSuperposeModel(self.MolData_name)
          if supModel:
            supModel.update_Connectivity2(saveId)
            supModel.do_redraw = 1
            UPDATEDISPLAY()
          

        def Help(self):
          HELPBROWSER().loadMgHelp('superpose.html')
            

            
        def loadSelectMatch(self,iMatch=-1):
          
          #self.selectMatch.blockSignals(True)
          supModel = Appl('Superpose').GetSuperposeModel(self.MolData_name)
          if supModel:
            
            match_list = supModel.get_match_menu(iMatch)
            #print 'loadSelectMatch',match_list
            if iMatch<0:
              self.selectMatch.clear()
              row = -1
              for active,label in match_list:
                #print 'loadSelectMatch',active,label
                self.selectMatch.addItem(label)
                row = row + 1
                if not active:
                  brush = self.selectMatch.item(row).foreground()
                  brush.setColor(QtCore.Qt.lightGray)
                  self.selectMatch.item(row).setForeground(brush)
            elif len(match_list)>0 and iMatch<self.selectMatch.count():
              self.selectMatch.item(iMatch).setText(match_list[0][1])
            #self.selectMatch.addItem('New match.. ')
          #self.selectMatch.blockSignals(False)
          self.selectMatch.update()

        def deleteMatch(self):
          iV = self.selectMatch.currentRow()
          if iV>=0 and iV<(self.selectMatch.count()):
            supModel = Appl('Superpose').GetSuperposeModel(self.MolData_name)
            if supModel:
              supModel.delete_match(iV)
            self.loadSelectMatch()
            
            self.setMatchId(iV)
            self.updateDisplay()
            self.emit(QtCore.SIGNAL('matchesChanged'))

        def deleteAll(self,unmatched=0):
          supModel = Appl('Superpose').GetSuperposeModel(self.MolData_name)
          if unmatched:
            supModel.clear_unmatched()
          else:
            supModel.clear_all()
          supModel.update_Connectivity2()
          #print 'deleteAll',self.selectMatch.count()
          self.loadSelectMatch()
          if self.selectMatch.count()<=0: 
            self.handleNew()
          else:
            self.setMatchId(-1)
          self.updateDisplay()
          self.clear()
          self.emit(QtCore.SIGNAL('matchesChanged'))

          
        def clear(self):
          self.blockWidgetSignals(1)
          self.fixedSelectionCombo.clear()
          self.movingSelectionCombo.clear()
          self.fixedAtomPicker.reset()
          self.movingAtomPicker.reset()
          self.onCheckBox.setChecked(1)
          self.blockWidgetSignals(0)

        def blockWidgetSignals(self,mode):
          if mode:
            self.signalsBlocked = self.signalsBlocked + 1
          else:
            self.signalsBlocked = self.signalsBlocked - 1
          if self.signalsBlocked:
            imode = True
          else:
            imode = False
          self.fixedSelectionCombo.blockSignals(imode)
          self.movingSelectionCombo.blockSignals(imode)
          self.fixedAtomPicker.blockSignals(imode)
          self.movingAtomPicker.blockSignals(imode)
          self.modeCombo.blockSignals(imode)
          self.onCheckBox.blockSignals(imode)
          #print 'blockWidgetSignals',mode,self.signalsBlocked,imode

        def setParams(self,params={},**kw):
          #print 'editMatchesFrame.setParams',params
          pars = {}
          import Superpose
          pars.update(Superpose.SuperposeMatch.initialise)
          pars.update(params)
          pars.update(kw)
          imode = editMatchesFrame.mode_alias.index(pars.get('mode','range'))
          #print 'setParams imode',imode
          self.blockWidgetSignals(1)
          self.modeCombo.setCurrentIndex(imode)
          self.onCheckBox.setChecked(pars.get('on',1))
          self.handleChangeMode()

          if ['selection','selection_close'].count(pars.get('mode','range')):
            self.fixedSelectionCombo.setParams(selection=pars.get('sele1',''))
            self.movingSelectionCombo.setParams(selection=pars.get('sele2',''))
          else:
            self.fixedAtomPicker.setSelection(atomName=pars.get('sele1',''))
            self.movingAtomPicker.setSelection(atomName=pars.get('sele2',''))
          self.blockWidgetSignals(0)

            
        def getParams(self):
          import Superpose
          mode = editMatchesFrame.mode_alias[self.modeCombo.currentIndex()]
          on = int(self.onCheckBox.isChecked())
          #close = int(self.closeCheckBox.isChecked())
          if ['selection','selection_close'].count(mode):
            sele1 = self.fixedSelectionCombo.text()
            sele2 = self.movingSelectionCombo.text()
          else:
            sele1 = self.fixedAtomPicker.selection()
            sele2 = self.movingAtomPicker.selection()
          pars = { 'mode' : mode,
                   'on' : on,
                   'sele1' : sele1,
                   'sele2' : sele2 }
          #         'close' : close,
          #print 'editMatchesFrame.getParams',pars
          return pars

        def getMatchId(self):
          return self.matchId
            
        def setMatchId(self,vid=-1):
          #print 'setMatchId',vid
          if vid<0 or vid> self.selectMatch.count():
            vid = self.selectMatch.count()-1
          self.setRow(vid)
          supModelMatch = Appl('Superpose').GetSuperposeModelMatch(self.MolData_name,vid)
          self.matchId = vid
          if supModelMatch: self.setParams(supModelMatch.getparams())
 
        def setRow(self,irow):
          if irow == self.selectMatch.currentRow(): return
          self.selectMatch.blockSignals(True)
          self.selectMatch.setCurrentRow(irow)
          self.selectMatch.blockSignals(False)

          
        def copyMatches(self):
          if not self.copyMatchGui:
            self.copyMatchGui=QtGui.QDialog(self)
            self.copyMatchGui.setWindowTitle('Superpose: Copy Matches')
            layout = QtGui.QGridLayout()
            layout.addWidget(QtGui.QLabel('Copy matches from',self),0,0,1,2)
            layout.addWidget(QtGui.QLabel('Fixed model',self),1,0)
            self.copyMatchFixed = mgWidgets.mgDataObjCombo(parent=self,object_type='MolData')
            layout.addWidget(self.copyMatchFixed,1,1)
            self.copyMatchFixed.setCurrentDataObj(self.fixed_MolData_name)
            layout.addWidget(QtGui.QLabel('Moving model',self),2,0)
            self.copyMatchMoving = mgWidgets.mgDataObjCombo(parent=self,object_type='MolData')
            layout.addWidget(self.copyMatchMoving,2,1)
            self.copyMatchMoving.setCurrentDataObj(self.MolData_name)

            dialog_buttons = QtGui.QDialogButtonBox()
            apply_button = dialog_buttons.addButton(QtGui.QDialogButtonBox.Apply)
            cancel_button = dialog_buttons.addButton(QtGui.QDialogButtonBox.Cancel)
            self.connect(cancel_button,QtCore.SIGNAL('clicked()'),self.copyMatchGui.close)
            self.connect(apply_button,QtCore.SIGNAL('clicked()'),self.handleCopyMatches)
            layout.addWidget(dialog_buttons)
            self.copyMatchGui.setLayout(layout)
          self.copyMatchGui.show()

        def handleCopyMatches(self):

          fixed = self.copyMatchFixed.getCurrentDataObj().name
          moving =  self.copyMatchMoving.getCurrentDataObj().name
          #print 'handleCopyMatches',fixed,moving

          if fixed == moving or (fixed == self.fixed_MolData_name and moving == self.MolData_name):
            QtGui.QMessageBox.warning(None,self.copyMatchGui.windowTitle(),'Invalid choice of models for copying matches')
          else:
            status,info = MODELINFO().get_info(set=moving,info='superpose_matches',key=fixed)
            if status or not info.has_key(fixed) or len(info[fixed])<=0:
              
              QtGui.QMessageBox.warning(None,self.copyMatchGui.windowTitle(),'There are no saved matches for these models')
            else:
              supModel = Appl('Superpose').GetSuperposeModel(self.MolData_name)
              if supModel:
                supModel.set_matches(info[fixed])
                self.loadSelectMatch()

        def updateRMS(self):
          supModel = Appl('Superpose').supModel.get(self.MolData_name)
          self.rmsLabel.setText('Last superposition RMS '+supModel.last_rms)
