#!/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/>.
##
#############################################################################
"""
Provides a QtObject for taurus attributes
"""
import weakref
import re
import PyTango
from taurus.core.taurusvalidator import AttributeNameValidator
from taurus.external.qt import Qt
from taurus.qt.qtgui.base import TaurusBaseComponent
from taurus.core.util.safeeval import SafeEvaluator
[docs]class TaurusQAttributeFactory(object): #@this probably needs to be ported to a proper TaurusFactory
'''A factory for TaurusQAttributes that ensures that only one
TaurusQAttributes is created for a given extended model.
IMPORTANT: This API is for testing purposes.It is likely to change. Don't rely on it'''
def __init__(self):
self._qAttrsByExtModel = weakref.WeakValueDictionary()
self._count = 0
[docs] def getQAttr(self, xmodel=None, id=None, autoIdformat=r'_QAttr%i_'):
#check if the qAttr is known to this factory
if xmodel is not None and xmodel in self._qAttrsByExtModel:
c = self._qAttrsByExtModel[xmodel]
#create a new qAttr
else:
if id is None:
id = autoIdformat%self._count
self._count += 1
c = TaurusQAttribute(xmodel=xmodel, id=id)
self._qAttrsByExtModel[xmodel] = c
return c
taurusQAttributeFactory = TaurusQAttributeFactory()
ATTRNAMEVALIDATOR = AttributeNameValidator()
[docs]class TaurusQAttribute(Qt.QObject, TaurusBaseComponent):
'''A listener for taurus attributes.
It stores the value in a numpy array and emits a
dataChanged signal when the data has changed.
'''
pyVar_RegExp = re.compile("[a-zA-Z_][a-zA-Z0-9_]*") #regexp for a variable/method name (symbol)
cref_RegExp = re.compile("\$\{(.+?)\}") #regexp for references to qAttrs in extended models
def __init__(self, xmodel = None, id=None):
Qt.QObject.__init__(self)
TaurusBaseComponent.__init__(self, self.__class__.__name__)
self._attrnamevalidator = ATTRNAMEVALIDATOR
self.id = id
self.sev = SafeEvaluator()
self._referencedQAttrs = []
self.value = None
self._setExtendedModel(xmodel)
def _setExtendedModel(self, xmodel):
self._xmodel = xmodel
if xmodel is None:
self.value = None
self._transformationString = None
self.setModel('')
return
xmodel = str(xmodel)
#for formulas
if xmodel.startswith('='):
trstring, ok = self.preProcessTransformation(xmodel[1:])
if ok:
self._transformationString = trstring
self.applyTransformation()
else:
print "!!!!!!!!!!!!!", self._transformationString
return
#for tango attributes
elif self._attrnamevalidator.isValid(xmodel):
self.setModel(xmodel)
self.fireEvent(None, None, None) #fake event to force a reading
else:
self.warning('Unsupported extended model "%s". Skipping',xmodel)
# #for nexus files
# m = re.match(NEXUS_src,model)
# if m is not None:
# host,path,nxpath,slice = m.group(4,5,9,10)
# #@todo:open file and check the data is accessible
# return model, nxpath, getThemeIcon('x-office-spreadsheet'), True
# #for ascii files
# m = re.match(ASCII_src,model)
# if m is not None:
# host,path, = m.group(4,5)
# #@todo: open and check the file
# #If nothing matches...
# return model, model, getThemeIcon('dialog-warning'), False
def __Match2Id(self, match):
"""
receives a re.match object for cref_RegExp. Returns the id of an
existing qAttr corresponding to the match. The qAttr is created
if it didn't previously exist.
"""
return self.__createReference(match.groups()[0]).id
def __createReference(self, ref):
'''creates a (or gets an existing)qAttr and connects to it and adds
its id to the safe evaluation symbols. It returns the qAttr.
'''
c = taurusQAttributeFactory.getQAttr(ref)
self.connect(c, Qt.SIGNAL("dataChanged"), self.applyTransformation)
self.sev.addSafe({c.id:c.value})
self._referencedQAttrs.append(c)
return c
[docs] def handleEvent(self, src, evt_type, val):
'''Handles Taurus Events for this curve
See: :meth:`TaurusBaseQAttr.handleEvent`
'''
model = src if src is not None else self.getModelObj()
if model is None:
self._values = None
self.emit(Qt.SIGNAL('dataChanged'))
return
value = val if isinstance(val, PyTango.DeviceAttribute) else self.getModelValueObj()
if not isinstance(value, PyTango.DeviceAttribute):
self.debug("Could not get DeviceAttribute value for this event. Dropping")
return
self.value = value.value
self.emit(Qt.SIGNAL('dataChanged'))