1 from __future__
import absolute_import
2 from __future__
import print_function
20 from FWCore.GuiBrowsers.DOTExport
import DotExport
21 import_dotexport_error=
None 22 except Exception
as e:
27 event_content_error=
None 28 except Exception
as e:
32 from .ToolDataAccessor
import ToolDataAccessor,ConfigToolBase,standardConfigDir
33 from .ToolDialog
import ToolDialog
34 import_tools_error=
None 35 except Exception
as e:
42 logging.debug(__name__ +
": __init__")
43 BrowserTabController.__init__(self, plugin)
54 openEditorAction = self.
plugin().application().createAction(
'&Open in custom editor', self.
openEditor,
"F6")
55 self._configMenu.addAction(openEditorAction)
56 chooseEditorAction = self.
plugin().application().createAction(
'&Choose custom editor...', self.
chooseEditor,
"Ctrl+T")
57 self._configMenu.addAction(chooseEditorAction)
58 self._configMenu.addSeparator()
67 self._configMenu.addSeparator()
74 """ Returns supported file type: py. 76 return [(
'py',
'Config file')]
77 staticSupportedFileTypes = staticmethod(staticSupportedFileTypes)
83 BrowserTabController.updateViewMenu(self)
88 logging.debug(__name__ +
": onCenterViewDoubleClicked()")
93 """ Fill the center view from an item in the TreeView and update it """ 98 statusMessage = self.
plugin().application().startWorking(
"Updating center view")
103 if self.
_thread !=
None and self._thread.isRunning():
105 while self._thread.isRunning():
106 if not Application.NO_PROCESS_EVENTS:
107 QCoreApplication.instance().processEvents()
118 while self._thread.isRunning():
119 if not Application.NO_PROCESS_EVENTS:
120 QCoreApplication.instance().processEvents()
121 self.
tab().
centerView().setConnections(self._thread.returnValue())
137 if self.
tab().propertyView().dataObject() != select
and propertyView:
138 self.
tab().propertyView().setDataObject(select)
140 if import_tools_error==
None and self.
tab().editorSplitter():
142 self.
plugin().application().stopWorking(statusMessage)
145 """ Shows plugin menus when user selects tab. 147 logging.debug(__name__ +
": activated()")
148 BrowserTabController.activated(self)
151 self._editorAction.setVisible(
not self.
tab().editorSplitter())
152 if self.
tab().editorSplitter():
154 self.
tab().mainWindow().application().showZoomToolBar()
158 logging.debug(__name__ +
": openEditor")
159 selected_object = self.
tab().propertyView().dataObject()
160 filename = self.
dataAccessor().fullFilename(selected_object)
161 if self.
_editorName !=
"" and selected_object !=
None and os.path.exists(filename):
162 if os.path.expandvars(
"$CMSSW_RELEASE_BASE")
in filename:
163 QMessageBox.information(self.
tab(),
"Opening readonly file...",
"This file is from $CMSSW_RELEASE_BASE and readonly")
165 command +=
" " + filename
170 """ Choose editor using FileDialog """ 171 logging.debug(__name__ +
": chooseEditor")
172 if _editorName ==
"":
173 _editorName =
str(QFileDialog.getSaveFileName(self.
tab(),
"Choose editor", self.
_editorName,
"Editor (*)",
None , QFileDialog.DontConfirmOverwrite
or QFileDialog.DontResolveSymlinks))
174 if not os.path.exists(_editorName):
175 _editorName = os.path.basename(_editorName)
176 if _editorName !=
None and _editorName !=
"":
181 """ Dump python configuration to file """ 182 logging.debug(__name__ +
": dumpPython")
185 logging.error(self.__class__.__name__ +
": dumpPython() - "+
"Cannot dump this config because it does not contain a 'process'.\nNote that only 'cfg' files contain a 'process'.")
186 self.
plugin().application().errorMessage(
"Cannot dump this config because it does not contain a 'process'.\nNote that only 'cfg' files contain a 'process'.")
190 defaultname = os.path.splitext(self.
_filename)[0] +
"_dump" + os.path.splitext(self.
_filename)[1]
191 fileName =
str(QFileDialog.getSaveFileName(self.
tab(),
"Save python config...", defaultname,
"Python config (*.py)", filter))
195 if os.path.splitext(fileName)[1].
upper().
strip(
".") == ext:
196 name = os.path.splitext(fileName)[0]
197 ext = os.path.splitext(fileName)[1].
upper().
strip(
".")
198 text_file =
open(name +
"." + ext.lower(),
"w")
199 text_file.write(dump)
203 """ Show config history """ 204 logging.debug(__name__ +
": history")
207 logging.error(self.__class__.__name__ +
": history() - "+
"Cannot show config history because it does not contain a 'process'.\nNote that only 'cfg' files contain a 'process'.")
208 self.
plugin().application().errorMessage(
"Cannot show config history because it does not contain 'process'.\nNote that only 'cfg' files contain a 'process'.")
210 dialog=
TextDialog(self.
tab(),
"Configuration history", history,
True,
"This window lists the parameter changes and tools applied in this configuration file before it was loaded into ConfigEditor.")
214 """ Open event content dialog """ 215 logging.debug(__name__ +
": eventContent")
216 if event_content_error!=
None:
217 logging.error(__name__ +
": Could not import EventContentDialog: "+event_content_error[1])
218 self.
plugin().application().errorMessage(
"Could not import EventContentDialog (see logfile for details):\n"+event_content_error[0])
220 dialog=
EventContentDialog(self.
tab(),
"This dialog let's you check if the input needed by your configuration file is in a dataformat or edm root file. You can compare either to a dataformat definition from a txt file (e.g. RECO_3_3_0) or any edm root file by selecting an input file.\n\nBranches that are used as input by your configuration but not present in the dataformat or file are marked in red.\nBranches that are newly created by your configuration are marked in green.")
225 """ read options from ini """ 226 ini = self.
plugin().application().ini()
227 if ini.has_option(
"config",
"editor"):
231 if ini.has_option(
"config",
"CurrentView"):
232 proposed_view = ini.get(
"config",
"CurrentView")
234 proposed_view = self.
plugin().viewClassId(ConnectionStructureView)
236 if ini.has_option(
"config",
"box content script")
and isinstance(self.
centerView(),ConfigEditorBoxView):
237 self.
centerView().setBoxContentScript(
str(ini.get(
"config",
"box content script")))
238 self._boxContentDialog.setScript(
str(ini.get(
"config",
"box content script")))
241 BrowserTabController.scriptChanged(self, script)
245 """ write options to ini """ 246 ini = self.
plugin().application().ini()
247 if not ini.has_section(
"config"):
248 ini.add_section(
"config")
252 if isinstance(self.
centerView(),ConfigEditorBoxView):
253 ini.set(
"config",
"box content script", self.
centerView().boxContentScript())
254 self.
plugin().application().writeIni()
257 if import_dotexport_error!=
None:
258 logging.error(__name__ +
": Could not import DOTExport: "+import_dotexport_error[1])
259 self.
plugin().application().errorMessage(
"Could not import DOTExport (see logfile for details):\n"+import_dotexport_error[0])
263 presets = {
'seqconnect':
False,
'tagconnect':
True,
'seq':
False,
'services':
False,
'es':
False,
'endpath':
True,
'source':
True,
'legend':
False}
265 presets = {
'seqconnect':
True,
'tagconnect':
False,
'seq':
True,
'services':
False,
'es':
False,
'endpath':
True,
'source':
True,
'legend':
False}
266 for opt, val
in presets.items():
267 dot.setOption(opt, val)
269 for ft
in dot.file_types:
272 types += ft.upper() +
" File (*." + ft.lower() +
")" 273 filter = QString(
"PDF File (*.pdf)")
275 defaultname = os.path.splitext(self.
_filename)[0] +
"_export" 276 fileName =
str(QFileDialog.getSaveFileName(self.
tab(),
"Export dot graphic...", defaultname, types, filter))
279 ext =
str(filter).
split(
" ")[0].lower()
280 if os.path.splitext(fileName)[1].lower().
strip(
".")
in dot.file_types:
281 name = os.path.splitext(fileName)[0]
282 ext = os.path.splitext(fileName)[1].lower().
strip(
".")
288 logging.error(self.__class__.__name__ +
": exportDot() - "+
"'dot' executable not found which is needed for conversion to '*." + ext +
"'. Created '*.dot' file instead.")
289 self.
plugin().application().errorMessage(
"'dot' executable not found which is needed for conversion to '*." + ext +
"'. Created '*.dot' file instead.")
290 except Exception
as e:
291 logging.error(self.__class__.__name__ +
": exportDot() - "+
"Could not export dot graphic (see logfile for details): " +
str(e))
295 """ Reads in the file in a separate thread. 303 if self.
plugin().application().commandLineOptions().saveimage:
305 self.
saveImage(self.
plugin().application().commandLineOptions().saveimage)
306 print(
"Saved image to", self.
plugin().application().commandLineOptions().saveimage,
".")
312 logging.debug(__name__ +
': save')
315 if os.path.basename(filename) == os.path.basename(self.
dataAccessor().configFile()):
316 logging.error(self.__class__.__name__ +
": save() - "+
"Cannot use name of original configuration file: "+
str(filename))
317 self.
plugin().application().errorMessage(
"Cannot use name of original configuration file.")
318 elif BrowserTabController.save(self, filename):
324 return BrowserTabController.save(self, filename)
325 return self.
tab().mainWindow().application().saveFileAsDialog()
328 """ Write replace config file. 330 logging.debug(__name__ +
': writeFile')
332 text_file =
open(filename,
"w")
339 def open(self, filename=None, update=True):
340 if BrowserTabController.open(self, filename, update):
347 logging.debug(__name__ +
": startEditMode")
348 if import_tools_error!=
None:
349 logging.error(__name__ +
": Could not import tools for ConfigEditor: "+import_tools_error[1])
350 self.
plugin().application().errorMessage(
"Could not import tools for ConfigEditor (see logfile for details):\n"+import_tools_error[0])
352 if self.
tab().editorSplitter():
355 logging.error(__name__ +
": Config does not contain a process and cannot be edited using ConfigEditor.")
356 self.
plugin().application().errorMessage(
"Config does not contain a process and cannot be edited using ConfigEditor.")
361 self.
tab().createEditor()
374 self._toolDataAccessor.setConfigDataAccessor(self.
dataAccessor())
379 self.connect(self.
tab().editorTableView(), SIGNAL(
'selected'), self.
codeSelected)
380 self.connect(self.
tab().propertyView(), SIGNAL(
'valueChanged'), self.
valueChanged)
387 if self.
tab().originalButton().isChecked():
389 self.
tab().minimizeButton().setChecked(
True)
390 self.
tab().originalButton().setChecked(
False)
391 self.
tab().maximizeButton().setChecked(
False)
392 self.
tab().verticalSplitter().setSizes([100, 1, 0])
395 self.
tab().minimizeButton().setChecked(
False)
396 self.
tab().originalButton().setChecked(
True)
397 self.
tab().maximizeButton().setChecked(
False)
401 if self.
tab().originalButton().isChecked():
403 self.
tab().minimizeButton().setChecked(
False)
404 self.
tab().originalButton().setChecked(
False)
405 self.
tab().maximizeButton().setChecked(
True)
406 self.
tab().verticalSplitter().setSizes([0, 1, 100])
409 logging.debug(__name__ +
": _updateCode")
410 self.
tab().propertyView().setEnabled(
False)
414 self.
tab().editorTableView().restoreSelection()
416 self.
tab().propertyView().setEnabled(
True)
419 logging.debug(__name__ +
": importConfig")
420 statusMessage = self.
plugin().application().startWorking(
"Import python configuration in Editor")
422 good=self.
open(filename,
False)
425 self.
plugin().application().errorMessage(
"Could not open configuration file (see log file for details).")
426 self.
plugin().application().stopWorking(statusMessage,
"failed")
429 logging.error(__name__ +
": Could not open configuration file.")
430 self.
plugin().application().errorMessage(
"Could not open configuration file.")
431 self.
plugin().application().stopWorking(statusMessage,
"failed")
434 logging.error(__name__ +
": Config does not contain a process and cannot be edited using ConfigEditor.")
435 self.
plugin().application().errorMessage(
"Config does not contain a process and cannot be edited using ConfigEditor.")
436 self.
plugin().application().stopWorking(statusMessage,
"failed")
442 self.
tab().propertyView().setDataObject(
None)
444 self._applyPatToolAction.setVisible(
True)
445 self.
plugin().application().stopWorking(statusMessage)
455 logging.debug(__name__ +
": importButtonClicked")
456 filename = QFileDialog.getOpenFileName(
457 self.
tab(),
'Select a configuration file',standardConfigDir,
"Python configuration (*.py)")
458 if not filename.isEmpty():
462 logging.debug(__name__ +
": applyButtonClicked")
466 if not self._toolDialog.exec_():
472 self.
tab().editorTableView().
select(self.
tab().editorTableView().dataObjects()[-2])
476 logging.debug(__name__ +
": removeButtonClicked")
478 self._toolDataAccessor.label(object)
in [
"Import",
"ApplyTool"]:
481 self.
plugin().application().errorMessage(
"Could not apply tool. See log file for details.")
485 self.
tab().editorTableView().
select(self.
tab().editorTableView().dataObjects()[-1])
490 BrowserTabController.onSelected(self, select)
493 self.
tab().propertyView().setDataObject(
None)
494 BrowserTabController.refresh(self)
497 if import_tools_error==
None and isinstance(object,ConfigToolBase):
501 BrowserTabController.updateContent(self, filtered, propertyView)
505 BrowserTabController.select(self, object)
508 if import_tools_error==
None and isinstance(object,ConfigToolBase):
514 if self.
tab().propertyView().dataObject() != select:
515 statusMessage = self.
plugin().application().startWorking(
"Updating property view")
517 self.
tab().propertyView().setDataObject(select)
519 self.
plugin().application().stopWorking(statusMessage)
523 if isinstance(self.
tab().propertyView().dataObject(),ConfigToolBase):
524 if self._toolDataAccessor.label(self.
tab().propertyView().dataObject())==
"Import":
525 filename=self.
toolDataAccessor().propertyValue(self.
tab().propertyView().dataObject(),
"filename")
def onTreeViewSelected(self, select)
def open(self, filename=None, update=True)
def chooseEditor(self, _editorName="")
def selectDataAccessor(self, object)
def saveImage(self, filename=None)
def exception_traceback()
def setModified(self, modified=True)
def dotExportAction(self)
S & print(S &os, JobReport::InputFile const &f)
def writeFile(self, filename)
def open(self, filename=None, update=True)
def save(self, filename='')
def __init__(self, plugin)
def onCenterViewDoubleClicked(self, object)
def scriptChanged(self, script)
def toolDataAccessor(self)
def readFile(self, filename)
def staticSupportedFileTypes()
def setFilename(self, filename)
def dumpPython(self, fileName=None)
def currentCenterViewClassId(self)
def setEditable(self, editable)
def valueChanged(self, name)
def setDataAccessor(self, accessor)
def codeSelected(self, select)
def onSelected(self, select)
def removeButtonClicked(self, object)
def updateCenterView(self, propertyView=True)
def _updateCode(self, propertyView=True)
def updateConfigHighlight(self)
def importConfig(self, filename)
def applyButtonClicked(self)
def updateLabel(self, prefix="", titletext="")
def exportDot(self, fileName=None)
def switchCenterView(self, requestedViewClassId)
def importButtonClicked(self)
def updateContent(self, filtered=False, propertyView=True)