summaryrefslogtreecommitdiff
path: root/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py')
-rw-r--r--src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py997
1 files changed, 0 insertions, 997 deletions
diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py
deleted file mode 100644
index e073f0e5..00000000
--- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py
+++ /dev/null
@@ -1,997 +0,0 @@
-#!/usr/bin/env python
-
-##############################################################################
-##
-## This file is part of Sardana
-##
-## http://www.sardana-controls.org/
-##
-## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
-##
-## Sardana is free software: you can redistribute it and/or modify
-## it under the terms of the GNU Lesser General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## Sardana 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.
-##
-## You should have received a copy of the GNU Lesser General Public License
-## along with Sardana. If not, see <http://www.gnu.org/licenses/>.
-##
-##############################################################################
-
-"""
-sequenceeditor.py:
-"""
-
-import sys
-from copy import deepcopy
-
-import PyTango
-
-from taurus.external.qt import Qt
-from taurus import Device
-from taurus.qt.qtgui.container import TaurusWidget, TaurusMainWindow, TaurusBaseContainer
-from taurus.qt.qtgui.display import TaurusLed
-from taurus.qt.qtgui.dialog import TaurusMessageBox
-from taurus.qt.qtgui.resource import getIcon, getThemeIcon
-
-from sardana.taurus.core.tango.sardana import macro
-from sardana.taurus.core.tango.sardana.macro import MacroRunException
-from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor import ParamEditorManager, ParamEditorModel, StandardMacroParametersEditor
-
-from .favouriteseditor import FavouritesMacrosEditor, HistoryMacrosViewer
-from .common import MacroComboBox, MacroExecutionWindow, standardPlotablesFilter
-
-
-class MacroProgressBar(Qt.QProgressBar):
-
- def __init__(self, parent=None):
- Qt.QProgressBar.__init__(self, parent)
-
-class SpockCommandWidget(Qt.QLineEdit, TaurusBaseContainer):
- def __init__(self, name, parent=None, designMode=False):
- #self.newValue - is used as a flag to indicate whether a controlUp controlDown actions are used to iterate existing element or put new one
- #self.disableEditMode - flag, used to disable edition, when user enters name of the macro which is not valid (not allowed to edit in the yellow line)
- # switches off validation
- #disableSpockCommandUpdate - flag, it disables updates of the model when macro is edited by macroEditor
-
- Qt.QLineEdit.__init__(self, parent)
- TaurusBaseContainer.__init__(self, name, parent, designMode)
-
- self._model = None
- self.setFont(Qt.QFont("Courier", 9))
- palette = Qt.QPalette()
- palette.setColor(Qt.QPalette.Base, Qt.QColor('yellow'))
- self.setPalette(palette)
- self.currentIndex = Qt.QModelIndex()
- self.newValue = False
- self.disableSpockCommandUpdate = False
- self.disableEditMode = True
- self.setEnabled(False)
-
- self.setActions()
- self.connect(self, Qt.SIGNAL("textChanged(const QString &)"), self.textChanged)
- self.connect(self, Qt.SIGNAL("returnPressed()"), self.returnPressed)
-
- def setActions(self):
- self._downAction = Qt.QAction("downAction", self)
- self._upAction = Qt.QAction("upAction", self)
- self._ctrlDownAction = Qt.QAction("controlDownAction", self)
- self._ctrlUpAction = Qt.QAction("controlUpAction", self)
-
- self._ctrlDownAction.setShortcut(Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Down))
- self._ctrlUpAction.setShortcut(Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Up))
- self._downAction.setShortcuts([Qt.Qt.Key_Down])
- self._upAction.setShortcuts([Qt.Qt.Key_Up])
-
- self._ctrlDownAction.setShortcutContext (Qt.Qt.WidgetShortcut)
- self._ctrlUpAction.setShortcutContext (Qt.Qt.WidgetShortcut)
- self._downAction.setShortcutContext (Qt.Qt.WidgetShortcut)
- self._upAction.setShortcutContext (Qt.Qt.WidgetShortcut)
-
- self.addAction(self._ctrlDownAction)
- self.addAction(self._ctrlUpAction)
- self.addAction(self._downAction)
- self.addAction(self._upAction)
- self.connect(self._downAction, Qt.SIGNAL("triggered()"), self.downAction)
- self.connect(self._upAction, Qt.SIGNAL("triggered()"), self.upAction)
- self.connect(self._ctrlDownAction, Qt.SIGNAL("triggered()"), self.controlDownAction)
- self.connect(self._ctrlUpAction, Qt.SIGNAL("triggered()"), self.controlUpAction)
-
- def setCommand(self):
- command = self._model.toSpockCommand()
- command = command.replace("None", "").strip()
- if not self.disableSpockCommandUpdate:
- self.setText(command)
-
- def setModel(self, model):
- enable = bool(model)
- self.disableEditMode = not enable
- self.setEnabled(enable)
- self._model = model
- self.connect(self._model, Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), self.setCommand)
- self.connect(self._model, Qt.SIGNAL("modelReset()"), self.setCommand)
-
- def model(self):
- return self._model
-
- def getIndex(self, elementNumber=-1):
- #Returns QModelIndex of the required element (number of single parameter). If the elementNumber == -1 next single parameter index is returned.
- if elementNumber == -1:
- ix = self.currentIndex
- elementNumber = 1
- elif elementNumber == 0:
- return Qt.QModelIndex()
- else:
- ix = Qt.QModelIndex()
-
- (col, row, parentIdx) = (ix.column(), ix.row(), ix.parent())
- #to start from second column
- if col == -1 and row == -1:
- ix = self.forwardIdx(0, 1, ix)
- for i in range (0, elementNumber):
- #This condition in case we start tabbing with cursor on first column
- if col == 0:
- currentNode = self.model().nodeFromIndex(ix)
- if isinstance(currentNode, macro.SingleParamNode):
- nextIdx = self.forwardIdx(row, 1, parentIdx)
- else:
- nextIdx = self.forwardIdx(0, 1, ix)
- else:
- nextIdx = self.forwardIdx(row + 1, 1, parentIdx)
- #this condition in case there is no next index and we want to pass focus
- #to next widget in parent obj
- if nextIdx == "term":
- return Qt.QModelIndex()
- ix = nextIdx
- (col, row, parentIdx) = (ix.column(), ix.row(), ix.parent())
- return ix
-
- def forwardIdx(self, row, col, parentIdx):
- #This method is moving down the tree to get next SingleParamNode index.
- try:
- proposalIdx = self.model().index(row, col, parentIdx)
- except AssertionError:
-
- if parentIdx.row() == -1:
- return Qt.QModelIndex()
- grandParentIdx = parentIdx.parent()
- return self.forwardIdx(parentIdx.row() + 1, col, grandParentIdx)
-
- proposalNode = self.model().nodeFromIndex(proposalIdx)
-
- if isinstance(proposalNode, macro.SingleParamNode):
- return proposalIdx
- elif isinstance(proposalNode, macro.RepeatNode):
- return self.forwardIdx(0, 1, proposalIdx)
- elif isinstance(proposalNode, macro.RepeatParamNode):
- if len(proposalNode) > 0:
- return self.forwardIdx(0, 1, proposalIdx)
- else:
- return self.forwardIdx(row + 1, col, proposalIdx)
-
- elif not proposalIdx.isValid():
- proposalIdx = parentIdx.sibling(parentIdx.row() + 1, 0)
-
- if proposalIdx.isValid():
- proposalIdx = proposalIdx.child(0, 1)
- else:
- while not proposalIdx.isValid():
- parentIdx = parentIdx.parent()
- if not parentIdx.isValid():
-
- return Qt.QModelIndex()
- proposalIdx = parentIdx.sibling(parentIdx.row() + 1, 1)
-
- return proposalIdx
-
- def validateAllExpresion(self, secValidation=False):
- #This method is responsible for full validation of the macro. It is executed whenever the text is changed (when user edits values).
- #Validation starts with checking if the macro (name) is valid.
- #Next steps:
- #1. Validates every SingleParamNode and counts how many there are in the macro.
- #2. If there are more SingleParamNodes than entered values it will check if there is RepeatParamNode.
- # If there is RepeatParamNode it will check if its RepeatNodes can be deleted.
- #3. If there are more values entered than SingleParamNodes in macro it will check if there is RepeatParamNode.
- # If there is it will try to add new RepeatNode.
-
- if self.model() is None:
- raise RuntimeError('Door must be set in order to use the macroexecutor.')
-
- self.currentIndex = Qt.QModelIndex()
- mlist = str(self.text()).split()
- problems = []
- try:
- if str(mlist[0]) != str(self.model().root().name()):
- try:
- self.getModelObj().validateMacroName(str(mlist[0]))
- self.validateMacro(mlist[0])
- self.updateMacroEditor(mlist[0])
- if not secValidation:
- self.validateAllExpresion(True)
-
- except Exception as e:
- if self.disableEditMode:
- self.updateMacroEditor(mlist[0])
- raise Exception(e)
- message = e[0]
- #raise Exception(e)
- problems.append(message)
-
- except IndexError:
- problems.append("<b>Macro<\b> is missing!")
- self.setStyleSheet("")
- self.setToolTip('<br>'.join(problems))
- return
-
- self.currentIndex = Qt.QModelIndex()
- ix = self.getIndex()
- self.currentIndex = ix
- counter = 1
- while not ix == Qt.QModelIndex():
- try:
- propValue = mlist[counter]
- try:
- self.validateOneValue(propValue)
- self.model().setData(self.currentIndex, Qt.QVariant(propValue))
- except Exception as e:
- self.model().setData(self.currentIndex, Qt.QVariant('None'))
- txt = str(Qt.from_qvariant(ix.sibling(ix.row(), 0).data(), str))
- message = "<b>" + txt + "</b> " + e[0]
- problems.append(message)
- except IndexError:
- txt = str(Qt.from_qvariant(ix.sibling(ix.row(), 0).data(), str))
- problems.append("<b>" + txt + "</b> is missing!")
-
- data = str(Qt.from_qvariant(ix.data(), str))
- if data != 'None':
- self.model().setData(self.currentIndex, Qt.QVariant('None'))
- counter += 1
- ix = self.getIndex()
- self.currentIndex = ix
-
- if len(mlist) > counter: #if there are more values than parameters
- repeatNode = None
- for i in self.model().root().params():
- repeatNode = i
- if isinstance(repeatNode, macro.RepeatParamNode):
- index = self.findParamRepeat(i)
- self.currentIndex = self.model()._insertRow(index)
- nn = self.model().nodeFromIndex(self.currentIndex)
- self.emit(Qt.SIGNAL("expandTree"))
- ix = self.getIndex()
- if not secValidation:
- self.validateAllExpresion(True)
- return
-
- repeatNode = None
- if repeatNode == None:
- problems.append("Too many values.")
-
- elif counter - len(mlist) >= 1:
- repeatNode = None
- node = None
- for i in self.model().root().params():
- repeatNode = i
- if isinstance(repeatNode, macro.RepeatParamNode):
- index = self.findParamRepeat(i)
- node = self.model().nodeFromIndex(index)
- sub = len(node.child(0))
- break
- repeatNode = None
-
- if repeatNode is not None:
- while counter - len(mlist) > sub - 1:
- if len(node.children()) == 1 and node.isReachedMin():
- break
- self.model()._removeRow(index.child(len(node.children()) - 1, 0))
- counter -= sub
-
- if not secValidation:
- self.validateAllExpresion(True)
- return
-
- if len(problems) == 0:
- self.setStyleSheet('SpockCommandWidget {background-color: %s; color: %s; border: %s; border-radius: %s}' % ('yellow', 'black', '3px solid green', '5px'))
- self.setToolTip("")
- else:
- self.setStyleSheet("")
- self.setToolTip('<br>'.join(problems))
- return
-
- def findParamRepeat(self, repeatNode):
- #Method which finds index of given ParamRepeatNode in the macro.
- children = self.model().root().children()
- occ = children.count(repeatNode)
- idx = 0
- for i in range(0, occ):
- idx = children.index(repeatNode, idx)
- index = self.model().index(idx , 0, Qt.QModelIndex())
- return index
-
- def validateOneValue(self, value):
- #Validates value of a SingleParamNode of a currentIndex
- paramNode = deepcopy(self.model().nodeFromIndex(self.currentIndex))
- paramNode.setValue(value)
- return self.getModelObj().validateSingleParam(paramNode)
-
- def returnPressed(self):
- #SLOT called when return is pressed
- if self.toolTip() == "":
- self.emit(Qt.SIGNAL("pressedReturn"))
- else:
- raise Exception("Cannot start macro. Please correct following mistakes: <br>" + self.toolTip())
-
- def textChanged(self, strs):
- #SLOT called when QLineEdit text is changed
- if strs == "":
- self.updateMacroEditor("")
-
- if not self.disableEditMode and self.disableSpockCommandUpdate:
- self.validateAllExpresion()
- else:
- txt_parts = str(self.text()).split()
- if len(txt_parts) == 0:
- return
- try:
- if self.validateMacro(txt_parts[0]):
- self.validateAllExpresion()
- except:
- self.setToolTip("Read Mode")
-
- def validateMacro(self, value):
- #Method which ivestigates if the macro can be edited using yellow line.
- #It cannot be executed when: 1. there are more than 1 ParamRepeatNodes,
- #2. There is a ParamRepeatNode inside ParamRepeatNodem
- #3. After ParamRepeatNode there are other nodes
-
- macroNode = self.getModelObj().getMacroNodeObj(str(value))
- if macroNode is None: return False
- t = [child for child in macroNode.children() if isinstance(child, macro.RepeatParamNode)]
- if len(t) > 1:
- self.disableEditMode = True
- raise Exception('Macro <b> %s </b> cannot be edited using yellow line.<br>It contains more than 1 paramRepeat node. <br>Please use Macro Editor Widget to edit and execute this macro.' % str(value))
- elif len(t) == 1:
- if len([child for child in t[0].children() if isinstance(child, macro.RepeatParamNode)]) > 0:
- self.disableEditMode = True
- raise Exception('Macro <b> %s </b> cannot be edited using yellow line.<br>It contains paramRepeat node inside paramRepeat node. <br>Please use Macro Editor Widget to edit and execute this macro.' % str(value))
- else:
- if macroNode.children().index(t[0]) != len(macroNode.children()) - 1 :
- self.disableEditMode = True
- raise Exception('Macro <b> %s </b> cannot be edited using yellow line.<br>It contains paramRepeat node but not as a last parameter. <br>Please use Macro Editor Widget to edit and execute this macro.' % str(value))
- self.disableEditMode = False
- return True
-
- def downAction(self):
- #Goes down in the history list of executed macros.
- #self.disableSpockCommandUpdate flag is used to allow updating yellow line when model is changed. (when new row in history is chosen)
-
- self.disableSpockCommandUpdate = False
- self.emit(Qt.SIGNAL("elementDown"))
- text = str(self.text()).split()
- if len(text) > 0:
- self.validateMacro(text[0])
- self.disableSpockCommandUpdate = True
-
- def upAction(self):
- self.disableSpockCommandUpdate = False
- self.emit(Qt.SIGNAL("elementUp"))
- text = str(self.text()).split()
- if len(text) > 0:
- self.validateMacro(text[0])
- self.disableSpockCommandUpdate = True
-
- def controlDownAction(self):
- c = self.cursorPosition()
- newValue = False
- try:
- if self.text()[c] == " " and self.text()[c - 1] == " ":
- newValue = True
- except IndexError:
- if c == 0:
- newValue = True
- elif len(self.text()) == self.cursorPosition() and self.text()[c - 1] == " ":
- newValue = True
- try:
- txt = str(self.text())
- txt = txt[:txt.find(" ", c)]
- except IndexError:
- txt = str(self.text())[:c]
- elementsNum = txt.split()
-
- if newValue:
- self.insert("0")
- self.currentIndex = self.getIndex(len(elementsNum))
- if not self.currentIndex.isValid():
- if len(elementsNum) > 0:
- self.backspace()
- return
- value = self.prevValue("")
- self.backspace()
- self.insert(value)
- self.model().setData(self.currentIndex, Qt.QVariant(value))
- else:
- self.currentIndex = self.getIndex(len(elementsNum) - 1)
- if not self.currentIndex.isValid():
- if len(elementsNum) > 1:
- return
- value = self.prevValue(elementsNum[len(elementsNum) - 1])
- sel = self.measureSelection(self.cursorPosition())
- self.setSelection(sel[0], sel[1])
- c = c - (sel[1] - len(str(value)))
- self.insert(value)
- self.setCursorPosition(c)
- self.model().setData(self.currentIndex, Qt.QVariant(value))
-
- def controlUpAction(self):
- c = self.cursorPosition()
- newValue = False
- try:
- if self.text()[c] == " " and self.text()[c - 1] == " ":
- newValue = True
- except IndexError:
- if c == 0:
- newValue = True
- elif len(self.text()) == self.cursorPosition() and self.text()[c - 1] == " ":
- newValue = True
- try:
- txt = str(self.text())
- txt = txt[:txt.find(" ", c)]
- except IndexError:
- txt = str(self.text())[:c]
- elementsNum = txt.split()
-
- if newValue:
- self.insert("0")
- self.currentIndex = self.getIndex(len(elementsNum))
- if not self.currentIndex.isValid():
- if len(elementsNum) > 0:
- self.backspace()
- return
- value = self.nextValue("")
- self.backspace()
- self.insert(value)
- self.model().setData(self.currentIndex, Qt.QVariant(value))
- else:
- self.currentIndex = self.getIndex(len(elementsNum) - 1)
- if not self.currentIndex.isValid():
- if len(elementsNum) > 1:
- return
- value = self.nextValue(elementsNum[len(elementsNum) - 1])
- sel = self.measureSelection(self.cursorPosition())
- self.setSelection(sel[0], sel[1])
- c = c - (sel[1] - len(str(value)))
- self.insert(value)
- self.setCursorPosition(c)
- self.model().setData(self.currentIndex, Qt.QVariant(value))
-
- def getParamItems(self, index):
- #Returns list of items that can be chosen for the node corresponding to the given index. Used by {next,prev}Value methods
-
- node = self.model().nodeFromIndex(index)
- if isinstance(node, macro.MacroNode):
- return None
- type = node.type()
- ms = self.getParentModelObj()
- items = ms.getElementsWithInterface(type).keys()
- return items, type
-
- def nextValue(self, current):
- current = str(current)
- if self.currentIndex.isValid():
- items, type = self.getParamItems(self.currentIndex)
- items = sorted(items)
- else:
- items = self.getParentModelObj().getMacroStrList()
- items = sorted(items)
- type = "Macro"
-
- if type == "Float":
- value = float(current) + 0.1
- elif type == "Integer":
- value = int(current) + 1
- elif type == "Boolean":
- value = True
- else:
- try:
- textindex = items.index(current)
- value = items[textindex - 1]
- except:
- tmpitems = [s for s in items if s.startswith(current)]
- if len(tmpitems) > 0:
- value = tmpitems[0]
- else:
- value = items[0]
- return str(value)
-
- def prevValue(self, current):
- current = str(current)
- if self.currentIndex.isValid():
- items, type = self.getParamItems(self.currentIndex)
- items = sorted(items)
- else:
- items = self.getParentModelObj().getMacroStrList()
- items = sorted(items)
- type = "Macro"
-
- if type == "Float":
- value = float(current) - 0.1
- elif type == "Integer":
- value = int(current) - 1
- elif type == "Boolean":
- value = True
- else:
- try:
- textindex = items.index(current)
- value = items[textindex + 1]
- except:
- tmpitems = [s for s in items if s.startswith(current)]
- if len(tmpitems) > 0:
- value = tmpitems[0]
- else:
- value = items[0]
- return str(value)
-
- def updateMacroEditor(self, macroName):
- #I had to make the macroname lowered as macros in comboBox (with macros), has names with all letter low.
- #Because of that sometimes it was not loading macros in MacroEditor
- #TO FIX
- self.emit(Qt.SIGNAL("spockComboBox"), str(macroName).lower())
-
- def measureSelection(self, position):
- s = str(self.text()) + " "
- try:
- if s[position] == " ":
- position -= 1
- except IndexError:
- position -= 1
- end = s.find(' ', position)
- beg = s.rfind(' ', 0, position + 1)
- if end == -1:
- end = s.length() - 1
- return beg + 1, end - beg - 1 #returns the start and length of the value
-
- def focusInEvent(self, event):
- self.disableSpockCommandUpdate = True
- Qt.QLineEdit.focusInEvent(self, event)
-
- def focusOutEvent(self, event):
- self.disableSpockCommandUpdate = False
- Qt.QLineEdit.focusOutEvent(self, event)
-
-class TaurusMacroExecutorWidget(TaurusWidget):
-
- def __init__(self, parent=None, designMode=False):
- TaurusWidget.__init__(self, parent, designMode)
- self.setObjectName(self.__class__.__name__)
-
- self._doorName = ""
- self._macroId = None
- self.setLayout(Qt.QVBoxLayout())
- self.layout().setContentsMargins(0, 0, 0, 0)
-
- self.addToFavouritesAction = Qt.QAction(getThemeIcon("software-update-available"), "Add to favourites", self)
- self.connect(self.addToFavouritesAction, Qt.SIGNAL("triggered()"), self.onAddToFavourites)
- self.addToFavouritesAction.setToolTip("Add to favourites")
- self.stopMacroAction = Qt.QAction(getIcon(":/actions/media_playback_stop.svg"), "Stop macro", self)
- self.connect(self.stopMacroAction, Qt.SIGNAL("triggered()"), self.onStopMacro)
- self.stopMacroAction.setToolTip("Stop macro")
- self.pauseMacroAction = Qt.QAction(getIcon(":/actions/media_playback_pause.svg"), "Pause macro", self)
- self.connect(self.pauseMacroAction, Qt.SIGNAL("triggered()"), self.onPauseMacro)
- self.pauseMacroAction.setToolTip("Pause macro")
- self.playMacroAction = Qt.QAction(getIcon(":/actions/media_playback_start.svg"), "Start macro", self)
- self.connect(self.playMacroAction, Qt.SIGNAL("triggered()"), self.onPlayMacro)
- self.playMacroAction.setToolTip("Start macro")
- actionsLayout = Qt.QHBoxLayout()
- actionsLayout.setContentsMargins(0, 0, 0, 0)
- addToFavouritsButton = Qt.QToolButton()
- addToFavouritsButton.setDefaultAction(self.addToFavouritesAction)
- self.addToFavouritesAction.setEnabled(False)
- actionsLayout.addWidget(addToFavouritsButton)
-
- self.macroComboBox = MacroComboBox(self)
- self.macroComboBox.setUseParentModel(True)
- self.macroComboBox.setModelColumn(0)
- actionsLayout.addWidget(self.macroComboBox)
- stopMacroButton = Qt.QToolButton()
- stopMacroButton.setDefaultAction(self.stopMacroAction)
- actionsLayout.addWidget(stopMacroButton)
- pauseMacroButton = Qt.QToolButton()
- pauseMacroButton.setDefaultAction(self.pauseMacroAction)
- actionsLayout.addWidget(pauseMacroButton)
- self.playMacroButton = Qt.QToolButton()
- self.playMacroButton.setDefaultAction(self.playMacroAction)
- actionsLayout.addWidget(self.playMacroButton)
- self.disableControlActions()
- self.doorStateLed = TaurusLed(self)
- actionsLayout.addWidget(self.doorStateLed)
- self.layout().addLayout(actionsLayout)
-
- splitter = Qt.QSplitter(self)
- self.layout().addWidget(splitter)
- splitter.setOrientation(Qt.Qt.Vertical)
-
- self._paramEditorModel = ParamEditorModel()
- self.stackedWidget = Qt.QStackedWidget()
- self.standardMacroParametersEditor = StandardMacroParametersEditor(self.stackedWidget)
- self.stackedWidget.addWidget(self.standardMacroParametersEditor)
- self.customMacroParametersEditor = None
- splitter.addWidget(self.stackedWidget)
-
- self._favouritesBuffer = None
- self.favouritesMacrosEditor = FavouritesMacrosEditor(self)
- self.registerConfigDelegate(self.favouritesMacrosEditor)
- self.favouritesMacrosEditor.setUseParentModel(True)
- self.favouritesMacrosEditor.setFocusPolicy(Qt.Qt.NoFocus)
-
- self._historyBuffer = None
- self.historyMacrosViewer = HistoryMacrosViewer(self)
- self.registerConfigDelegate(self.historyMacrosViewer)
- self.historyMacrosViewer.setUseParentModel(True)
- self.historyMacrosViewer.setFocusPolicy(Qt.Qt.NoFocus)
-
- self.tabMacroListsWidget = Qt.QTabWidget(self)
- self.tabMacroListsWidget.addTab(self.favouritesMacrosEditor, "Favourite list")
- self.tabMacroListsWidget.addTab(self.historyMacrosViewer, "History Viewer")
- splitter.addWidget(self.tabMacroListsWidget)
-
- self._isHistoryMacro = False
- self.macroProgressBar = MacroProgressBar(self)
- self.layout().addWidget(self.macroProgressBar)
-
- #spockCommandLabel = Qt.QLabel("Spock command:", self)
- #spockCommandLabel.setFont(Qt.QFont("Courier",9))
- self.spockCommand = SpockCommandWidget("Spock", self)
- self.spockCommand.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum)
- self.spockCommand.setUseParentModel(True)
- spockCommandLayout = Qt.QHBoxLayout()
- spockCommandLayout.setContentsMargins(0, 0, 0, 0)
- #spockCommandLayout.addWidget(spockCommandLabel)
- spockCommandLayout.addWidget(self.spockCommand)
- self.layout().addLayout(spockCommandLayout)
- self.connect(self.macroComboBox, Qt.SIGNAL("currentIndexChanged(QString)"), self.onMacroComboBoxChanged)
- self.connect(self.favouritesMacrosEditor.list, Qt.SIGNAL("favouriteSelected"), self.onFavouriteSelected)
- self.connect(self.historyMacrosViewer.list, Qt.SIGNAL("historySelected"), self.onHistorySelected)
-
- self.connect(self.spockCommand, Qt.SIGNAL("pressedReturn"), self.onPlayMacro)
- self.connect(self.spockCommand, Qt.SIGNAL("spockComboBox"), self.setComboBoxItem)
- self.connect(self.spockCommand, Qt.SIGNAL("elementUp"), self.setHistoryUp)
- self.connect(self.spockCommand, Qt.SIGNAL("elementDown"), self.setHistoryDown)
- self.connect(self.spockCommand, Qt.SIGNAL("setHistoryFocus"), self.setHistoryFocus)
- self.connect(self.spockCommand, Qt.SIGNAL("expandTree"), self.standardMacroParametersEditor.tree.expandAll)
-
- def macroId(self):
- return self._macroId
-
- def contextMenuEvent(self, event):
- menu = Qt.QMenu()
- action = menu.addAction(getThemeIcon("view-refresh"), "Check door state", self.checkDoorState)
- menu.exec_(event.globalPos())
-
- def checkDoorState(self):
- door = Device(self.doorName())
- doorState = door.state()
- if doorState == PyTango.DevState.RUNNING:
- self.playMacroAction.setEnabled(False)
- self.pauseMacroAction.setEnabled(True)
- self.stopMacroAction.setEnabled(True)
- elif doorState == PyTango.DevState.ON or doorState == PyTango.DevState.ALARM:
- self.playMacroAction.setEnabled(True)
- self.pauseMacroAction.setEnabled(False)
- self.stopMacroAction.setEnabled(False)
- elif doorState == PyTango.DevState.STANDBY:
- self.playMacroAction.setEnabled(True)
- self.pauseMacroAction.setEnabled(False)
- self.stopMacroAction.setEnabled(True)
-
- def setMacroId(self, macroId):
- self._macroId = macroId
-
- def doorName(self):
- return self._doorName
-
- def setDoorName(self, doorName):
- self._doorName = doorName
-
- def setFavouritesBuffer(self, favouritesMacro):
- self._favouritesBuffer = favouritesMacro
-
- #History Widget
- def setHistoryUp(self):
- self.setHistoryFocus()
- self.historyMacrosViewer.listElementUp()
-
- def setHistoryDown(self):
- self.setHistoryFocus()
- self.historyMacrosViewer.listElementDown()
-
- def setHistoryFocus(self):
- self.tabMacroListsWidget.setCurrentWidget(self.historyMacrosViewer)
- #self.historyMacrosViewer.setFocus()
-
- def historyBuffer(self):
- return self._historyBuffer
-
- def setHistoryBuffer(self, favouritesMacro):
- self._historyBuffer = favouritesMacro
-
- def favouritesBuffer(self):
- return self._favouritesBuffer
-
- def paramEditorModel(self):
- return self._paramEditorModel
-
- def setParamEditorModel(self, paramEditorModel):
- self._paramEditorModel = paramEditorModel
-
- def setComboBoxItem(self, macroName):
- self.macroComboBox.selectMacro(macroName)
-
- def onMacroComboBoxChanged(self, macroName):
- macroName = str(macroName)
- if macroName == "":
- macroName, macroNode = None, None
-# macroNode = macro.MacroNode(name="")
- self.playMacroAction.setEnabled(False)
- self.addToFavouritesAction.setEnabled(False)
- else:
- if self._isHistoryMacro:
- macroNode = self.historyBuffer()
- self.setHistoryBuffer(None)
- self.favouritesMacrosEditor.list.clearSelection()
- else:
- macroNode = self.favouritesBuffer()
- self.setFavouritesBuffer(None)
- self.historyMacrosViewer.list.clearSelection()
- self._isHistoryMacro = False
-
- if macroNode is None:
- macroNode = self.getModelObj().getMacroNodeObj(macroName)
-
- self.playMacroAction.setEnabled(True)
- self.addToFavouritesAction.setEnabled(True)
-
- self.paramEditorModel().setRoot(macroNode)
- self.spockCommand.setModel(self.paramEditorModel())
- if self.stackedWidget.count() == 2:
- self.stackedWidget.removeWidget(self.customMacroParametersEditor)
- self.customMacroParametersEditor.setParent(None)
- self.customMacroParametersEditor = ParamEditorManager().getMacroEditor(macroName, self.stackedWidget)
- if self.customMacroParametersEditor:
- self.customMacroParametersEditor.setModel(self.paramEditorModel())
- self.stackedWidget.addWidget(self.customMacroParametersEditor)
- self.stackedWidget.setCurrentWidget(self.customMacroParametersEditor)
- else:
- self.standardMacroParametersEditor.setModel(self.paramEditorModel())
-
- self.emit(Qt.SIGNAL("macroNameChanged"), macroName)
-
- def onFavouriteSelected(self, macroNode):
- self.setFavouritesBuffer(macroNode)
- name = ""
- if not macroNode is None:
- name = macroNode.name()
- self._isHistoryMacro = False
- self.macroComboBox.selectMacro(name)
-
- def onHistorySelected(self, macroNode):
- self.setHistoryBuffer(macroNode)
- name = ""
- if not macroNode is None:
- name = macroNode.name()
- self._isHistoryMacro = True
- self.macroComboBox.selectMacro(name)
-
- def onAddToFavourites(self):
- self.favouritesMacrosEditor.addMacro(deepcopy(self.paramEditorModel().root()))
-
- def addToHistory(self):
- self.historyMacrosViewer.addMacro(deepcopy(self.paramEditorModel().root()))
-
- def onDoorChanged(self, doorName):
- self.setDoorName(doorName)
- if self.doorName() == "":
- self.doorStateLed.setModel(None)
- return
- self.doorStateLed.setModel(self.doorName() + "/State")
- doorState = Device(doorName).state()
- if doorState == PyTango.DevState.ON:
- self.playMacroAction.setText("Start macro")
- self.playMacroAction.setToolTip("Start macro")
- elif doorState == PyTango.DevState.STANDBY:
- self.playMacroAction.setText("Resume macro")
- self.playMacroAction.setToolTip("Resume macro")
-
- def onPlayMacro(self):
- door = Device(self.doorName())
- doorState = door.state()
- if doorState == PyTango.DevState.ON or doorState == PyTango.DevState.ALARM:
- paramEditorModel = self.paramEditorModel()
- macroNode = paramEditorModel.root()
- id = macroNode.assignId()
- self.setMacroId(id)
- params, alerts = macroNode.toRun()
- xmlString = paramEditorModel.toXmlString()
- if len(alerts) > 0:
- Qt.QMessageBox.warning(self, "Macro parameters warning", alerts)
- return
- door.runMacro(xmlString)
- self.addToHistory()
-# door.runMacro(str(macroNode.name()), params)
- elif doorState == PyTango.DevState.STANDBY:
- door.command_inout("ResumeMacro")
- else:
- Qt.QMessageBox.warning(self, "Error while starting/resuming macro",
- "It was not possible to start/resume macro, because state of the door was different than ON/STANDBY")
-
- def onStopMacro(self):
- door = Device(self.doorName())
- doorState = door.state()
-
- if doorState in (PyTango.DevState.RUNNING, PyTango.DevState.STANDBY):
- door.command_inout("StopMacro")
- else:
- Qt.QMessageBox.warning(self, "Error while stopping macro",
- "It was not possible to stop macro, because state of the door was different than RUNNING or STANDBY")
-
- def onPauseMacro(self):
- door = Device(self.doorName())
- doorState = door.state()
-
- if doorState == PyTango.DevState.RUNNING:
- door.command_inout("PauseMacro")
- else:
- Qt.QMessageBox.warning(self, "Error while pausing macro",
- "It was not possible to pause macro, because state of the door was different than RUNNING")
-
- def onMacroStatusUpdated(self, data):
- macro = data[0]
- if macro is None: return
- data = data[1][0]
- state, range, step, id = data["state"], data["range"], data["step"], data["id"]
- if id is None: return
- id = int(id)
- if id != self.macroId(): return
- macroName = macro.name
- shortMessage = ""
- if state == "start":
- self.emit(Qt.SIGNAL("macroStarted"), "DoorOutput")
- self.macroProgressBar.setRange(range[0], range[1])
- self.playMacroAction.setEnabled(False)
- self.pauseMacroAction.setEnabled(True)
- self.stopMacroAction.setEnabled(True)
- self.emit(Qt.SIGNAL("plotablesFilterChanged"), None)
- self.emit(Qt.SIGNAL("plotablesFilterChanged"), standardPlotablesFilter)
- shortMessage = "Macro %s started." % macroName
- elif state == "pause":
- self.playMacroAction.setText("Resume macro")
- self.playMacroAction.setToolTip("Resume macro")
- self.playMacroAction.setEnabled(True)
- self.pauseMacroAction.setEnabled(False)
- shortMessage = "Macro %s paused." % macroName
- elif state == "resume":
- self.playMacroAction.setText("Start macro")
- self.playMacroAction.setToolTip("Start macro")
- self.playMacroAction.setEnabled(False)
- self.pauseMacroAction.setEnabled(True)
- shortMessage = "Macro %s resumed." % macroName
- elif state == "stop" or state == "finish":
- self.playMacroAction.setEnabled(True)
- self.pauseMacroAction.setEnabled(False)
- self.stopMacroAction.setEnabled(False)
- shortMessage = "Macro %s finished." % macroName
- elif state == "exception":
- self.playMacroAction.setEnabled(True)
- self.pauseMacroAction.setEnabled(False)
- self.stopMacroAction.setEnabled(False)
- shortMessage = "Macro %s error." % macroName
- exc_value, exc_stack = data['exc_value'], data['exc_stack']
- exceptionDialog = TaurusMessageBox(MacroRunException, exc_value, exc_stack)
- exceptionDialog.exec_()
- elif state == "abort":
- self.playMacroAction.setText("Start macro")
- self.playMacroAction.setToolTip("Start macro")
- self.playMacroAction.setEnabled(True)
- self.pauseMacroAction.setEnabled(False)
- self.stopMacroAction.setEnabled(False)
- shortMessage = "Macro %s stopped." % macroName
- elif state == "step":
- shortMessage = "Macro %s at %d %% of progress." % (macroName, step)
- self.emit(Qt.SIGNAL("shortMessageEmitted"), shortMessage)
- self.macroProgressBar.setValue(step)
-
- def disableControlActions(self):
- self.pauseMacroAction.setEnabled(False)
- self.stopMacroAction.setEnabled(False)
- self.playMacroAction.setEnabled(False)
-
- def setModel(self, model):
- oldModelObj = self.getModelObj()
- if oldModelObj is not None:
- self.disconnect(oldModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated)
- TaurusWidget.setModel(self, model)
- newModelObj = self.getModelObj()
- self.connect(newModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated)
-
- @classmethod
- def getQtDesignerPluginInfo(cls):
- return {'container': False,
- 'group': 'Taurus Sardana',
- 'module': 'taurus.qt.qtgui.extra_macroexecutor',
- 'icon': ':/designer/frame.png'}
-
-
-class TaurusMacroExecutor(MacroExecutionWindow):
-
- def __init__(self, parent=None, designMode=False):
- MacroExecutionWindow.__init__(self, parent, designMode)
-
- def initComponents(self):
- self.taurusMacroExecutorWidget = TaurusMacroExecutorWidget(self)
- self.registerConfigDelegate(self.taurusMacroExecutorWidget)
- self.taurusMacroExecutorWidget.setUseParentModel(True)
- self.setCentralWidget(self.taurusMacroExecutorWidget)
- self.connect(self.taurusMacroExecutorWidget, Qt.SIGNAL('shortMessageEmitted'), self.onShortMessage)
- self.statusBar().showMessage("MacroExecutor ready")
-
- def setCustomMacroEditorPaths(self, customMacroEditorPaths):
- MacroExecutionWindow.setCustomMacroEditorPaths(self, customMacroEditorPaths)
- ParamEditorManager().parsePaths(customMacroEditorPaths)
- ParamEditorManager().browsePaths()
-
- def loadSettings(self):
- TaurusMainWindow.loadSettings(self)
- self.emit(Qt.SIGNAL("doorChanged"), self.doorName())
-
- def onDoorChanged(self, doorName):
- MacroExecutionWindow.onDoorChanged(self, doorName)
- if self._qDoor:
- Qt.QObject.disconnect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated)
- if doorName == "": return
- self._qDoor = Device(doorName)
- Qt.QObject.connect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated)
- self.taurusMacroExecutorWidget.onDoorChanged(doorName)
-
- @classmethod
- def getQtDesignerPluginInfo(cls):
- return None
-
-
-def createMacroExecutorWidget(args):
- macroExecutor = TaurusMacroExecutorWidget()
- macroExecutor.setModelInConfig(True)
- Qt.QObject.connect(macroExecutor, Qt.SIGNAL("doorChanged"), macroExecutor.onDoorChanged)
- if len(args) == 2:
- macroExecutor.setModel(args[0])
- macroExecutor.emit(Qt.SIGNAL('doorChanged'), args[1])
- return macroExecutor
-
-def createMacroExecutor(args):
- macroExecutor = TaurusMacroExecutor()
- macroExecutor.setModelInConfig(True)
- Qt.QObject.connect(macroExecutor, Qt.SIGNAL("doorChanged"), macroExecutor.onDoorChanged)
- if len(args) == 2:
- macroExecutor.setModel(args[0])
- macroExecutor.emit(Qt.SIGNAL('doorChanged'), args[1])
- macroExecutor.loadSettings()
- return macroExecutor
-
-def main():
- from taurus.qt.qtgui.application import TaurusApplication
- import taurus
-
- app = TaurusApplication(sys.argv, app_version=taurus.Release.version)
- args = app.get_command_line_args()
-
- app.setOrganizationName("Taurus")
- app.setApplicationName("macroexecutor")
- macroExecutor = createMacroExecutor(args)
- macroExecutor.show()
- sys.exit(app.exec_())
-
-if __name__ == "__main__":
- main()