""" qtgui/CCP4ModelWidgets.py: CCP4 Gui Project Copyright (C) 2010 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. """ ##@package CCP4ModelWidgets (QtGui) Collection of widgets for model data types from PyQt4 import QtGui,QtCore import CCP4ModelData from CCP4ErrorHandling import * import CCP4Widgets class CResidueRangeView(CCP4Widgets.CComplexLineWidget): MODEL_CLASS = CCP4ModelData.CResidueRange ERROR_CODES = { } def __init__(self,parent=None,model=None,qualifiers={}): qualis = qualifiers CCP4Widgets.CComplexLineWidget.__init__(self,parent,qualis) #if self.editable: self.connect(self.iconButton,QtCore.SIGNAL('acceptDropData'),self.handleDrop) if model is not None: self.setModel(model) self.layout().addWidget(QtGui.QLabel('Chain')) if self.editable: self.widgets['chainId'] = CCP4Widgets.CComboBox(self,charWidth=2,dragType=self.dragType()) else: self.widgets['chainId'] = CCP4Widgets.CLabel(self,charWidth=4,uneditable=True,dragType=self.dragType()) self.layout().addWidget(self.widgets['chainId']) for item,label in [['firstRes','residue'],['lastRes','to']]: self.layout().addWidget(QtGui.QLabel(label)) if self.editable: self.widgets[item] = CCP4Widgets.CLineEdit(self,charWidth=10,dragType=self.dragType()) else: self.widgets[item] = CCP4Widgets.CLabel(self,charWidth=10,uneditable=True,dragType=self.dragType()) self.layout().addWidget(self.widgets[item]) if self.editable: for item in self.widgets.keys(): self.connect(self.widgets[item],QtCore.SIGNAL('editingFinished()'),self.updateModelFromView) self.connect(self.widgets[item],QtCore.SIGNAL('acceptDropData'),self.acceptDropData) pdbFileObj = self.model.parent().getDataByKey('pdbFileKey') if pdbFileObj is not None: self.loadChains() self.connect(pdbFileObj,QtCore.SIGNAL('dataChanged'),self.loadChains) self.layout().addStretch(5) def loadChains(self): self.widgets['chainId'].clear() for chn in self.model.parent().getChains(): self.widgets['chainId'].addItem(chn) def getMenuDef(self): return ['clear','copy','paste','help'] class CSequenceEdit: def __init__(self,parent=None,model=None): pass class CSequenceView(CCP4Widgets.CComplexLineWidget): ERROR_CODES = { } MODEL_CLASS = CCP4ModelData.CSequence def __init__(self,parent=None,model=None,qualifiers={}): qualis = {'gridLayout':True} qualis.update(qualifiers) CCP4Widgets.CComplexLineWidget.__init__(self,parent,qualis) if model is not None: self.setModel(model) #if qualis.get('stackButton',None) is not None: # self.layout().addWidget(qualis['stackButton'],0,1) self.layout().addWidget(QtGui.QLabel('Description:',self),1,0) if self.editable: self.widgets['identifier'] = CCP4Widgets.CLineEdit(self,qualifiers=qualis) self.widgets['reference'] = CCP4Widgets.CLineEdit(self,qualifiers=qualis) self.widgets['referenceDb'] = CCP4Widgets.CComboBox(self,qualifiers= CCP4ModelData.CSequence.CONTENTS['referenceDb']['qualifiers'] ) else: self.widgets['identifier'] = CCP4Widgets.CLabel(self,qualifiers=qualis) self.widgets['reference'] = CCP4Widgets.CLabel(self,qualifiers=qualis) self.widgets['referenceDb'] = CCP4Widgets.CLabel(self,qualifiers=qualis) self.widgets['identifier'].setToolTip('Name of the sequence') self.widgets['reference'].setToolTip('Database identifier') self.widgets['referenceDb'].setToolTip('Sequence database') self.layout().addWidget(self.widgets['identifier'],1,1,1,2) self.layout().addWidget(QtGui.QLabel('Database reference:',self),0,0) self.layout().addWidget(self.widgets['referenceDb'],0,1) self.layout().addWidget(self.widgets['reference'],0,2) #if self.editable: # self.widgets['moleculeType']=CCP4Widgets.CComboBox(self,qualifiers= CCP4ModelData.CSequence.CONTENTS['moleculeType']['qualifiers']) #else: # self.widgets['moleculeType']=CCP4Widgets.CLabel(self,qualifiers=qualis) #self.layout().addWidget(self.widgets['moleculeType'],0,5) self.widgets['sequence'] = CCP4Widgets.CTextEdit(self,qualifiers=qualis) self.layout().addWidget(self.widgets['sequence'],2,0,1,3) for item in CCP4ModelData.CSequence.CONTENTS_ORDER: widget = self.widgets.get(item,None) if widget is not None: #print 'CSequenceView.__init__',item,repr(self.model.getDataObjects(item)),type(self.model.getDataObjects(item)) if model is not None: tT = self.model.getDataObjects(item).qualifiers('toolTip') if tT is NotImplemented: tT = '' widget.setToolTip(tT) if self.editable: self.connect(widget,QtCore.SIGNAL(widget.editSignal()),self.updateModelFromView) self.connect(widget,QtCore.SIGNAL('acceptDropData'),self.acceptDropData) def getMenuDef(self): menu = CCP4Widgets.CComplexLineWidget.getMenuDef(self) menu.insert(0,'content') return menu def updateViewFromModel(self): #print 'CSequenceView.updateViewFromModel model',self.model #print 'CSequenceView.updateViewFromModel',self.model.get() if len(self.widgets) == 0: return if self.model is None: for item in ['identifier','reference','referenceDb','sequence']: self.widgets[item].setValue('') else: for item in ['identifier','reference','referenceDb','sequence']: #print 'CSequenceView.updateViewFromModel',item,self.model.__dict__['_value'][item].__str__() self.widgets[item].setValue(self.model.__dict__['_value'][item].__str__()) self.validate() class CSeqDataFileView(CCP4Widgets.CDataFileView): MODEL_CLASS = CCP4ModelData.CSeqDataFile def __init__(self,parent=None,model=None,qualifiers={}): qualis = {'vboxLayout':True} qualis.update(qualifiers) self.enableEdit = qualifiers.get('enableEdit',True) CCP4Widgets.CDataFileView.__init__(self,parent=parent,model=model,qualifiers=qualis) qualis['iconButton'] = False if model is not None: self.widgets['sequence'] = CSequenceView(parent=parent,model=model.getFileContent(),qualifiers=qualis) else: self.widgets['sequence'] = CSequenceView(parent=parent,qualifiers=qualis) self.layout().addWidget(self.widgets['sequence']) self.widgets['sequence'].hide() self.setModel(model) parentTask = self.parentTaskWidget() if parentTask is not None: self.connect(parentTask,QtCore.SIGNAL('doFix'),self.saveSequence) def getMenuDef(self): if self.editable: menu = ['clear',['View','view_text'],'sep','copy','paste','help'] if self.enableEdit: menu.insert(2,'edit') else: menu = [['View','view_text'],'sep','copy','editLabel','export','help'] return menu def getActionDef(self,name): if name == 'edit': return dict ( text = self.tr("View/edit sequence"), tip = self.tr('You can cut-n-paste sequence into the widget'), slot = self.showEditor ) else: return CCP4Widgets.CDataFileView.getActionDef(self,name) def showEditor(self,visible=None): if visible is None: visible = not self.widgets['sequence'].isVisible() #print 'CSeqDataFile.showEditor',visible,self.model.exists(),self.widgets['sequence'].model if visible and self.model.exists(): self.model.loadFile() #print 'CSeqDataFile.showEditor after loadFile',repr(self.widgets['sequence'].model),self.widgets['sequence'].model if self.widgets['sequence'].model is None: self.widgets['sequence'].setModel(model.fileContent) self.widgets['sequence'].updateViewFromModel() self.widgets['sequence'].setVisible(visible) def setModel(self,model): CCP4Widgets.CDataFileView.setModel(self,model) if self.widgets.get('sequence',None) is None: return if model is not None: if hasattr(model,'fileContent'): self.widgets['sequence'].setModel(model.fileContent) self.connect(model,QtCore.SIGNAL('dataChanged'),self.loadSequence) self.loadSequence() else: self.widgets['sequence'].setModel(None) def loadSequence(self): if not self.editable: return if self.model.isSet(): try: self.model.loadFile() except: self.model.fileContent.unSet() else: self.model.fileContent.unSet() self.updateViewFromModel() #self.widgets['sequence'].updateViewFromModel() def saveSequence(self): widgetValue = self.widgets['sequence'].widgets['sequence'].getValue() #print 'CSeqDataFileView.saveSequence',widgetValue if widgetValue is None or len(widgetValue.strip())==0: return jobId = self.parentTaskWidget().jobId() self.widgets['sequence'].updateModelFromView() if not self.model.baseName.isSet(): self.model.saveSequence(jobId=jobId) self.validate() else: if self.model.fileContent.sequence.isSet(): # User has a filename set and a sequence set - test if they match fileContent = CCP4ModelData.CSequence() #try: if 1: fileContent.loadFile(str(self.model),format=self.model.__dict__['format']) err = self.model.fileContent.assertSame(fileContent) #print 'CSeqDataFileView.saveSequence',self.model.fileContent,fileContent,err.report() if err.maxSeverity()>SEVERITY_WARNING: mess = QtGui.QMessageBox(self) mess.setWindowTitle('Sequence file') mess.setText('Save sequence or reference data to a new file') mess.addButton('Save to file', QtGui.QMessageBox.AcceptRole) mess.addButton('Keep existing file',QtGui.QMessageBox.ActionRole) mess.addButton('Cancel', QtGui.QMessageBox.RejectRole) mess.show() ret = mess.exec_() if ret == QtGui.QMessageBox.RejectRole: return elif ret == QtGui.QMessageBox.ActionRole: self.model.loadFile() else: self.model.saveSequence(jobId=jobId) self.validate() def validate(self,isValid=None,reportMessage=True): dataFileIsValid = CCP4Widgets.CDataFileView.validate(self,isValid=isValid,reportMessage=reportMessage) if self.editable: try: sequenceIsValid = self.widgets['sequence'].validate(isValid=isValid,reportMessage=reportMessage) if self.model.qualifiers('allowUndefined') and sequenceIsValid.maxSeverity()0 and self.model.fileContent.__dict__['loadWarning'][0]['code'] == 108: import CCP4Utils win = self.makeImportReport('Importing '+str(filename),self.acceptFixedPir) label = QtGui.QLabel(self) label.setText( 'The input file is not correct PIR format but has been fixed and is shown below.\nIf this is still incorrect please correct the file and select it again.\n' + CCP4ModelData.PIR_DESCRIPTION + '\nYour corrected file:') #label.setReadOnly(True) win.layout().insertWidget(0,label) label = QtGui.QTextEdit(self) label.setText(CCP4Utils.readFile(self.model.fileContent.__dict__['loadWarning'][0]['details'])) label.setReadOnly(True) win.layout().insertWidget(1,label) win.show() return elif self.model.fileContent.__dict__['loadWarning'].maxSeverity()>SEVERITY_WARNING: self.model.fileContent.__dict__['loadWarning'].warningMessage(windowTitle='Importing sequence file',parent=self,message='Failed importing sequence file') self.model.unSet() self.updateViewFromModel() return elif len(self.model.__dict__.get('identifiers',[]))>1: #print 'handleBrowserOpenFile drawing idChooser',getattr(self,'idChooser',None) if getattr(self,'idChooser',None) is None: self.idChooser = QtGui.QListWidget(self) self.idChooser.setSelectionMode(QtGui.QListWidget.SingleSelection) win = self.makeImportReport('Importing '+str(filename),self.handleIdChooser) win.layout().insertWidget(0,self.idChooser) win.layout().insertWidget(0,QtGui.QLabel('Select one of the sequences in the file',self)) self.idChooser.clear() for item in self.model.__dict__['identifiers']: self.idChooser.addItem(item) self.idChooser.window().show() self.idChooser.window().raise_() return if self.model.__dict__['format'] is None or self.model.__dict__['format'] != 'internal': #self.model.importFile(jobId=self.parentTaskWidget().jobId(),jobNumber=self.parentTaskWidget().jobNumber()) self.doImportFile() else: self.model.emitDataChanged() # No problems just display it! self.updateViewFromModel() self.validate() def makeImportReport(self,title,callBack=None): win = QtGui.QDialog(self) win.setWindowTitle(title) win.setLayout(QtGui.QVBoxLayout()) line = QtGui.QHBoxLayout() box = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel) win.layout().addLayout(line) line.addStretch(1) line.addWidget(box) line.addStretch(1) if callBack is not None: self.connect(box,QtCore.SIGNAL('clicked ( QAbstractButton * )'),callBack) #self.connect(box,QtCore.SIGNAL('clicked ( QAbstractButton * )'),win.close) return win def doImportFile(self,label=None): if self.model.fileContent.identifier.isSet() and len(self.model.fileContent.identifier)>0: anno = self.model.fileContent.identifier elif label is not None: anno = label+' imported from '+ str(self.model.baseName) else: anno = self.model.qualifiers('guiLabel')+' imported from '+ str(self.model.baseName) #print 'doImportFile anno',anno,'label',label #self.model.blockSignals(True) validatedFile=self.model.fileContent.__dict__.get('validatedFile',None) self.model.importFile(jobId=self.parentTaskWidget().jobId(),annotation=anno,validatedFile=validatedFile,jobNumber=self.parentTaskWidget().jobNumber()) self.model.annotation = anno #self.model.blockSignals(False) self.updateViewFromModel() import CCP4Modules if CCP4Modules.PREFERENCES().AUTO_INFO_ON_FILE_IMPORT and not self.model.dbFileId.isSet(): self.openInfo(label=self.model.qualifiers('guiLabel').lower(),sourceFileAnnotation=self.model.__dict__.get('sourceFileAnnotation','')) def acceptFixedPir(self,but): #print 'CSeqDataFileView.acceptFixedPir',but.text().__str__() if but.text().__str__() == 'Cancel': self.model.unSet() self.updateViewFromModel() else: self.doImportFile() win = but.window() win.close() self.updateViewFromModel() def handleIdChooser(self,but): #print 'CSeqDataFileView.handleIdChooser', but.text().__str__() record = self.idChooser.currentRow() win = but.window() win.setModal(False) win.close() if but.text().__str__() == 'Cancel': self.model.unSet() self.updateViewFromModel() return else: #print 'CSeqDataFileView.handleIdChooser',record; import sys; sys.stdout.flush() self.model.fileContent.loadExternalFile(self.model.__str__(),self.model.__dict__['format'],record=record) self.doImportFile() print 'handleIdChooser',self.model.fileContent.identifier,self.model.fileContent.sequence self.updateViewFromModel() def filterText(self): # make the filters text for QFileDialog to include the alignment extensions textList = [] for desc,extList in [ [CCP4ModelData.CSeqDataFile.QUALIFIERS['mimeTypeDescription'] , CCP4ModelData.EXTLIST ], ]: text = desc + ' (' for ext in extList.keys(): text = text + '*.'+ext+' ' textList.append( text[0:-1]+')' ) return textList ''' This reimplemetation of CDataFileView provides tools for user to merge Refmac dictionary files It is no longer presented on the gui but the issues are handled in the appropriate scripts eg.CPluginScript.mergeDictToProjectLib() is used. class CDictDataFileView(CCP4Widgets.CDataFileView): MODEL_CLASS = CCP4ModelData.CDictDataFile PROJECT_FILE_LABEL = 'Ideal ligand geometry file for project' def __init__(self,parent=None,model=None,qualifiers={},**kw): qualis = {} qualis.update(qualifiers) qualis.update(kw) CCP4Widgets.CDataFileView.__init__(self,parent=parent,model=model,qualifiers=qualis) def getActionDef(self,name): if name == 'manage_dict': return dict ( text = self.tr("View/edit dictionary"), tip = self.tr('View/edit the currently selected dictionary'), slot = self.manageProjectDictionary ) else: return CCP4Widgets.CDataFileView.getActionDef(self,name) def manageProjectDictionary(self): if not hasattr(self,'dictManager'): #self.dictManager = CDictDataDialog(model=self.model.fileContent) self.dictManager = CDictDataDialog(parent=self.parentTaskWidget(),projectId=self.parentTaskWidget().projectId()) self.dictManager.show() self.dictManager.raise_() def handleMerge(self): import CCP4FileBrowser,CCP4Modules self.mergeFileBrowser = CCP4FileBrowser.CFileDialog(parent=self,title='Select dictionary file to merge into project dictionary', defaultSuffix=CCP4Modules.MIMETYPESHANDLER().getMimeTypeInfo(name='application/refmac-dictionary',info='fileExtensions'), fileMode=QtGui.QFileDialog.ExistingFiles,saveButtonText='Merge these files') self.mergeFileBrowser.show() self.connect(self.mergeFileBrowser,QtCore.SIGNAL('selectFiles'),self.mergeFiles) def mergeFiles(self,selectedFiles=[]): # 'CDictDataFileView.mergeFiles',selectedFiles if hasattr(self,'mergeFileBrowser'): self.mergeFileBrowser.close() self.mergeFileBrowser.deleteLater() import CCP4Modules workDirectory = CCP4Modules.PROJECTSMANAGER().jobDirectory( jobId=self.parentTaskWidget().jobId(),projectId=self.parentTaskWidget().projectId()) newFile,err = self.model.mergeInDictFiles(dictFileList=selectedFiles,parentWorkDirectory=workDirectory) for fileName in selectedFiles: err = self.model.fileContent.mergeFile(fileName=fileName,overwrite=True) #print 'CDictDataFileView.mergeFiles',err.report(),err.maxSeverity() if err.maxSeverity()>SEVERITY_WARNING: err.warningMessage(windowTitle='Error merging Refmac dictionaries',parent=self,message='Error attempting to merge Refmac dictionaries') return """ def loadJobCombo(self): CCP4Widgets.CDataFileView.loadJobCombo(self) if self.jobCombo.findText(CDictDataFileView.PROJECT_FILE_LABEL)<0: # Call the defaultProjectDict even though result is not used it will ensure that # a file exists (by creting emptly file if necessary) if self.model is None: return dictFile = self.model.defaultProjectDict(projectId=self.parentTaskWidget().projectId()) self.jobCombo.insertItem(1,CDictDataFileView.PROJECT_FILE_LABEL) self.jobCombo.setCurrentIndex(1) """ def handleFollowFrom(self,contextJobId,projectId): self.jobCombo.setCurrentIndex(1) def handleJobComboChange(self,indx=None): self.connectUpdateViewFromModel(False) if indx is None: indx = 0 if str(self.jobCombo.itemText(indx)) == CDictDataFileView.PROJECT_FILE_LABEL: self.model.set(self.model.defaultProjectDict(projectId=self.parentTaskWidget().projectId())) self.model.annotation = CDictDataFileView.PROJECT_FILE_LABEL else: CCP4Widgets.CDataFileView.handleJobComboChange(self,indx0=indx) ''' class CMonomerView(CCP4Widgets.CComplexLineWidget): MODEL_CLASS = CCP4ModelData.CMonomer def __init__(self,parent=None,model=None,qualifiers={}): qualis = {'gridLayout':True} qualis.update(qualifiers) CCP4Widgets.CComplexLineWidget.__init__(self,parent,qualis) if model is not None: self.setModel(model) self.layout().addWidget(QtGui.QLabel('Identifier:',self),0,1) if self.editable: self.widgets['identifier'] = CCP4Widgets.CStringView(self,qualifiers=qualis) else: self.widgets['identifier'] = CCP4Widgets.CLabel(self,qualifiers=qualis) self.layout().addWidget(self.widgets['identifier'],0,2) self.layout().addWidget(QtGui.QLabel('Formula:',self),0,3) if self.editable: self.widgets['formula'] = CCP4Widgets.CStringView(self,qualifiers=qualis) else: self.widgets['formula'] = CCP4Widgets.CLabel(self,qualifiers=qualis) self.layout().addWidget(self.widgets['formula'],0,4) self.layout().addWidget(QtGui.QLabel('Dictionary name:',self),1,1) if self.editable: self.widgets['dictionaryName'] = CCP4Widgets.CStringView(self,qualifiers=qualis) else: self.widgets['dictionaryName'] = CCP4Widgets.CLabel(self,qualifiers=qualis) self.layout().addWidget(self.widgets['dictionaryName'],1,2) self.layout().addWidget(QtGui.QLabel('Smiles string:',self),1,3) if self.editable: self.widgets['smiles'] = CCP4Widgets.CStringView(self,qualifiers=qualis) else: self.widgets['smiles'] = CCP4Widgets.CLabel(self,qualifiers=qualis) self.layout().addWidget(self.widgets['smiles'],1,4) ''' toolTip = self.model.qualifiers('toolTip') if toolTip is NotImplemented: toolTip = '' else: toolTip = toolTip for item in self.model.CONTENTS_ORDER: widget = self.widgets[item] tT = self.model.getDataObjects(item).qualifiers('toolTip') if tT is NotImplemented: tT = '' widget.setToolTip(toolTip+tT) if self.editable: self.connect(widget,QtCore.SIGNAL(widget.editSignal()),self.updateModelFromView) self.connect(widget,QtCore.SIGNAL('acceptDropData'),self.acceptDropData) ''' class CPdbEnsembleItemView(CCP4Widgets.CComplexLineWidget): MODEL_CLASS = CCP4ModelData.CPdbEnsembleItem def __init__(self,parent=None,model=None,qualifiers={}): qualis = {'vboxLayout':True,'iconButton':False} qualis.update(qualifiers) CCP4Widgets.CComplexLineWidget.__init__(self,parent,qualis) if model is not None: self.setModel(model) self.widgets = {} self.widgets['structure'] = CPdbDataFileView(self,qualifiers={'iconButton':True,'iconName':'PdbDataFile','ifAtomSelection' : True}) self.layout().addWidget(self.widgets['structure']) self.widgets['identity_to_target'] = CCP4Widgets.CFloatView(self) self.widgets['rms_to_target'] = CCP4Widgets.CFloatView(self) self.widgets['number'] = CCP4Widgets.CIntView(self, qualifiers = { 'editable' : self.editable, 'guiMode' : 'combo', 'enumerators' : [i for i in range(21)], 'menuText' : [str(i) for i in range(21)]}) self.widgets['number'].setMaximumWidth(60) line = QtGui.QHBoxLayout() line.addWidget(QtGui.QLabel('Copies:',self)) line.addWidget(self.widgets['number']) line.addWidget(QtGui.QLabel('Sequence identity:',self)) line.addWidget(self.widgets['identity_to_target']) line.addWidget(QtGui.QLabel('OR RMS difference:',self)) line.addWidget(self.widgets['rms_to_target']) self.layout().addLayout(line) def setModel(self, model): ensemble = None if model is not None and hasattr(model,'parent') and model.parent() is not None: ensemble = model.parent().parent() cEnsembleLabelView = self.parent().findChildren(CEnsembleLabelView)[0] if self.model is not None: for item in ['structure','identity_to_target','rms_to_target']: self.disconnect(self.model.get(item),QtCore.SIGNAL('dataChanged'),self.validate) if ensemble is not None: for item in ['number']: self.disconnect(ensemble.get(item),QtCore.SIGNAL('dataChanged'),self.numberChanged) if model is None or isinstance(model,self.MODEL_CLASS): from CCP4Widgets import CViewWidget CViewWidget.setModel(self,model) if model is not None: self.connect(model,QtCore.SIGNAL('dataChanged'),self.validate) toolTip = model.qualifiers('toolTip') if toolTip is not NotImplemented and toolTip is not None and self.iconButton is not None: self.iconButton.setToolTip(toolTip+'\n'+self.iconButton.toolTip()) for key,w in self.widgets.items(): if key in ['structure','identity_to_target','rms_to_target']: if isinstance(w,CViewWidget): w.setModel(model.get(key)) elif key in ['number']: if ensemble is not None: if isinstance(w,CViewWidget): w.setModel(ensemble.get(key)) else: for key,w in self.widgets.items(): if isinstance(w,CViewWidget): w.setModel(None) # Set allowUndefined True for the first CPdbEnsembleItem in the first CEnsemble where the CEnsembleList # is allowed zero length if model is not None and ensemble is not None: if isinstance(ensemble,CCP4ModelData.CEnsemble) and ensemble.qualifiers('allowUndefined'): if model.parent().index(model) == 0: model.setQualifier('allowUndefined',True) model.structure.setQualifier('allowUndefined',True) if model is not None and self.editable: for item in ['structure','identity_to_target','rms_to_target']: self.connect(model.get(item),QtCore.SIGNAL('dataChanged'),self.validate) for item in ['number']: if ensemble is not None: self.connect(ensemble.get(item),QtCore.SIGNAL('dataChanged'),self.numberChanged) if self.widgets['structure'].widgets.get('selection',None) is None: self.widgets['structure'].showAtomSelection() def updateViewFromModel(self): for key,widget in self.widgets.items(): widget.updateViewFromModel() #self.parent().findChildren(CEnsembleLabelView)[0].updateViewFromModel() def numberChanged(self, **kw): cEnsembleLabelView = self.parent().findChildren(CEnsembleLabelView)[0] self.parent().parent().updateViewFromModel(**kw) cEnsembleLabelView.validate() ''' def getMenuDef(self): return self.widgets['structure'].getMenuDef() def getActionDef(self,name): return self.widgets['structure'].getActionDef(name) def showAtomSelection(self): self.widgets['structure'].showAtomSelection() def viewContents(self): self.widgets['structure'].viewContents() ''' class CEnsembleView(CCP4Widgets.CComplexLineWidget): def __init__(self,parent=None,model=None,qualifiers={}): qualis = {'vboxLayout':True} qualis.update(qualifiers) CCP4Widgets.CComplexLineWidget.__init__(self,parent,qualis) if model is not None: self.setModel(model) self.widgets = {} line = QtGui.QHBoxLayout() iconWidgetItem = self.layout().takeAt(0) line.addWidget(iconWidgetItem.widget()) line.addWidget(QtGui.QLabel('Label for ensemble:',self)) self.widgets['label'] = CCP4Widgets.CStringView(self) line.addWidget(self.widgets['label']) self.layout().addLayout(line) self.widgets['pdbItemList'] = CCP4Widgets.CListView(self,model=self.model.pdbItemList,qualifiers={ 'editable' : self.editable, 'mode' : 'table', 'tableItems': ['structure','identity_to_target','rms_to_target'], 'columnHeaders':['Filename','Identity','RMS'] }) self.layout().addWidget(self.widgets['pdbItemList']) class CEnsembleLabelView(CCP4Widgets.CComplexLineWidget): MODEL_CLASS = CCP4ModelData.CEnsemble def __init__(self,parent=None,model=None,qualifiers={}): CCP4Widgets.CComplexLineWidget.__init__(self,parent,qualifiers=qualifiers) self.widgets['use'] = CCP4Widgets.CBooleanView(self, qualifiers = { 'editable' : self.editable } ) self.widgets['number'] = CCP4Widgets.CIntView(self, qualifiers = { 'editable' : self.editable, 'guiMode' : 'combo', 'enumerators' : [i for i in range(21)], 'menuText' : [str(i) for i in range(21)]}) self.widgets['number'].setMaximumWidth(60) self.widgets['label'] = CCP4Widgets.CStringView(self, qualifiers = { 'editable' : self.editable } ) self.layout().addWidget( self.widgets['use'] ) self.layout().addWidget(QtGui.QLabel('Find',self)) self.layout().addWidget( self.widgets['number'] ) self.layout().addWidget(QtGui.QLabel('of search ensemble called',self)) self.layout().addWidget( self.widgets['label'] ) self.setModel(model) def validate(self,isValid=None,reportMessage=True): # Just validate the number and label if isValid is None: if self.model is None: isValid = False else: v = self.model.number.validity(self.model.number.get()) v.extend(self.model.label.validity(self.model.label.get())) isValid = (v.maxSeverity()<=SEVERITY_WARNING) CCP4Widgets.CComplexLineWidget.validate(self,isValid=isValid,reportMessage=reportMessage) class CEnsembleListView(CCP4Widgets.CTreeView): MODEL_CLASS = CCP4ModelData.CEnsembleList def __init__(self,parent=None,model=None,qualifiers={}): displayRole = QtCore.Qt.DisplayRole qualis = { 'editors' : [ { 'modelClass' : CCP4ModelData.CEnsemble, 'name' : 'ensemble', 'label':'ensemble' } , { 'modelClass' : CCP4ModelData.CPdbEnsembleItem , 'name' : 'pdbEnsembleItem','label':'structure in ensemble' } ], 'columnHeaders':[ {displayRole:'Ensemble/Filename','width':240}, {displayRole:'Selection','width':240}, {displayRole:'Identity','width':50}, {displayRole:'RMS','width':50} ] } """ 'hierarchy' : [ {'name':'self','label':'ensemble','editorClass':CEnsembleLabelView, 'grey':True, 'list': [{'name':'pdbItemList','label':'structure in ensemble','editorClass':CPdbEnsembleItemView }] } ], """ #print 'INTO CEnsembleListView',model qualis.update(qualifiers) super(CEnsembleListView,self).__init__(parent,model=model,qualifiers=qualis) class CPdbDataFileView(CCP4Widgets.CDataFileView): MODEL_CLASS = CCP4ModelData.CPdbDataFile def __init__(self,parent=None,model=None,qualifiers={}): self.ifAtomSelection = qualifiers.get('ifAtomSelection',False) qualis = { 'vboxLayout' : True } qualis.update(qualifiers) #print 'CPdbDataFileView parent',parent #CCP4Widgets.CDataFileView.__init__(self,parent=parent,model=model,qualifiers=qualis) super(CPdbDataFileView,self).__init__(parent=parent,model=model,qualifiers=qualis) #if self.ifAtomSelection: self.showAtomSelection() def getMenuDef(self): if self.editable: #menu = ['clear','view','annotate','sep','copy','paste','help'] menu = ['clear',['View','quick_view','view_text','view_CCP4mg','view_Coot','view_PdbView'],'sep','copy','paste','help'] if self.ifAtomSelection: menu.insert(menu.index('sep'),'select') else: if self.role is not None and self.role == 'output': menu = [['View','quick_view','view_text','view_CCP4mg','view_Coot','view_PdbView'],'sep','copy','editLabel','export','help'] else: menu = [['View','quick_view','view_text','view_CCP4mg','view_Coot','view_PdbView'],'sep','copy','export','help'] if self._stacked: menu.insert(0,'handleStack') if self.ifInfo: menu.insert(menu.index('sep'),'annotate') return menu def getActionDef(self,name): if name == 'select': def iC(): try: return self.widgets['selection'].isVisible() except: return False return dict ( text = self.tr("Select atoms"), tip = self.tr('Select limited set of atoms'), slot = self.showAtomSelection, checkable = True, isChecked = iC ) elif name == 'quick_view': def e(): return (self.model is not None and self.model.exists()) return dict ( text = self.tr("Quick view"), tip = self.tr('Quick view of model data'), slot = self.viewContents, enabled = e ) else: return CCP4Widgets.CDataFileView.getActionDef(self,name) def openViewer(self,mode): import CCP4Modules if mode == 'view_text': CCP4Modules.WEBBROWSER().openFile(fileName=self.model.__str__(),toFront=True) else: CCP4Widgets.CDataFileView.openViewer(self,mode) def setModel(self,model=None): #print 'CPdbDataFileView.setModel',repr(model),self.widgets.has_key('selection') #if model is not None: print model.objectName() if self.model is not None and self.widgets.has_key('selection'): self.disconnect(self.model,QtCore.SIGNAL('dataChanged'),self.widgets['selection'].applySelection) super(CPdbDataFileView,self).setModel(model=model) if self.ifAtomSelection and model is not None: if 'selection' in self.widgets: self.widgets['selection'].setModel(model.selection) self.widgets['selection'].updateViewFromModel() elif model is not None and model.selection.isSet(): if 'selection' not in self.widgets: self.showAtomSelection() self.widgets['selection'].setModel(model.selection) self.widgets['selection'].updateViewFromModel() def getValue(self): val = CCP4Widgets.CDataFileView.getValue(self) if getattr(self,'selectionLine',None) is not None: val['selection'] = self.widgets['selection'].getValue() #print 'CPdbDataFileView.getValue',val return val def setValue(self,value): #print 'CPdbDataFileView.setValue',self.model.objectName(),value CCP4Widgets.CDataFileView.setValue(self,value) if value.get('selection',None) is not None: self.showAtomSelection() self.widgets['selection'].setValue(value.get('selection',{})) elif getattr(self,'selectionLine',None) is not None: self.widgets['selection'].clear() else: return self.widgets['selection'].applySelection() def showAtomSelection(self): #print 'CPdbDataFileView.showAtomSelection' import sys,os import CCP4Utils if self.widgets.get('selection',None) is None: self.selectionLine = QtGui.QFrame(self) self.selectionLine.setLayout(QtGui.QHBoxLayout()) self.selectionLine.layout().setSpacing(0) self.selectionLine.layout().setContentsMargins(0,0,0,0) self.selectionLine.layout().addWidget(QtGui.QLabel('Atom selection')) selection = None if hasattr(self,'model') and self.model is not None: selection = self.model.selection self.widgets['selection'] = CAtomSelectionView(parent=self,model=selection, qualifiers= { 'editable' :self.editable} ) if hasattr(self,'model') and self.model is not None: self.connect(self.model,QtCore.SIGNAL('dataChanged'),self.widgets['selection'].applySelection) self.selectionLine.layout().addWidget(self.widgets['selection']) self.layout().addWidget(self.selectionLine) simpleSelectionsCheck = QtGui.QCheckBox('Simple selections ...') self.layout().addWidget(simpleSelectionsCheck) expanded_cb_path = os.path.abspath(os.path.join(CCP4Utils.getCCP4I2Dir(),'qticons','toc-minus.png')) unexpanded_cb_path = os.path.abspath(os.path.join(CCP4Utils.getCCP4I2Dir(),'qticons','toc-plus.png')) expandStyle = """ QCheckBox::indicator:unchecked { image: url("""+unexpanded_cb_path+"""); } QCheckBox::indicator:checked { image: url("""+expanded_cb_path+"""); } """ simpleSelectionsCheck.setStyleSheet(expandStyle) self.selectionTypes = QtGui.QFrame(self) self.layout().addWidget(self.selectionTypes) self.chainsWidget = QtGui.QFrame(self) self.layout().addWidget(self.chainsWidget) if self.editable: self.selectionTypes.setLayout(QtGui.QGridLayout()) self.chainsWidget.setLayout(QtGui.QGridLayout()) self.selectionTypes.layout().addWidget(QtGui.QLabel('Residue types'),0,0) peptideWidget = QtGui.QCheckBox('Peptide') nucleicWidget = QtGui.QCheckBox('Nucleic acid') ligandWidget = QtGui.QCheckBox('Ligands') waterWidget = QtGui.QCheckBox('Water') soluteWidget = QtGui.QCheckBox('Solute') saccharideWidget = QtGui.QCheckBox('Saccharide') nucleotideWidget = QtGui.QCheckBox('Nucleotide') metalWidget = QtGui.QCheckBox('Metal') def interpretSimpleSelections(): sel = '' if peptideWidget.isChecked(): sel += 'peptide' if nucleicWidget.isChecked(): if len(sel)>0: sel += ' or nucleic' else: sel = 'nucleic' if ligandWidget.isChecked(): if len(sel)>0: sel += ' or ligands' else: sel = 'ligands' if waterWidget.isChecked(): if len(sel)>0: sel += ' or water' else: sel = 'water' if soluteWidget.isChecked(): if len(sel)>0: sel += ' or solute' else: sel = 'solute' if saccharideWidget.isChecked(): if len(sel)>0: sel += ' or saccharide' else: sel = 'saccharide' if nucleotideWidget.isChecked(): if len(sel)>0: sel += ' or nucleotide' else: sel = 'nucleotide' if metalWidget.isChecked(): if len(sel)>0: sel += ' or metal' else: sel = 'metal' chains = self.chainsWidget.findChildren(QtGui.QCheckBox) chainsel = '' for ch in chains: #print ch.isChecked(), ch.text() if ch.isChecked(): if len(chainsel)>0: chainsel += " or " + str(ch.text())+"/" else: chainsel = str(ch.text())+"/" #print chainsel; sys.stdout.flush() if len(chainsel)>0 and len(sel)>0: sel = "{"+sel+"} and {"+chainsel+"}" elif len(sel)==0 and len(chainsel)>0: sel = chainsel val = {'selection':{'text':sel}} CCP4Widgets.CDataFileView.setValue(self,val) self.widgets['selection'].setValue(val) self.widgets['selection'].applySelection() # Surely should not have to do this? But applySelection0 seems not to work... self.widgets['selection'].connectUpdateViewFromModel(False) self.widgets['selection'].model.text.set(sel) self.widgets['selection'].connectUpdateViewFromModel(True) peptideWidget.stateChanged.connect(interpretSimpleSelections) nucleicWidget.stateChanged.connect(interpretSimpleSelections) ligandWidget.stateChanged.connect(interpretSimpleSelections) waterWidget.stateChanged.connect(interpretSimpleSelections) soluteWidget.stateChanged.connect(interpretSimpleSelections) saccharideWidget.stateChanged.connect(interpretSimpleSelections) nucleotideWidget.stateChanged.connect(interpretSimpleSelections) metalWidget.stateChanged.connect(interpretSimpleSelections) self.selectionTypes.layout().addWidget(peptideWidget,1,0) self.selectionTypes.layout().addWidget(nucleicWidget,2,0) self.selectionTypes.layout().addWidget(ligandWidget,3,0) self.selectionTypes.layout().addWidget(waterWidget,4,0) self.selectionTypes.layout().addWidget(soluteWidget,1,1) self.selectionTypes.layout().addWidget(saccharideWidget,2,1) self.selectionTypes.layout().addWidget(metalWidget,3,1) self.selectionTypes.layout().addWidget(nucleotideWidget,4,1) def fillChainsWidget(): #print "fillChainsWidget"; sys.stdout.flush() if hasattr(self,"model") and hasattr(self.model,"fileContent") and hasattr(self.model.fileContent,"composition") and hasattr(self.model.fileContent.composition,"chains"): if len(self.model.fileContent.composition.chains)<30: # and len(self.model.fileContent.composition.chains)>1: self.chainsWidget.layout().addWidget(QtGui.QLabel('Chains'),0,0) for i in range(len(self.model.fileContent.composition.chains)): col = i / 8 row = i % 8 + 1 chainWidget = QtGui.QCheckBox(self.model.fileContent.composition.chains[i]) self.chainsWidget.layout().addWidget(chainWidget,row,col) chainWidget.stateChanged.connect(interpretSimpleSelections) fillChainsWidget() def clearLayout(layout): #print "clearLayout"; sys.stdout.flush() #print self.model.fileContent.molHnd while layout.count(): child = layout.takeAt(0) if child.widget(): child.widget().deleteLater() def dataIsChanged(): #print "dataIsChanged"; sys.stdout.flush() if not self.model.fileContent.molHnd is self._old_molHnd: clearLayout(self.chainsWidget.layout()) fillChainsWidget() self._old_molHnd = self.model.fileContent.molHnd if hasattr(self,"model") and hasattr(self.model,"fileContent") and hasattr(self.model.fileContent,"composition") and hasattr(self.model.fileContent.composition,"chains"): self._old_molHnd = self.model.fileContent.molHnd else: self._old_molHnd = None self.connect(self.model,QtCore.SIGNAL('dataChanged'),dataIsChanged) elif not self.widgets['selection'].isVisible() and simpleSelectionsCheck.isChecked(): self.selectionLine.show() self.selectionTypes.show() self.chainsWidget.show() else: self.selectionLine.hide() self.selectionTypes.hide() self.chainsWidget.hide() simpleSelectionsCheck.hide() simpleSelectionsCheck.clicked.connect(self.selectionTypes.setVisible) simpleSelectionsCheck.clicked.connect(self.chainsWidget.setVisible) self.selectionTypes.hide() self.chainsWidget.hide() def viewContents(self): if not hasattr(self,'contentsViewer'): self.contentsViewer = CPdbContentsViewer(self) try: fileContent = self.model.fileContent except: pass self.connect(self.model.fileContent,QtCore.SIGNAL('dataChanged'),self.contentsViewer.load) self.contentsViewer.load() self.contentsViewer.show() def setFocus1(self,reason,index=None): #print 'CPdbDataFileView.setFocus1',index if index is None: CCP4Widgets.CDataFileView.setFocus(self,reason) elif index==1 and self.ifAtomSelection: self.showAtomSelection() self.selectionLine.setFocus(reason) else: self.jobCombo.setFocus(reason) def handleBrowserOpenFile(self,filename,downloadInfo,**kw): kw['validate'] = False kw['updateView'] = False CCP4Widgets.CDataFileView.handleBrowserOpenFile(self,filename,downloadInfo,**kw) err = self.model.importFile(jobId=self.parentTaskWidget().jobId(),jobNumber=self.parentTaskWidget().jobNumber()) if err is not None and len(err)>0: if err.maxSeverity()>SEVERITY_WARNING: message = 'File failed validation test' err.warningMessage(windowTitle='Importing coordinate file',parent=self,message=message) self.model.unSet() self.updateViewFromModel() self.validate() class CPdbContentsViewer(QtGui.QDialog): def __init__(self,parent): QtGui.QDialog.__init__(self,parent) self.setLayout(QtGui.QVBoxLayout()) self.textEdit = QtGui.QTextEdit(self) self.textEdit.setReadOnly(True) self.layout().addWidget(self.textEdit) butBox = QtGui.QDialogButtonBox(self) self.layout().addWidget(butBox) but = butBox.addButton(QtGui.QDialogButtonBox.Close) self.connect(but,QtCore.SIGNAL('released()'),self.close) def load(self): #print 'CPdbContentsViewer.load', self.parent().model.fileContent.composition.chains self.textEdit.setReadOnly(False) self.textEdit.clear() if self.parent().model.annotation.isSet(): self.setWindowTitle(self.parent().model.annotation.__str__()) else: self.setWindowTitle(self.parent().model.__str__()) text = '\nSpace group: ' + str(self.parent().model.fileContent.mmdbManager.GetSpaceGroup()) try: cell = self.parent().model.fileContent.mmdbManager.GetCell() text = text + '\nCell:' for ii in range(1,7): text = text + ' ' + str(cell[ii]) except: pass if len( self.parent().model.fileContent.composition.chains)>0: text = text + '\n\nChains in model:\n' comp = self.parent().model.fileContent.composition for i in range(len(comp.chains)): text = text + str(comp.chains[i])+ ' ' + comp.chainInfo[i][1].split('/')[3] + ' - ' + comp.chainInfo[i][2].split('/')[3] + \ ' ('+str(comp.chainInfo[i][0]) +' residues)\n' if len( self.parent().model.fileContent.composition.monomers)>0: text = text + '\n\nMonomers in model:\n'+self.parent().model.fileContent.composition.monomers[0] for mon in self.parent().model.fileContent.composition.monomers[1:]: text = text + ', ' + str(mon) self.textEdit.document().setPlainText(text) self.textEdit.setReadOnly(True) class CPdbDataFileListView(CCP4Widgets.CListView): MODEL_CLASS = CCP4ModelData.CPdbDataFileList def __init__(self,parent=None,model=None,qualifiers={}): #print 'CPdbDataFileListView' qualis = { 'mode' : 'table', 'tableItems' : ['fullPath','selection'] , 'columnHeaders':['Coordinate file','Selection'], } qualis.update(qualifiers) CCP4Widgets.CListView.__init__(self,parent,model=model,qualifiers=qualis) # Tis broke! self.editor.showAtomSelection() class CAtomSelectionView(CCP4Widgets.CComplexLineWidget): MODEL_CLASS = CCP4ModelData.CAtomSelection ERROR_CODES = { 101 : { 'description' : 'No CPdbDataFile when applying atom selection' }, 102 : { 'description' : 'Error applying atom selection' } } def __init__(self,parent=None,model=None,qualifiers={}): super(CAtomSelectionView,self).__init__(parent=parent,qualifiers=qualifiers) if self.editable: self.widgets['text'] = CCP4Widgets.CLineEdit(self) self.widgets['text'].setToolTip("Enter selection command e.g. 'A/ or B/11-21'") self.setFocusProxy(self.widgets['text']) else: self.widgets['text'] = CCP4Widgets.CLabel(self) self.layout().addWidget(self.widgets['text']) self.label = QtGui.QLabel(' ( 0 atoms)',self) self.layout().addWidget(self.label) self.help = QtGui.QPushButton('Help',self) self.help.setToolTip('Details of atom selection syntax') self.layout().addWidget(self.help) self.connect(self.widgets['text'],QtCore.SIGNAL('textEdited(const QString &)'),self.applySelection0) self.connect(self.help,QtCore.SIGNAL('released()'),self.showHelp) if self.parent().model is not None: self.connect(self.parent().model,QtCore.SIGNAL('dataLoaded'),self.applySelection) if model is not None: self.setModel(model) self.updateViewFromModel() def validate(self,isValid=None,reportMessage=True): pass def showHelp(self): import CCP4Modules CCP4Modules.WEBBROWSER().loadWebPage(helpFileName='general/atom_selection.html') def setValue(self,value={}): CCP4Widgets.CComplexLineWidget.setValue(self,value=value) try: self.applySelection() except: self.label.setText('No atoms') def updateViewFromModel(self): #print 'CAtomSelectionView.updateViewFromModel' #import traceback #traceback.print_stack(limit=10) self.widgets['text'].blockSignals(True) self.widgets['text'].setText(self.model.__str__()) self.widgets['text'].blockSignals(False) try: self.applySelection() except: self.label.setText('No atoms') def clear(self): CCP4Widgets.CComplexLineWidget.clear(self) self.widgets['text'].clear() self.label.setText('No atoms') def applySelection0(self,text=None): try: self.applySelection(text=text) except: pass else: self.connectUpdateViewFromModel(False) self.model.text.set(text) self.connectUpdateViewFromModel(True) def applySelection(self,text=None): #print 'CSelectionLine.applySelection',text if text is None: text = self.widgets['text'].text() if isinstance(self.model.parent(),CCP4ModelData.CPdbDataFile): pdbDataObj = self.model.parent() else: pdbDataObj = self.model.getDataByKey('pdbFileKey') #print 'CSelectionLine.applySelection',text,pdbDataObj if pdbDataObj is None: try: pdbDataObj = self.model.parent() except: self.label.setText('No atoms') raise CException(self.__class__,101,name=self.modelObjectPath()) try: # Call to loadFile removed from here - CPdbDataFile.updateData() unsets fileContent # so this accessing fileContent should cause a loadFile() if necessasy nSelAtoms,selHnd = pdbDataObj.fileContent.interpretSelection(str(text)) if selHnd is not None: pdbDataObj.fileContent.molHnd.DeleteSelection(selHnd) except Exception as e: #print 'CSelectionLine.applySelection loadFile fail\n',e self.label.setText('No atoms') raise CException(self.__class__,102,name=self.modelObjectPath()) self.label.setText(' ( '+str(nSelAtoms)+' atoms)') if nSelAtoms == 0: self.setProperty("isValid",False) self.setProperty("hasWarning",True) self.isValid = False self.validityMessage = 'No atoms selected' else: self.setProperty("isValid",True) self.setProperty("hasWarning",False) self.isValid = True self.validityMessage = None self.updateValidityIndicator() class CDictDataDialog(QtGui.QDialog): def __init__(self,parent=None,model=None,projectId=None): import CCP4Modules if parent is None: parent = CCP4Modules.QTAPPLICATION() QtGui.QDialog. __init__(self,parent) self.setLayout(QtGui.QHBoxLayout()) self.setModal(False) if projectId is not None: pName = ' for '+CCP4Modules.PROJECTSMANAGER().db().getProjectInfo(projectId=projectId,mode='projectname') else: pName='' self.setWindowTitle('Manage project dictionary'+pName) self.frame = CDictDataView(self,model=model,projectId=projectId) self.layout().addWidget(self.frame) def closeEvent(self,event): import CCP4Utils,CCP4Modules #print 'CDictDataDialog.closeEvent',self.frame.showWidget if self.frame.showWidget is not None and CCP4Utils.isAlive(self.frame.showWidget): CCP4Modules.WEBBROWSER().tab().deleteTabWidget(widget=self.frame.showWidget) event.accept() class CDictDataView(CCP4Widgets.CViewWidget): def __init__(self,parent=None,model=None,projectId=None): CCP4Widgets.CViewWidget.__init__(self,parent=parent) self.showWidget = None if model is None: self.dictDataFile = CCP4ModelData.CDictDataFile() #self.dictDataFile.set(self.dictDataFile.defaultProjectDict(projectId=projectId)) self.dictDataFile.loadFile() self.model = self.dictDataFile.fileContent import CCP4ProjectViewer import os CCP4ProjectViewer.FILEWATCHER().addJobPath(os.path.split( os.path.split(str(self.dictDataFile))[0])[1],self.dictDataFile.__str__()) self.connect(CCP4ProjectViewer.FILEWATCHER(),QtCore.SIGNAL('fileChanged(const QString &)'),self.handleFileChanged) else: self.model = model self.dictDataFile = model.parent() #print 'CDictDataView',self.dictDataFile,self.model,self.model.monomerList QtGui.QFrame.__init__(self,parent) self.setLayout(QtGui.QHBoxLayout()) self.layout().setContentsMargins(1,1,1,1) self.layout().setSpacing(1) self.monomerListWidget = CDictDataList(self) self.layout().addWidget(self.monomerListWidget ) butLayout = QtGui.QVBoxLayout() for label,connect in [['Show',self.handleShow],['Import geometry file',self.handleMerge],['Delete',self.handleDelete]]: but = QtGui.QPushButton(label,self) self.connect(but,QtCore.SIGNAL('released()'),connect) butLayout.addWidget(but) self.layout().addLayout(butLayout) self.updateViewFromModel() self.connect(self.model,QtCore.SIGNAL('dataChanged'),self.updateViewFromModel) self.connect(self.monomerListWidget,QtCore.SIGNAL('itemDoubleClicked(QTreeWidgetItem *,int)'),self.handlDoubleClick) def handleFileChanged(self,path): #print 'CDictDataView.handleFileChanged',path if str(path) == str(self.dictDataFile): #print 'CDictDataView.handleFileChanged updating' self.dictDataFile.fileContent.loadFile(str(self.dictDataFile)) self.updateViewFromModel() def handlDoubleClick(self,item,col): #print 'CDictDataView.handlDoubleClick',item,col idd = item.data(0).toStrint().__str__() self.handleShow(idd) def updateViewFromModel(self): import CCP4Utils self.monomerListWidget.load(self.model.monomerList) if self.showWidget is not None and CCP4Utils.isAlive(self.showWidget): self.showWidget.reload() def updateModelFromView(self): # All updates should be handled by the edit methods pass def handleShow(self,idd=None): if idd is None: idd = self.monomerListWidget.currentSelection() import CCP4Modules,CCP4Utils #print 'CDictDataView.handleShow',idd,self.model,self.model.parent() if self.showWidget is not None: print 'alive?',CCP4Utils.isAlive(self.showWidget) if self.showWidget is None or (not CCP4Utils.isAlive(self.showWidget)): self.showWidget = CCP4Modules.WEBBROWSER().openFile(self.model.parent().__str__()) else: self.showWidget.browserWindow().show() self.showWidget.browserWindow().raise_() if idd is not None: self.showWidget.findText(subString='data_comp_'+idd) def handleMerge(self): import CCP4FileBrowser,CCP4Modules self.mergeFileBrowser = CCP4FileBrowser.CFileDialog(parent=self,title='Select geometry file to merge into project geometry file', defaultSuffix=CCP4Modules.MIMETYPESHANDLER().getMimeTypeInfo(name='application/refmac-dictionary',info='fileExtensions'), filters = ['Geometry file for refinement(*.cif)'], fileMode=QtGui.QFileDialog.ExistingFiles,saveButtonText='Merge these files') self.mergeFileBrowser.show() self.connect(self.mergeFileBrowser,QtCore.SIGNAL('selectFiles'),self.mergeFiles) def mergeFiles(self,selectedFiles): if hasattr(self,'mergeFileBrowser'): self.mergeFileBrowser.close() self.mergeFileBrowser.deleteLater() #print 'CDictDataFileView.mergeFiles',selectedFiles for fileName in selectedFiles: err = self.model.mergeFile(fileName=fileName,overwrite=True) #print 'CDictDataFileView.mergeFiles',err.report(),err.maxSeverity() if err.maxSeverity()>SEVERITY_WARNING: err.warningMessage(windowTitle='Error merging geometry files',parent=self,message='Error attempting to merge geometry files') return def handleDelete(self): idd = self.monomerListWidget.currentSelection() #print 'CDictDataView.handleDelete',idd if idd is None: return err = self.model.delete(idd) if err.maxSeverity()>SEVERITY_WARNING: err.warningMessage(windowTitle='Error deleting item in geometry file',parent=self,message='Error attempting to edit geometry file') return class CDictDataList(QtGui.QTreeWidget): def __init__(self,parent): QtGui.QTreeWidget.__init__(self,parent) self.setMinimumWidth(400) self.setColumnCount(3) self.setHeaderLabels(['Id','Code','Name']) self.setColumnWidth(0,80) self.setColumnWidth(1,80) self.setColumnWidth(2,200) self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) def load(self,monomerList): # monomerList is a Clist of CChemComp #print 'CDictDataList.load',monomerList self.clear() for monomer in monomerList: #print 'CDictDataList.load',monomer.get('id') qList = QtCore.QStringList() for item in ['id','three_letter_code','name']: qList.append(str(monomer.get(item))) item = QtGui.QTreeWidgetItem(qList) treeId=self.addTopLevelItem(item) def handleMonomerDeleted(self,id): #print 'CDictDataList.handleMonomerDeleted',id if self.model().rowCount()==0: return modInxList = self.model().match(id) if len(modInxList)==0: #print 'CDictDataList.handleMonomerDeleted no match to id',id pass else: self.model().removeRow(modInxList[0].row()) def handleMonomerAdded(self,id): pass def currentSelection(self): indices = self.selectionModel().selectedRows() if len(indices) == 0: return None idd = str(indices[0].data().toString()) return idd class CSeqEdit(CCP4Widgets.CTextEdit): def __init__(self,parent): CCP4Widgets.CTextEdit.__init__(self,parent) self.setStyleSheet("CSeqEdit { font-family: Courier ;}") def setValue(self,text): if text is None: CCP4Widgets.CTextEdit.setValue(self,'') return nGap = 10 nLine = 60 seqList = [] while len(text)>0: line = text[0:nLine] text = text[nLine:] while len(line)>0: seqList.append(line[0:nGap]+' ') line = line[nGap:] seqList[-1] = seqList[-1]+'\n' newText = '' newText = newText.join(seqList) CCP4Widgets.CTextEdit.setValue(self,newText) def getValue(self): text = CCP4Widgets.CTextEdit.getValue(self) newText = CCP4ModelData.CAsuContentSeq().cleanupSequence(text) #print 'CSeqEdit.getValue',newText return newText class CAsuContentSeqView(CCP4Widgets.CComplexLineWidget): MODEL_CLASS = CCP4ModelData.CAsuContentSeq ERROR_CODES = { 101 : { 'description' : 'There is no valid sequence name' }, 102 : { 'description' : 'There is no valid sequence' } } def __init__(self,parent=None,model=None,qualifiers={}): import functools import CCP4Modules qualis = {} qualis.update(qualifiers) qualis['vboxLayout'] = True CCP4Widgets.CComplexLineWidget.__init__(self,parent=parent,qualifiers=qualis) w = self.layout().takeAt(0).widget() self.widgets['nCopies'] = CCP4Widgets.CIntView(self,qualifiers={ 'editable' : True, 'enumerators':[0,1,2,3,4,5,6,7,8,9,10,11,12] } ) self.widgets['nCopies'].setToolTip("The expected number of copies of the sequence") print 'CAsuContentSeqView nCopies insertPolicy',self.widgets['nCopies'].widget.insertPolicy() self.widgets['name'] = CCP4Widgets.CLineEdit(self) self.widgets['name'].setToolTip("A name for the seqeunce") self.connect(self.widgets['name'],QtCore.SIGNAL('editingFinished()'),self.updateModelFromView) self.widgets['description'] = CCP4Widgets.CLineEdit(self) self.widgets['description'].setToolTip("A name for the seqeunce") self.connect(self.widgets['description'],QtCore.SIGNAL('editingFinished()'),self.updateModelFromView) self.widgets['sequence'] = CSeqEdit(self) self.widgets['sequence'].setToolTip("Paste sequence into this window") self.connect(self.widgets['sequence'],QtCore.SIGNAL('textChanged()'),self.updateModelFromView) line = QtGui.QHBoxLayout() line.addWidget(w) line.addWidget(self.widgets['nCopies']) line.addWidget(QtGui.QLabel('copies in asymmetric unit of chain named',self)) line.addWidget(self.widgets['name']) self.layout().addLayout(line) line = QtGui.QHBoxLayout() line.addWidget(QtGui.QLabel('Description:',self)) line.addWidget(self.widgets['description']) self.layout().addLayout(line) self.layout().addWidget(self.widgets['sequence']) line = QtGui.QHBoxLayout() line.addWidget(QtGui.QLabel('Load sequence from',self)) but =QtGui.QPushButton('Sequence file',self) self.connect(but,QtCore.SIGNAL('clicked()'),functools.partial(self.loadFile,'sequence')) line.addWidget(but) but =QtGui.QPushButton('Coordinate file',self) self.connect(but,QtCore.SIGNAL('clicked()'),functools.partial(self.loadFile,'coords')) line.addWidget(but) self.layout().addLayout(line) # Allow using an already imported sequence file self.seqObjLine = QtGui.QHBoxLayout() self.seqObjLine.addWidget(QtGui.QLabel('Use already loaded sequence',self)) self.seqObjCombo = CCP4Widgets.CComboBox(self,onlyEnumerators=True) self.seqObjCombo.setEditable(False) self.seqObjCombo.addItem('Select sequence..',QtCore.QVariant(-1)) seqObjInfo =CCP4Modules.PROJECTSMANAGER().db().getJobsWithOutputFiles( projectId=self.taskProjectId(),fileType = 'application/CCP4-seq') #print 'CAsuContentSeqView',seqObjInfo for item in seqObjInfo: if item['annotation'] is not None: title = item['annotation'] else: title = 'Sequence from '+CCP4Modules.TASKMANAGER().getTitle(item['taskname']) self.seqObjCombo.addItem(str(item['jobnumber'])+' '+title,QtCore.QVariant(item['fileid'])) self.seqObjLine.addWidget(self.seqObjCombo) but =QtGui.QPushButton('Load',self) self.connect(but,QtCore.SIGNAL('clicked()'),functools.partial(self.loadFile,'seqObj')) self.seqObjLine.addWidget(but) self.layout().addLayout(self.seqObjLine) self.setModel(model) self.pdbFile = None self.seqFile = None def validate(self,isValid=None,excludeWidgets=[],report=None,reportMessage=True): err = CErrorReport() if len(self.widgets['name'].getValue())==0: self.widgets['name'].validate(isValid=False) isValid = False err.append(self.__class__,101,stack=False) if len(self.widgets['sequence'].getValue())==0: self.widgets['sequence'].validate(isValid=False) isValid = False err.append(self.__class__,102,stack=False) if err.maxSeverity()>SEVERITY_WARNING: if report is None: report = err.report(ifStack=False,user=True,mode=2) else: report += '\n'+ err.report(ifStack=False,user=True,mode=2) CCP4Widgets.CComplexLineWidget.validate(self,isValid=isValid,excludeWidgets=excludeWidgets,report=report,reportMessage=reportMessage) def setModel(self,model=None): CCP4Widgets.CComplexLineWidget.setModel(self,model=model) if model is None: self.widgets['nCopies'].setModel(None) else: self.widgets['nCopies'].setModel(model.nCopies) def loadFile(self,mode): import CCP4FileBrowser,CCP4Modules if mode == 'seqObj': fileId = self.seqObjCombo.itemData(self.seqObjCombo.currentIndex()).toString().__str__() if fileId == '-1': return self.doLoadSequenceFile(fileId=fileId) return elif mode == 'sequence': filters = CCP4Modules.MIMETYPESHANDLER().getMimeTypeInfo('application/CCP4-seq','filter') self.seqFile = CCP4ModelData.CSeqDataFile(parent=self) self.loadDialog = CCP4FileBrowser.CFileDialog(parent=self, title='Load sequence from file', filters = [ filters ]) self.connect(self.loadDialog,QtCore.SIGNAL('selectFile'),self.loadSequenceFile) elif mode == 'coords': filters = CCP4Modules.MIMETYPESHANDLER().getMimeTypeInfo('chemical/x-pdb','filter') self.pdbFile = CCP4ModelData.CPdbDataFile(parent=self) self.loadDialog = CCP4FileBrowser.CFileDialog(parent=self, title='Load sequence from coordinate file', filters = [ filters ]) self.connect(self.loadDialog,QtCore.SIGNAL('selectFile'),self.loadPdbFile) #print 'CAsuContentSeqView.loadFile',repr(self.parent()),repr(self.parent().parent()) if self.window().objectName()=='createAsu': self.window().setModal(False) self.loadDialog.show() self.loadDialog.raise_() def loadSequenceFile(self,fileName=None): self.pdbFile= None if fileName is not None: self.seqFile.setFullPath(fileName) self.seqFile.identifyFile() #print 'CAsuContentSeqView.loadSequenceFile',fileName,self.seqFile.format,self.seqFile.identifiers if self.seqFile.__dict__['format'] == 'unknown': QtGui.QMessageBox.warning(self,'Reading sequence file','The format of the file has not been recognised. Please edit the sequence to remove any non-sequence information.' ) elif self.seqFile.fileContent.__dict__.get('loadWarning',None) is not None: if len(self.seqFile.fileContent.__dict__['loadWarning'])>0 and self.seqFile.fileContent.__dict__['loadWarning'][0]['code'] == 108: ''' import CCP4Utils win = self.makeImportReport('Importing '+str(filename),self.acceptFixedPir) label = QtGui.QLabel(self) label.setText( 'The input file is not correct PIR format but has been fixed and is shown below.\nIf this is still incorrect please correct the file and select it again.\n' + CCP4ModelData.PIR_DESCRIPTION + '\nYour corrected file:') #label.setReadOnly(True) win.layout().insertWidget(0,label) label = QtGui.QTextEdit(self) label.setText(CCP4Utils.readFile(self.model.fileContent.__dict__['loadWarning'][0]['details'])) label.setReadOnly(True) win.layout().insertWidget(1,label) win.show() ''' return elif self.seqFile.fileContent.__dict__['loadWarning'].maxSeverity()>SEVERITY_WARNING: self.seqFile.fileContent.__dict__['loadWarning'].warningMessage(windowTitle='Importing sequence file',parent=self,message='Failed importing sequence file') self.seqFile.unSet() return elif len(self.seqFile.__dict__.get('identifiers',[]))>1: if getattr(self,'idChooser',None) is None: self.idChooser = QtGui.QListWidget(self) win = self.makeImportReport('Importing '+str(fileName),self.handleIdChooser) win.layout().insertWidget(0,self.idChooser) if isinstance(self.model.parent(),CCP4ModelData.CAsuContentSeqList): self.idChooser.setSelectionMode(QtGui.QListWidget.MultiSelection) title = 'Select one or more sequences from the file' else: self.idChooser.setSelectionMode(QtGui.QListWidget.SingleSelection) title = 'Select one of the sequences in the file' win.layout().insertWidget(0,QtGui.QLabel(title,self)) else: self.idChooser.window().setWindowTitle('Importing '+str(fileName)) self.idChooser.clear() for item in self.seqFile.__dict__['identifiers']: self.idChooser.addItem(item) self.idChooser.window().show() self.idChooser.window().raise_() return else: self.doLoadSequenceFile(record=0) def doLoadSequenceFile(self,record=0,fileId=None): self.model.unSet() if fileId is not None: import CCP4Modules fileName = CCP4Modules.PROJECTSMANAGER().db().getFullPath(fileId=fileId) fileAnnotation = CCP4Modules.PROJECTSMANAGER().db().getFileInfo(fileId=fileId,mode='annotation') print 'doLoadSequenceFile fileAnnotation',fileAnnotation self.seqFile = CCP4ModelData.CSeqDataFile(parent=self) self.seqFile.setFullPath(fileName) self.seqFile.__dict__['format'] = 'internal' self.seqFile.fileContent.loadInternalFile(str(self.seqFile)) #importInfo = CCP4Modules.PROJECTSMANAGER().db().getImportFileInfo(fileId=fileId) else: self.seqFile.fileContent.loadExternalFile(str(self.seqFile),self.seqFile.__dict__['format'],record=record) self.model.source = self.seqFile.__str__() self.model.sequence.set(self.model.cleanupSequence(self.seqFile.fileContent.sequence)) try: self.model.name.set(self.model.name.fix(self.seqFile.fileContent.name)) except: pass if not self.model.name.isSet(): if fileAnnotation is not None: self.model.name.set(self.model.name.fix(fileAnnotation)) else: import os self.model.name.set(os.path.split(os.path.splitext(self.seqFile.__str__())[0])[1]) self.model.description.set(self.seqFile.fileContent.description) self.updateViewFromModel() def makeImportReport(self,title,callBack=None): win = QtGui.QDialog(self) win.setWindowTitle(title) win.setLayout(QtGui.QVBoxLayout()) line = QtGui.QHBoxLayout() box = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel) win.layout().addLayout(line) line.addStretch(1) line.addWidget(box) line.addStretch(1) if callBack is not None: self.connect(box,QtCore.SIGNAL('clicked ( QAbstractButton * )'),callBack) return win def handleIdChooser(self,but): #print 'CAsuContentSeqView.handleIdChooser', but.text().__str__() if self.idChooser.selectionMode() == QtGui.QListWidget.SingleSelection: recordList = [self.idChooser.currentRow()] else: recordList = [] for item in self.idChooser.selectedItems(): recordList.append(self.idChooser.row(item)) win = but.window() win.setModal(False) win.close() print 'CAsuContentSeqView.handleIdChooser',recordList if but.text().__str__() == 'Cancel': return else: if self.seqFile is not None: self.doLoadSequenceFile(record=recordList[0]) if len(recordList)>1: rv = self.model.parent().extendSeqList(self.seqFile,recordList[1:]) self.parent().parent().updateViewFromModel() if rv.maxSeverity()>SEVERITY_WARNING: rv.warningMessage(parent=self,windowTitle='Loading '+str(self.seqFile),message='Not all chains loaded') elif self.pdbFile is not None: self.doLoadPdbFile(record=recordList[0]) if len(recordList)>1: rv = self.model.parent().extendSeqList(self.pdbFile,recordList[1:]) self.parent().parent().updateViewFromModel() if rv.maxSeverity()>SEVERITY_WARNING: rv.warningMessage(parent=self,windowTitle='Loading '+str(self.pdbFile),message='Not all chains loaded') def loadPdbFile(self,fileName): self.seqFile = None self.pdbFile.setFullPath(fileName) if len(self.pdbFile.fileContent.sequences)==0: QtGui.QMessageBox.warning(self,'Reading sequence from coordinate file','No sequences were read from the file\n'+ fileName) return elif len(self.pdbFile.fileContent.sequences)==1: self.doLoadPdbFile(record=0) else: if getattr(self,'idChooser',None) is None: self.idChooser = QtGui.QListWidget(self) win = self.makeImportReport('Importing '+str(fileName),self.handleIdChooser) win.layout().insertWidget(0,self.idChooser) if isinstance(self.model.parent(),CCP4ModelData.CAsuContentSeqList): self.idChooser.setSelectionMode(QtGui.QListWidget.MultiSelection) title = 'Select one or more sequences from the file' else: self.idChooser.setSelectionMode(QtGui.QListWidget.SingleSelection) title = 'Select one of the sequences in the file' win.layout().insertWidget(0,QtGui.QLabel(title,self)) self.idChooser.window().setWindowTitle('Importing '+str(fileName)) self.idChooser.clear() for item in self.pdbFile.fileContent.sequences.keys(): self.idChooser.addItem(item) self.idChooser.window().show() self.idChooser.window().raise_() return def doLoadPdbFile(self,record=0): self.model.unSet() chainId = self.pdbFile.fileContent.sequences.keys()[record] print 'doLoadPdbFile chainId',chainId self.model.sequence.set(self.model.cleanupSequence(self.pdbFile.fileContent.sequences[chainId])) self.model.name.set(chainId) self.model.description.unSet() self.updateViewFromModel() class CAsuContentSeqListView(CCP4Widgets.CListView): MODEL_CLASS = CCP4ModelData.CAsuContentSeqList def __init__(self,parent=None,model=None,qualifiers={}): qualis = { 'mode' : 'table', 'tableItems' : ['name','nCopies','description','seqeunce'] , 'columnHeaders':['Name','Copies','Description','Sequence'], } qualis.update(qualifiers) CCP4Widgets.CListView.__init__(self,parent,model=model,qualifiers=qualis) self.listWidget.horizontalHeader().setStretchLastSection(True) class CAsuDataFileView(CCP4Widgets.CDataFileView): MODEL_CLASS = CCP4ModelData.CAsuDataFile NOTICE = \ """CCP4i2 now uses a 'Crystal content' file that contains all chain sequences in a crystal instead of separate sequence files. Where necessary you will be able to select chain(s) from the file. In future projects please use the 'Define crystal contents' (in the 'Import ..' module). Please enter all known chain sequences for your structure.""" def __init__(self,parent=None,model=None,qualifiers={}): self.selectionMode = qualifiers.get('selectionMode',0) qualis = { 'vboxLayout' : True } qualis.update(qualifiers) super(CAsuDataFileView,self).__init__(parent=parent,model=None,qualifiers=qualis) if self.selectionMode>0: if self.selectionMode == 1: label = QtGui.QLabel('Select one sequence',self) else: label = QtGui.QLabel('Select one or more sequences',self) label.setObjectName('italic') self.layout().addWidget(label) self.selectionFrame = QtGui.QFrame(self) self.selectionFrame.setLayout(QtGui.QGridLayout()) self.layout().addWidget(self.selectionFrame) self.selectionGroup = QtGui.QButtonGroup(self) if self.selectionMode==1: self.selectionGroup.setExclusive(True) self.selectionButtons = [] self.connect(self.selectionGroup,QtCore.SIGNAL('buttonClicked(int)'),self.updateModelSelection) self.setModel(model) def filterText(self): # make the filters text for QFileDialog textList = CCP4Widgets.CDataFileView.filterText(self) extList = CCP4ModelData.CSeqDataFile().qualifiers('fileExtensions') line = 'Sequence files (*.'+extList[0] for ext in extList: line = line+' *.'+ext line +=')' textList.insert(0,line) return textList def handleBrowserOpenFile(self,fileName,downloadInfo,autoInfoOnFileImport=True,validate=True,updateView=True): import os if fileName.endswith('asu.xml'): CCP4Widgets.CDataFileView.handleBrowserOpenFile(self,fileName,downloadInfo,autoInfoOnFileImport=autoInfoOnFileImport, validate=validate,updateView=updateView) else: #projectId = self.parentTaskWidget().projectId() self.importDialog = QtGui.QDialog(self) self.importDialog.setObjectName('createAsu') self.importDialog.setLayout(QtGui.QGridLayout()) self.importDialog.setWindowTitle('Define crystal content - import sequences:'+os.path.split(fileName)[1]) self.importDialog.setModal(True) self.importDialog.layout().addWidget(QtGui.QLabel(self.NOTICE,self.importDialog)) self.importAsuContent = CCP4ModelData.CAsuContentSeqList(parent=self) self.importAsuContentView = CAsuContentSeqListView(parent=self.importDialog,model=self.importAsuContent) self.importAsuContentView.setListVisible(True) self.importDialog.layout().addWidget(self.importAsuContentView,1,0) self.importDialog.show() self.importAsuContentView.editor.seqFile = CCP4ModelData.CSeqDataFile(parent=self.importAsuContentView) self.importAsuContentView.editor.loadSequenceFile(fileName) butBox = QtGui.QDialogButtonBox(self) self.importDialog.layout().addWidget(butBox,2,0) but = butBox.addButton(QtGui.QDialogButtonBox.Save) self.connect(but,QtCore.SIGNAL('clicked()'),self.doImport) but = butBox.addButton(QtGui.QDialogButtonBox.Cancel) self.connect(but,QtCore.SIGNAL('clicked()'),self.importDialog.hide) but = butBox.addButton(QtGui.QDialogButtonBox.Help) self.connect(but,QtCore.SIGNAL('clicked()'),self.showHelp) def doImport(self): if self.importAsuContentView.validate(): self.importDialog.hide() def getMenuDef(self): menu = ['clear','view','sep','copy','paste','help'] if self.selectionMode>0: menu.insert(menu.index('sep'),'select') return menu def getActionDef(self,name): if name == 'select': def iC(): try: return self.selectionList.isVisible() except: return False return dict ( text = self.tr("Select chains"), tip = self.tr('Select limited set of sequences'), slot = self.showSelection, checkable = True, isChecked = iC ) return CCP4Widgets.CDataFileView.getActionDef(self,name) def openViewer(self,mode): pass def showSelection(self): self.selectionFrame.setVisible(not self.selectionFrame.isVisible()) def getValue(self): rv = CCP4Widgets.CDataFileView.getValue(self) if self.selectionMode>0: selDict = {} for idx in range(len(self.model.fileContent.seqList)): selDict[str(self.model.fileContent.seqList[idx].name)] = self.selectionGroup.button(idx).isChecked() rv['selection'] = selDict print 'CAsuDataFileView.getValue',rv['selection'] return rv def setValue(self,value): print 'CAsuDataFileView.setValue',value['selection'] CCP4Widgets.CDataFileView.setValue(self,value) if self.selectionMode==0: return self.selectionGroup.blockSignals(True) for idx in range(len(self.model.fileContent.seqList)): self.selectionGroup.button(idx).setChecked(value['selection'][str(self.model.fileContent.seqList[idx].name)]) self.selectionGroup.blockSignals(False) def updateModelFromView(self): CCP4Widgets.CDataFileView.updateModelFromView(self) if self.model is None: return if self.selectionMode==0: return self.updateModelSelection() def updateModelSelection(self): selDict = {} if len(self.selectionButtons)==0: return self.connectUpdateViewFromModel(False) for idx in range(len(self.model.fileContent.seqList)): selDict[str(self.model.fileContent.seqList[idx].name)] = self.selectionGroup.button(idx).isChecked() self.model.selection.set(selDict) self.connectUpdateViewFromModel(True) def updateViewFromModel(self): CCP4Widgets.CDataFileView.updateViewFromModel(self) if self.model is None: return if self.selectionMode==0: return self.selectionGroup.blockSignals(True) for but in self.selectionButtons: self.selectionGroup.remove(but) but.deleteLater() self.selectionButtons = [] if self.model.isSet(): idx = 0 for asuObject in self.model.fileContent.seqList: text = str(asuObject.name) + ' ' + str(asuObject.description) if self.selectionMode==1: self.selectionButtons.append(QtGui.QRadioButton(text,self)) else: self.selectionButtons.append(QtGui.QCheckBox(text,self)) self.selectionGroup.addButton(self.selectionButtons[-1],idx) self.selectionFrame.layout().addWidget(self.selectionButtons[-1],idx,0) if self.model.selection.get(str(asuObject.name),False): self.selectionButtons[idx].setChecked(True) idx += 1 self.selectionGroup.blockSignals(False) def showHelp(self): import CCP4Modules CCP4Modules.WEBBROWSER().loadWebPage(helpFileName='model_data')