diff --git a/secop/client/baseclient.py b/secop/client/baseclient.py index f57240d..47d4659 100644 --- a/secop/client/baseclient.py +++ b/secop/client/baseclient.py @@ -439,7 +439,7 @@ class Client(object): if msgtype == 'read' and ':' not in spec: spec = spec + ':value' - # check if a such a request is already out + # check if such a request is already out rply = self._get_reply_from_request(msgtype) if (rply, spec) in self.expected_replies: raise RuntimeError( @@ -538,6 +538,10 @@ class Client(object): def getCommands(self, module): return self.describing_data['modules'][module]['commands'] + def execCommand(self, module, command, args=None): + # ignore reply message + reply specifier, only return data + return self._communicate('do', '%s:%s' % (module, command), self.encode_message(args) if args else None)[2] + def getProperties(self, module, parameter): return self.describing_data['modules'][module]['parameters'][parameter] diff --git a/secop/gui/modulectrl.py b/secop/gui/modulectrl.py index dfe2773..ad12bf6 100644 --- a/secop/gui/modulectrl.py +++ b/secop/gui/modulectrl.py @@ -23,13 +23,27 @@ from __future__ import print_function -from PyQt4.QtGui import QWidget, QLabel, QPushButton as QButton, QLineEdit, QMessageBox, QCheckBox, QSizePolicy +from PyQt4.QtGui import QWidget, QLabel, QPushButton as QButton, QLineEdit, QMessageBox, QCheckBox, QSizePolicy, QDialog from PyQt4.QtCore import pyqtSignature as qtsig, Qt, pyqtSignal from secop.gui.util import loadUi from secop.gui.params import ParameterView +def showCommandResultDialog(command, args, result, extras=''): + m = QMessageBox() + if not args: + args = '' + m.setText('calling: %s(%s)\nyielded: %s\nqualifiers: %s' % + (command, args, result, extras)) + m.exec_() + + +def showErrorDialog(error): + m = QMessageBox(str(error)) + m.exec_() + + class ParameterGroup(QWidget): def __init__(self, groupname, parent=None): @@ -63,6 +77,29 @@ class ParameterGroup(QWidget): w.hide() +class CommandButton(QWidget): + + def __init__(self, cmdname, argin, cb, parent=None): + super(CommandButton, self).__init__(parent) + loadUi(self, 'cmdbuttons.ui') + + self._cmdname = cmdname + self._argin = argin # list of datatypes + self._cb = cb # callback function for exection + + if not argin: + self.cmdLineEdit.setHidden(True) + self.cmdPushButton.setText(cmdname) + + def on_cmdPushButton_pressed(self): + self.cmdPushButton.setEnabled(False) + if self._argin: + self._cb(self._cmdname, self.cmdLineEdit.text()) + else: + self._cb(self._cmdname, None) + self.cmdPushButton.setEnabled(True) + + class ModuleCtrl(QWidget): def __init__(self, node, module, parent=None): @@ -83,10 +120,32 @@ class ModuleCtrl(QWidget): self._node.newData.connect(self._updateValue) + def _execCommand(self, command, arg=None): + if arg: # try to validate input + # XXX: check datatypes with their validators? + import ast + try: + arg = ast.literal_eval(arg) + except Exception as e: + return showErrorDialog(e) + result, qualifiers = self._node.execCommand(self._module, command, arg) + showCommandResultDialog(command, arg, result, qualifiers) + def _initModuleWidgets(self): initValues = self._node.queryCache(self._module) row = 0 + # ignore groupings for commands (for now) + commands = self._node.getCommands(self._module) + # keep a reference or the widgets are detroyed to soon. + self.cmdWidgets = cmdWidgets = {} + # create and insert widgets into our QGridLayout + for command in sorted(commands): + w = CommandButton(command, [], self._execCommand) + cmdWidgets[command] = w + self.commandGroupBox.layout().addWidget(w, row, 0, 1, 0) + row += 1 + # collect grouping information paramsByGroup = {} # groupname -> [paramnames] allGroups = set() @@ -101,7 +160,8 @@ class ModuleCtrl(QWidget): if param not in initValues: self._node.getParameter(self._module, param) - groupWidgets = {} # groupname -> CheckBoxWidget for (un)folding + # groupname -> CheckBoxWidget for (un)folding + self._groupWidgets = groupWidgets = {} # create and insert widgets into our QGridLayout for param in sorted(allGroups.union(set(params))):