""" CCP4CustomisationGui.py: CCP4 GUI Project Copyright (C) 2013 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. """ """ Liz Potterton July 2013 - create and manage customisations """ import os from PyQt4 import QtGui,QtCore from core import CCP4Data,CCP4Container from core.CCP4ErrorHandling import * from core.CCP4Modules import WEBBROWSER,PROJECTSMANAGER,DUMMYMAINWINDOW class CCustomisationGui(QtGui.QDialog): insts = [] def __init__(self,parent=None,mode=None,title=None,ifEdit=True,ifClone=True): if parent is None: parent = DUMMYMAINWINDOW() QtGui.QDialog.__init__(self,parent) CCustomisationGui.insts.append(self) self.mode = mode self.setWindowTitle(title) self.createWidget = None layout = QtGui.QGridLayout() self.setLayout(layout) self.customListView = CCustomListWidget(self) self.connect(self.customListView,QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'),self.handleDoubleClick) self.customListView.populate() self.layout().addWidget(self.customListView,1,0) butDef = [ ['New',self.handleNew,True,False], ['Edit',self.handleEdit,True,False], ['Clone',self.handleClone,True,False], ['Export',self.handleExport,True,False], ['Import',self.handleImport,True,False], ['Delete',self.handleDelete,True,False], ['Help',self.handleHelp,True,False]] if not ifClone: del butDef[2] if not ifEdit: del butDef[1] buttonLayout = QtGui.QVBoxLayout() for label,slot,enabled,default in butDef: button =QtGui.QPushButton(self,text=label) button.setEnabled(enabled) if default: button.setDefault(True) buttonLayout.addWidget(button) self.connect(button,QtCore.SIGNAL('clicked()'),slot) self.layout().addLayout(buttonLayout,1,1) def done(self,r): try: CCustomisationGui.insts.remove(self) except: print 'Error in CCustomisationGui.done removing from insts list' print 'CCustomisationGui.done',r,CCustomisationGui.insts QtGui.QDialog.done(self,r) def manager(self): # Reimplement in sub-class return None def handleNew(self): pass def handleEdit(self,selected): print 'CCustomisationGui.handleEdit',selected pass def handleClone(self): selected = self.customListView.selectedItem() if selected is None: return if not hasattr(self,'cloneDialog'): self.cloneDialog = CCustomCloneDialog(self) self.connect(self.cloneDialog,QtCore.SIGNAL('clone'),self.handleClone2) self.cloneDialog.setSelected(selected) self.cloneDialog.show() self.cloneDialog.raise_() def handleClone2(self,original,new,ifEdit=True): try: self.manager().clone(original,new) except CException as e: e.warningMessage('Clone '+self.mode,'Error cloning '+original,parent=self) return if ifEdit: self.handleEdit(new) def handleDoubleClick(self,item): nameVar = item.data(QtCore.Qt.UserRole) name = nameVar.toString().__str__() self.handleEdit(selected=name) def handleExport(self): selected = self.customListView.selectedItem() if selected is None: return from qtgui import CCP4FileBrowser import functools self.browser = CCP4FileBrowser.CFileDialog(self, title='Save '+self.mode+' to compressed file', filters= ['CCP4 '+self.mode+' (*.ccp4_'+self.mode+'.tar.gz)'], defaultSuffix='ccp4_'+self.mode+'.tar.gz', fileMode=QtGui.QFileDialog.AnyFile ) self.connect(self.browser,QtCore.SIGNAL('selectFile'),functools.partial(self.handleExport2,selected)) self.browser.show() def handleExport2(self,selected,fileName): self.browser.hide() self.browser.deleteLater() del self.browser err = self.manager().export(selected,fileName) if err.maxSeverity()>SEVERITY_WARNING: err.warningMessage('Export '+self.mode,'Error creating compressed file',parent=self) def handleImport(self): from qtgui import CCP4FileBrowser self.browser = CCP4FileBrowser.CFileDialog(self, title='Import '+self.mode+' compressed file', filters= ['CCP4 compressed '+self.mode+' (*.ccp4_'+self.mode+'.tar.gz)'], defaultSuffix='ccp4_'+self.mode+'.tar.gz', fileMode=QtGui.QFileDialog.ExistingFile ) self.connect(self.browser,QtCore.SIGNAL('selectFile'),self.handleImport1) self.browser.show() def handleImport1(self,fileName): self.browser.hide() self.browser.deleteLater() del self.browser #print 'handleImport1',fileName try: self.manager().testImport(fileName) except CException as e: if e.count(code=110) == 0: e.warningMessage('Error opening compressed '+self.mode+' file',parent=self) else: name = e[0]['details'] self.importQuery = CCustomImportDialog(self,name,fileName) self.connect(self.importQuery,QtCore.SIGNAL('import'),self.handleImport2) self.importQuery.show() else: try: self.manager().uncompress(fileName,self.manager().getDirectory()) except CException as e: e.warningMessage('Error importing '+self.mode,'Failed to write to '+self.mode+' directory',parent=self) def handleImport2(self,name,fileName,overwrite,rename): #print 'handleImport2',name,overwrite,rename if overwrite: self.manager().delete(name) self.manager().uncompress(fileName, self.manager().getDirectory(),rename=rename) def handleDelete(self): selected = self.customListView.selectedItem() if selected is None: return ret = QtGui.QMessageBox.question(self,self.windowTitle(),'Delete '+self.mode+' '+selected,QtGui.QMessageBox.Ok|QtGui.QMessageBox.Cancel) if ret == QtGui.QMessageBox.Cancel: return ret = self.manager().delete(selected) if ret: QtGui.QMessageBox.warning(self,self.windowTitle(),'Error deleting '+self.mode+' '+selected) def handleHelp(self): WEBBROWSER().loadWebPage(helpFileName='customisation') class CCustomListWidget(QtGui.QListWidget): def __init__(self,parent): QtGui.QListWidget.__init__(self,parent) self.connect(self.parent().manager(),QtCore.SIGNAL('listChanged'),self.populate) def populate(self): self.clear() titleList =self.parent().manager().getTitleList() for name,title in titleList: obj = QtGui.QListWidgetItem(title) obj.setData(QtCore.Qt.UserRole,name) self.addItem(obj) def selectedItem(self): seleList = self.selectedItems() #print 'contentsTree.selectedItem',seleList if len(seleList) == 0: return None else: qvar = seleList[0].data(QtCore.Qt.UserRole) #print 'contentsTree.selectedItem',qvar.isNull() , qvar.isValid(),qvar.toString().__str__() if qvar.isNull() or (not qvar.isValid()): return seleList[0].text().__str__() else: return qvar.toString().__str__() class CCustomImportDialog(QtGui.QDialog): def __init__(self,parent,name=None,fileName=None): QtGui.QDialog.__init__(self,parent) self.setWindowTitle("Import a "+self.parent().mode) self.setLayout(QtGui.QVBoxLayout()) self.name = name self.fileName = fileName self.layout().addWidget(QtGui.QLabel('There is already a '+self.parent().mode+' called '+str(name))) self.bg = QtGui.QButtonGroup(self) self.bg.setExclusive(True) but = QtGui.QRadioButton('Overwrite existing '+self.parent().mode,self) self.bg.addButton(but,1) self.layout().addWidget(but) line = QtGui.QHBoxLayout() but = QtGui.QRadioButton('Rename to ',self) line.addWidget(but) self.rename = QtGui.QLineEdit(self) line.addWidget(self.rename) self.layout().addLayout(line) self.bg.addButton(but,2) but.setChecked(True) butBox = QtGui.QDialogButtonBox(self) but = butBox.addButton('Import '+self.parent().mode,QtGui.QDialogButtonBox.ActionRole) but.setDefault(False) self.connect(but,QtCore.SIGNAL('released()'),self.apply) but = butBox.addButton(QtGui.QDialogButtonBox.Cancel) self.connect(but,QtCore.SIGNAL('released()'),self.close) self.layout().addWidget(butBox) def close(self): self.hide() self.deleteLater() def apply(self): if self.bg.checkedId() == 2 and len(self.rename.text().__str__())<=0 or self.rename.text().__str__() in self.parent().manager().getList(): return self.emit(QtCore.SIGNAL('import'),self.name,self.fileName,2-self.bg.checkedId(),self.rename.text().__str__()) self.close() class CCustomCloneDialog(QtGui.QDialog): def __init__(self,parent,selected=None): QtGui.QDialog.__init__(self,parent) self.setWindowTitle("Clone a "+self.parent().mode) self.setLayout(QtGui.QVBoxLayout()) self.label = QtGui.QLabel(self) self.layout().addWidget(self.label) line = QtGui.QHBoxLayout() line.addWidget( QtGui.QLabel('Name',self)) self.nameWidget = QtGui.QLineEdit(self) line.addWidget(self.nameWidget) self.layout().addLayout(line) ''' line = QtGui.QHBoxLayout() line.addWidget( QtGui.QLabel('Title',self)) self.titleWidget = QtGui.QLineEdit(self) line.addWidget(self.titleWidget) self.layout().addLayout(line) line = QtGui.QHBoxLayout() self.editWidget = QtGui.QCheckBox('Edit new '+self.parent().mode,self) self.editWidget.setChecked(True) line.addWidget(self.editWidget ) self.layout().addLayout(line) ''' butBox = QtGui.QDialogButtonBox(self) but = butBox.addButton('Clone '+self.parent().mode,QtGui.QDialogButtonBox.ActionRole) but.setDefault(False) self.connect(but,QtCore.SIGNAL('released()'),self.apply) but = butBox.addButton(QtGui.QDialogButtonBox.Cancel) self.connect(but,QtCore.SIGNAL('released()'),self.close) self.layout().addWidget(butBox) self.setSelected(selected) def setSelected(self,selected): self.selected = selected self.label.setText('Clone '+str(selected)+' to new '+self.parent().mode+':') ''' if selected is None: self.titleWidget.setText('') else: self.titleWidget.setText(self.parent().manager().getTitle(selected)) ''' def apply(self): name = self.nameWidget.text().__str__() #title = self.titleWidget.text().__str__() if len(name)<=0 or name in self.parent().manager().getList(): QtGui.QMessageBox.warning(self,'Clone '+self.parent().mode,'Please enter unique name for new '+self.parent().mode) return ''' if len(title)<=0 or title == self.parent().manager().getTitle(self.selected): QtGui.QMessageBox.warning(self,'Clone '+self.parent().mode,'Please enter a different title') return ''' self.emit(QtCore.SIGNAL('clone'),self.selected,name) self.close()