#!/usr/bin/env python
#############################################################################
##
# This file is part of Taurus
##
# http://taurus-scada.org
##
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
##
# Taurus 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.
##
# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
##
#############################################################################
"""This module is designed to provide a library of taurus Qt actions"""
__all__ = ["ExternalAppAction",
"TaurusMenu",
"TaurusAction",
"SeparatorAction",
"AttributeHistoryAction",
"AttributeAllConfigAction",
"AttributeMonitorDeviceAction",
"AttributeImageDisplayAction",
"AttributeMenu",
"ConfigurationMenu",
]
__docformat__ = 'restructuredtext'
import os
import xml.dom.minidom
from taurus.external.qt import Qt
from taurus.core.taurushelper import getSchemeFromName
from taurus.qt.qtcore.configuration import BaseConfigurableClass
[docs]class ExternalAppAction(Qt.QAction, BaseConfigurableClass):
""" An specialized QAction for launching external applications
Signals: apart of those from QAction, it emits a "cmdArgsChanged" signal
with the current cmdArgs list as its argument.
"""
DEFAULT_ICON_NAME = 'application-x-executable'
cmdArgsChanged = Qt.pyqtSignal(list)
def __init__(self, cmdargs, text=None, icon=None, parent=None, interactive=True):
'''creator
:param cmdargs: (list<str> or str) A list of strings to be passed to
:meth:`subprocess.Popen` for launching the external
application. It can also be a single string containing a
command. See :meth:`setCmdArgs`
:param text: (str) see :class:`Qt.QAction`
:param icon: (QIcon or any other object that can be passed to QIcon creator) see :class:`Qt.QAction`
:param parent: (QObject) The parent object
'''
if isinstance(cmdargs, (basestring, Qt.QString)):
import shlex
cmdargs = shlex.split(str(cmdargs))
self.path = os.path.realpath(cmdargs and cmdargs[0] or '')
if text is None:
text = os.path.basename(cmdargs and cmdargs[0] or '')
if icon is None:
icon = Qt.QIcon.fromTheme(self.DEFAULT_ICON_NAME)
elif isinstance(icon, basestring):
tmp = Qt.QIcon.fromTheme(icon)
if not tmp.isNull():
icon = tmp
Qt.QAction.__init__(self, Qt.QIcon(icon), text, parent)
BaseConfigurableClass.__init__(self)
self.interactive = interactive
self._process = []
self.setCmdArgs(cmdargs)
self.triggered.connect(self.actionTriggered)
self.setToolTip("Launches %s (external application)" % text)
self.registerConfigProperty(self.cmdArgs, self.setCmdArgs, 'cmdArgs')
[docs] def setCmdArgs(self, cmdargs, emitsignal=True):
'''Sets the command args for executing this external application.
It emits the "cmdArgsChanged" signal with the new cmdArgs list
:param cmdargs: (list<str> or str) A list of strings to be passed to
:meth:`subprocess.Popen` for launching the external
application. It can also be a string containing a
command, which will be automatically converted to a list
'''
if isinstance(cmdargs, (basestring, Qt.QString)):
import shlex
cmdargs = shlex.split(str(cmdargs))
self.__cmdargs = cmdargs
if emitsignal:
self.cmdArgsChanged.emit(self.__cmdargs)
[docs] def cmdArgs(self):
return self.__cmdargs
@Qt.pyqtSlot(name='triggered', result=bool)
[docs] def actionTriggered(self, args=None):
'''launches the external application as a subprocess'''
import subprocess
try:
if args is not None:
if isinstance(args, (basestring, Qt.QString)):
import shlex
args = shlex.split(str(args))
args = self.cmdArgs() + args
else:
args = self.cmdArgs()
if any(args):
#Qt.QMessageBox.warning(self.parentWidget(),'Warning','In ExternalAppAction(%s)'%args)
self._process.append(subprocess.Popen(args))
return True
else:
return False
except OSError:
err = "Error launching %s" % unicode(self.text())
msg = "Cannot launch application:\n" + \
" ".join(self.__cmdargs) + \
"\nHint: Check that %s is installed and in the path" % unicode(
self.text())
if self.interactive:
Qt.QMessageBox.warning(self.parentWidget(), err, msg)
from taurus.core.util import Logger
Logger().warning('%s:\n%s' % (err, msg))
return False
[docs] def kill(self):
# Kills all processes opened by this application
[p.kill() for p in self._process]
[docs] def check(self):
'''Returns True if the application is available for executing
:return: (bool)
'''
# raise NotImplementedError #@todo: implement a checker (check if
# self.cmdargs[0] is in the execution path and is executable
path = os.path.realpath(self.cmdArgs()[0])
try:
os.stat(path)
return True
except:
return False
[docs]class TaurusAction(Qt.QAction):
"""Base class for Taurus Actions"""
def __init__(self, parent):
import taurus.qt.qtgui.base
if (parent is None) or \
(not isinstance(parent, Qt.QWidget)) or \
(not isinstance(parent, taurus.qt.qtgui.base.TaurusBaseComponent)):
raise RuntimeError(
"Invalid parent. Must be a valid Taurus widget.")
Qt.QAction.__init__(self, parent)
parent.modelChanged.connect(self.modelChanged)
self.triggered.connect(self.actionTriggered)
self.update()
[docs] def update(self):
model = self.parent().getModelObj()
self.setDisabled(model is None)
@Qt.pyqtSlot('QString')
[docs] def modelChanged(self, modelName):
self.update()
@Qt.pyqtSlot(name='triggered')
[docs] def actionTriggered(self):
pass
[docs]class SeparatorAction(TaurusAction):
menuID = "_Separator_"
def __init__(self, parent=None):
Qt.QAction.__init__(self, parent)
self.setSeparator(True)
[docs]class AttributeHistoryAction(TaurusAction):
menuID = "AttrHistory"
def __init__(self, parent=None):
TaurusAction.__init__(self, parent)
self.setText("Show history...")
[docs] def actionTriggered(self):
dialog = Qt.QDialog()
dialog.exec_()
[docs]class AttributeAllConfigAction(TaurusAction):
menuID = "AttrConfig"
def __init__(self, parent=None):
TaurusAction.__init__(self, parent)
self.setText("All...")
[docs] def actionTriggered(self):
taurus_widget = self.parent()
from taurus.qt.qtgui.dialog.taurusconfigurationdialog import (
TaurusConfigurationDialog)
d = TaurusConfigurationDialog(taurus_widget)
d.setModel(taurus_widget.getModelName())
d.exec_()
[docs]class AttributeMonitorDeviceAction(TaurusAction):
menuID = "MonitorDevice"
def __init__(self, parent=None):
TaurusAction.__init__(self, parent)
self.setText("&Monitor device ...")
[docs] def actionTriggered(self):
taurus_widget = self.parent()
model_name = taurus_widget.getModelName()
w = model_name.split("/")
if len(w) == 3:
dev_name = model_name
elif len(w) == 4:
dev_name = w[0] + "/" + w[1] + "/" + w[2]
elif len(w) == 5: # FB: If the first parameter is the database
dev_name = w[1] + "/" + w[2] + "/" + w[3]
else:
return
cmd = "atkpanel " + dev_name + " &"
os.system(cmd)
[docs]class AttributeImageDisplayAction(TaurusAction):
menuID = "ImageDisplay"
def __init__(self, parent=None):
TaurusAction.__init__(self, parent)
self.setText("&Image Display ...")
[docs] def actionTriggered(self):
taurus_widget = self.parent()
model_name = taurus_widget.getModelName()
w = model_name.split("/")
if len(w) == 3:
dev_name = model_name
elif len(w) == 4:
dev_name = w[0] + "/" + w[1] + "/" + w[2]
else:
return
attr_name = dev_name + "/Image"
import qub
im = qub._TaurusQubDataImageDisplay(data=attr_name)
im.show()