""" CCP4ComFilePatchManagerGui.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 com file patches """ import os from PyQt4 import QtGui,QtCore from core import CCP4Data,CCP4Container from qtgui import CCP4CustomisationGui from core.CCP4ErrorHandling import * from core.CCP4Modules import COMFILEPATCHMANAGER,WEBBROWSER,PROJECTSMANAGER def openGui(): if CComFilePatchManagerGui.insts is None: CComFilePatchManagerGui.insts = CComFilePatchManagerGui() CComFilePatchManagerGui.insts.show() CComFilePatchManagerGui.insts.raise_() class CComFilePatchManagerGui(CCP4CustomisationGui.CCustomisationGui): insts = None def __init__(self,parent=None): CCP4CustomisationGui.CCustomisationGui.__init__(self,parent=parent,mode='comfilepatch',title='Task Parameter and Patches Manager') def manager(self): return COMFILEPATCHMANAGER() def handleNew(self): createWidget = CCreatePatchDialog(self) createWidget.show() createWidget.raise_() def handleEdit(self,selected=None): if selected is None: selected = self.customListView.selectedItem() if selected is None: return createWidget = CCreatePatchDialog(self,new=False) createWidget.loadPatch(selected) createWidget.show() createWidget.raise_() class CCreatePatchDialog(QtGui.QDialog): def __init__(self,parent=None,new=True): from qtgui import CCP4Widgets QtGui.QDialog.__init__(self,parent) self.setWindowTitle('Set custom task parameters') self.selectedJob = None self.setLayout(QtGui.QVBoxLayout()) if not new: line = QtGui.QHBoxLayout() self.taskLabel = QtGui.QLabel('Apply patch to tasks: ',self) line.addWidget(self.taskLabel) self.layout().addLayout(line) line = QtGui.QHBoxLayout() line.addWidget(QtGui.QLabel('Edit command file from project:')) if new: self.projectCombo = QtGui.QComboBox(self) self.connect(self.projectCombo,QtCore.SIGNAL('currentIndexChanged(int)'),self.handleProjectChanged) line.addWidget(self.projectCombo) else: self.projectLabel = QtGui.QLabel(self) line.addWidget(self.projectLabel) line.addWidget(QtGui.QLabel('job:')) if new: self.jobsCombo = CCP4Widgets.CJobSelectionCombo(self) self.connect(self.jobsCombo,QtCore.SIGNAL('currentIndexChanged(int)'),self.handleJobSelection) line.addWidget(self.jobsCombo) else: self.jobsLabel = QtGui.QLabel(self) line.addWidget(self.jobsLabel) line.addStretch(1) self.layout().addLayout(line) line = QtGui.QHBoxLayout() line.addWidget(QtGui.QLabel('Name for task parameters')) self.nameLineEdit= QtGui.QLineEdit(self) self.nameLineEdit.setToolTip('Enter a name for the custom task parameters') self.nameLineEdit.setMinimumWidth(300) line.addWidget(self.nameLineEdit) self.layout().addLayout(line) line = QtGui.QHBoxLayout() line.addWidget(QtGui.QLabel('Title to be used in interface')) self.titleLineEdit= QtGui.QLineEdit(self) self.titleLineEdit.setToolTip('Enter a short descriptive description') self.titleLineEdit.setMinimumWidth(300) line.addWidget(self.titleLineEdit) self.layout().addLayout(line) line = QtGui.QHBoxLayout() self.useControlParamsWidget = QtGui.QCheckBox('Use the control parameters set for this job',self) self.useControlParamsWidget.setChecked(True) line.addWidget(self.useControlParamsWidget) self.layout().addLayout(line) line = QtGui.QHBoxLayout() box = QtGui.QVBoxLayout() box.addWidget(QtGui.QLabel('Original command file')) self.originalTextEdit = QtGui.QTextEdit(self) self.originalTextEdit.setReadOnly(True) self.originalTextEdit.setObjectName('readOnly') box.addWidget(self.originalTextEdit) line.addLayout(box) box = QtGui.QVBoxLayout() box.addWidget(QtGui.QLabel('Edit the command file')) self.textEdit = QtGui.QTextEdit(self) box.addWidget(self.textEdit) line.addLayout(box) self.layout().addLayout(line) buttonBox = QtGui.QDialogButtonBox(self) but = buttonBox.addButton('Help',QtGui.QDialogButtonBox.HelpRole) but.setFocusPolicy(QtCore.Qt.NoFocus) self.connect(but,QtCore.SIGNAL('released()'),self.help) but = buttonBox.addButton('Cancel',QtGui.QDialogButtonBox.RejectRole) but.setFocusPolicy(QtCore.Qt.NoFocus) self.connect(but,QtCore.SIGNAL('released()'),self.cancel) but = buttonBox.addButton('Save task parameters',QtGui.QDialogButtonBox.AcceptRole) but.setFocusPolicy(QtCore.Qt.NoFocus) self.connect(but,QtCore.SIGNAL('released()'),self.accept) self.layout().addWidget(buttonBox) but.setFocusPolicy(QtCore.Qt.NoFocus) self.reset() def handleProjectChanged(self): self.selectedProject = self.projectCombo.itemData(self.projectCombo.currentIndex()).toString().__str__() self.jobsCombo.setProjectId(self.selectedProject) def handleJobSelection(self,indx): jobId = self.jobsCombo.getSelection() #print 'CCreatePatchDialog.handleJobSelection',jobList,errList self.selectedJob = jobId self.originalText = self.parent().manager().getComFileText(jobId=self.selectedJob) self.originalTextEdit.setReadOnly(False) self.originalTextEdit.setPlainText(self.originalText) self.originalTextEdit.setReadOnly(True) self.textEdit.setPlainText(self.originalText) #print 'CCreatePatchDialog.handleJobSelection',self.selectedJob def reset(self): self.textEdit.clear() self.originalTextEdit.clear() # get list of projectId,projectName,projectDir,parentId if hasattr(self,'projectCombo'): projectList = PROJECTSMANAGER().db().listProjects(order='name') for project in projectList: item = self.projectCombo.addItem(project[1],QtCore.QVariant(project[0])) self.jobsCombo.setProjectId(projectList[0][0]) #self.titleLineEdit.setReadOnly(False) self.nameLineEdit.clear() self.titleLineEdit.clear() self.loadedFrom= None def help(self): WEBBROWSER().loadWebPage(helpFileName='customisation') def cancel(self): self.hide() def accept(self): if self.selectedJob is None and self.jobsLabel.text().__str__()!='Unknown': QtGui.QMessageBox.warning(self,'Task parameters','No job has been selected') return name = self.nameLineEdit.text().__str__() if len(name)<1: QtGui.QMessageBox.warning(self,'Task parameters','Please provide a unique name for task parameters') return import re name0 = re.sub('[^a-zA-Z0-9_-]','_',name) if name0 != name: self.nameLineEdit.setText(name0) QtGui.QMessageBox.warning(self,'Create task parameters','The task parameters name will be used as a directory name\n' + 'it has been changed to limited chacter set a-z,A-Z,0-9,_,-\n' + "Please click 'Save task parameters' again" ) return diry = COMFILEPATCHMANAGER().getDirectory(name=name) if os.path.exists(diry): import functools msgBox = QtGui.QMessageBox() msgBox.setWindowTitle('Create task parameter') msgBox.setText('There is already a task parameter directory called\n'+os.path.split(diry)[1]) b = msgBox.addButton(QtGui.QMessageBox.Cancel) b = msgBox.addButton('Overwrite',QtGui.QMessageBox.ApplyRole) self.connect(b,QtCore.SIGNAL('released()'),functools.partial(self.handleOverwrite,name)) msgBox.exec_() return self.createPatch(name) self.hide() def handleOverwrite(self,name): self.createPatch(name,True) self.hide() def createPatch(self,name,overwrite=False): title = None jobInfoList = [] taskNameList = [] #print 'createPatch selectedJob',self.selectedJob,self.loadedFrom if self.loadedFrom is not None: container,errMess = self.patchContainer(self.loadedFrom) #print 'createPatch loadedFrom',self.loadedFrom, container,errMess if container is not None: for item in container.taskNameList: taskNameList.append(item.__str__()) elif self.selectedJob is not None: jobId = self.selectedJob while jobId is not None: try: jobInfoList.append( PROJECTSMANAGER().db().getJobInfo(jobId=jobId,mode=['parentjobid','taskname']) ) jobId = jobInfoList[-1]['parentjobid'] except: jobId = None for jobInfo in jobInfoList: taskNameList.append(jobInfo['taskname']) #print 'createPatch taskNameList', jobInfoList,taskNameList text2 = self.textEdit.toPlainText().__str__() title = self.titleLineEdit.text().__str__() useControlParams = self.useControlParamsWidget.isChecked() print 'createPatch title',title err = COMFILEPATCHMANAGER().createPatch(name,title,taskNameList,self.selectedProject,self.selectedJob,self.originalText,text2,useControlParams,overwrite=True) if err.maxSeverity()>SEVERITY_WARNING: err.warningMessage('Create command file patch','Error saving patch',parent=self) return self.emit(QtCore.SIGNAL('created'),name) def patchContainer(self,name): from core import CCP4ComFilePatchManager container = CCP4ComFilePatchManager.CPatchDefinition(parent=self,name=name) fileName=COMFILEPATCHMANAGER().getCustomFile(name=name) #print 'patchContainer fileName',fileName if fileName is None: return None,'Task parameter file does not exist: '+COMFILEPATCHMANAGER().getCustomFile(name=name,mustExist=False) try: container.loadDataFromXml(fileName=fileName,loadHeader=True) except: return None,'Probably error in file: '+fileName return container,None def loadPatch(self,name): container,errMess = self.patchContainer(name) if errMess is not None: QtGui.QMessageBox.warning(self,'Error loading task parameter information',errMess) return if hasattr(self,'projectLabel'): self.selectedProject = container.projectId.__str__() try: projectName = PROJECTSMANAGER().db().getProjectInfo(projectId=self.selectedProject,mode='projectname') except: projectName = None if projectName is not None: self.projectLabel.setText(projectName) else: self.projectLabel.setText('Unknown') self.selectedJob = container.jobId.__str__() try: jobInfo = PROJECTSMANAGER().db().getJobInfo(jobId=self.selectedJob,mode=['jobnumber','taskname']) except: jobInfo = None if jobInfo is not None: self.jobsLabel.setText(jobInfo['jobnumber']+' '+jobInfo['taskname']) else: self.jobsLabel.setText('Unknown') if getattr(self,'taskLabel') is not None: label = 'Apply patch to tasks: ' from core import CCP4TaskManager for taskName in container.taskNameList: title = CCP4TaskManager.TASKMANAGER().getTitle(taskName=taskName) label = label + title + ' ' self.taskLabel.setText(label) self.originalText = str(container.text1) self.originalTextEdit.setReadOnly(False) self.originalTextEdit.setPlainText(self.originalText) self.originalTextEdit.setReadOnly(True) self.nameLineEdit.setText(name) self.textEdit.setPlainText(str(container.text2)) title = container.header.pluginTitle.__str__() self.titleLineEdit.setText(title) self.useControlParamsWidget.setChecked(container.controlParameters.isSet()) self.loadedFrom= name #self.titleLineEdit.setReadOnly(True)