Source code for taurus.qt.qtgui.graphic.jdraw.jdraw

#!/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 contains the graphics factory for the jdraw file format"""

__all__ = ["TaurusJDrawGraphicsFactory"]

__docformat__ = 'restructuredtext'

import os
import traceback

from taurus.external.qt import Qt
from taurus.core.util.log import Logger
from taurus.core.util.singleton import Singleton
from taurus.core.util.containers import CaselessDict
from taurus.qt.qtgui.graphic import (TaurusBaseGraphicsFactory,
                                     TaurusGraphicsScene, TaurusGraphicsItem)


LINESTYLE_JDW2QT = {0: Qt.Qt.SolidLine,
                    1: Qt.Qt.DotLine,
                    2: Qt.Qt.DashLine,
                    3: Qt.Qt.DashLine,
                    4: Qt.Qt.DashDotLine}

FILLSTYLE_JDW2QT = {0: Qt.Qt.NoBrush,
                    1: Qt.Qt.SolidPattern,
                    2: Qt.Qt.FDiagPattern,
                    3: Qt.Qt.BDiagPattern,
                    4: Qt.Qt.DiagCrossPattern,
                    5: Qt.Qt.FDiagPattern,
                    6: Qt.Qt.BDiagPattern,
                    7: Qt.Qt.Dense5Pattern,
                    8: Qt.Qt.Dense7Pattern,
                    9: Qt.Qt.Dense6Pattern,
                    10: Qt.Qt.Dense4Pattern,
                    11: Qt.Qt.LinearGradientPattern}

TEXTHINT_JDW2QT = CaselessDict({
    'helvetica': Qt.QFont.Helvetica,
    'serif': Qt.QFont.Serif,
    'sansserif': Qt.QFont.SansSerif,
    'courier': Qt.QFont.Courier,
    'Monospaced': Qt.QFont.Courier,
    'times': Qt.QFont.Times,
    '': Qt.QFont.AnyStyle, })

ALIGNMENT = {
    0: Qt.Qt.AlignHCenter,
    1: Qt.Qt.AlignLeft,
    2: Qt.Qt.AlignRight,
}

VALIGNMENT = {
    0: Qt.Qt.AlignVCenter,
    1: Qt.Qt.AlignTop,
    2: Qt.Qt.AlignBottom,
}


[docs]class TaurusJDrawGraphicsFactory(Singleton, TaurusBaseGraphicsFactory, Logger): def __init__(self, parent, alias=None, delayed=False): """ Initialization. Nothing to be done here for now.""" self.myparent = parent self.call__init__wo_kw(TaurusBaseGraphicsFactory, parent) self._zBufferLevel = 0 self._delayed = delayed self.alias = alias if alias is not None else {}
[docs] def init(self, *args, **kwargs): """Singleton instance initialization.""" self.call__init__(Logger, self.__class__.__name__) self.call__init__(TaurusBaseGraphicsFactory)
[docs] def getZBufferLevel(self): return self._zBufferLevel
[docs] def incZBufferLevel(self): self._zBufferLevel += 1 return self._zBufferLevel
[docs] def setZBufferLevel(self, level): self._zBufferLevel = level
[docs] def resetZBufferLevel(self): self.setZBufferLevel(0)
[docs] def getSceneObj(self, items): scene = TaurusGraphicsScene(self.myparent) for item in items: try: if isinstance(item, Qt.QWidget): scene.addWidget(item) elif isinstance(item, Qt.QGraphicsItem): scene.addItem(item) except: self.warning("Unable to add item %s to scene" % str(item)) self.debug("Details:", exc_info=1) return scene
[docs] def getObj(self, name, params): method_name = 'get' + name.lstrip('JD') + 'Obj' try: method = getattr(self, method_name) obj = method(params) obj.setZValue(self.incZBufferLevel()) return obj except: self.warning("Error fetching object") self.info("Details:", exc_info=1) pass return None
[docs] def getRectangleObj(self, params): item = self.getGraphicsItem('Rectangle', params) x1, y1, x2, y2 = params.get('summit') width = x2 - x1 height = y2 - y1 # item.setPos(x1,y1) item.setRect(x1, y1, width, height) return item
[docs] def getRoundRectangleObj(self, params): item = self.getGraphicsItem('RoundRectangle', params) x1, y1, x2, y2 = params.get('summit') width = x2 - x1 height = y2 - y1 cornerWidth = params.get('cornerWidth', 24) nbPoints = params.get('step', 6) # item.setPos(x1,y1) item.setRect(x1, y1, width, height) item.setCornerWidth(cornerWidth, nbPoints) return item
[docs] def getLineObj(self, params): item = self.getGraphicsItem('Line', params) x1, y1, x2, y2 = params.get('summit') item.setLine(x1, y1, x2, y2) return item
[docs] def getEllipseObj(self, params): item = self.getGraphicsItem('Ellipse', params) x1, y1, x2, y2 = params.get('summit') width = x2 - x1 height = y2 - y1 item.setRect(x1, y1, width, height) return item
[docs] def getPolylineObj(self, params): item = self.getGraphicsItem('Polyline', params) polygon = Qt.QPolygonF() p = params.get('summit') for i in xrange(0, len(p), 2): polygon.append(Qt.QPointF(p[i], p[i + 1])) item.setPolygon(polygon) return item
[docs] def getSplineObj(self, params): item = self.getGraphicsItem('Spline', params) p = params.get('summit') p = [Qt.QPointF(p[i], p[i + 1]) for i in xrange(0, len(p), 2)] item.setControlPoints(p) isClosed = params.get('isClosed', True) item.setClose(isClosed) return item
[docs] def getLabelObj(self, params): item = self.getGraphicsItem('Label', params) self.readLabelObj(item, params) return item
[docs] def readLabelObj(self, item, params): origin = params.get('origin') item.setPos(origin[0], origin[1]) summit = params.get('summit') x, y = summit[0] - origin[0], summit[1] - origin[1] width, height = summit[2] - summit[0], summit[3] - summit[1] item.setRect(x, y, width, height) # it is parsed as a float vAlignment = int(params.get('vAlignment', 0)) hAlignment = int(params.get('hAlignment', 0)) assert(vAlignment in VALIGNMENT.keys()) assert(hAlignment in ALIGNMENT.keys()) vAlignment = VALIGNMENT[vAlignment] hAlignment = ALIGNMENT[hAlignment] item.setAlignment(hAlignment | vAlignment) fnt = params.get('font', None) if fnt: family, style, size = fnt f = Qt.QFont(family, int(.85 * size), Qt.QFont.Light, False) f.setStyleHint(TEXTHINT_JDW2QT.get(family, Qt.QFont.AnyStyle)) f.setStyleStrategy(Qt.QFont.PreferMatch) if style == 1: f.setWeight(Qt.QFont.DemiBold) elif style == 2: f.setItalic(True) elif style == 3: f.setWeight(Qt.QFont.DemiBold) f.setItalic(True) # TODO: Improve code in order to be able to set a suitable font item.setFont(f) fg = params.get("foreground", (0, 0, 0)) color = Qt.QColor(fg[0], fg[1], fg[2]) item.setDefaultTextColor(color) txt = params.get('text') if txt: if any(isinstance(txt, t) for t in (list, tuple, set)): # Parsing several lines of text txt = '\n'.join(txt) item.setPlainText(Qt.QString(txt)) item._currText = txt
[docs] def getGroupObj(self, params): item = self.getGraphicsItem('Group', params) s = params.get('summit') x1, y1 = s[0], s[1] item.setPos(x1, y1) children = params.get('children') if children: for child in children: if child: #self.info('jdraw.py: "%s".addItem("%s")'%(str(params.get('name')),str(child))) item.addToGroup(child) if item._fillStyle: self.set_item_filling(item, expand=True) return item
[docs] def getSwingObjectObj(self, params): item = self.getGraphicsItem('SwingObject', params) s = params.get('summit') x1, y1 = s[0], s[1] item.setPos(x1, y1) className = params.get('className') if className == "fr.esrf.tangoatk.widget.attribute.SimpleScalarViewer": self.readSimpleScalarViewerObj(item, params) return item
[docs] def readSimpleScalarViewerObj(self, item, params): self.readLabelObj(item, params) ext = params.get('extensions') c = ext.get('validBackground') c = [int(x) for x in c.split(",")] if c: validBackground = Qt.QColor(*c) item.setValidBackground(validBackground) invalidText = ext.get('invalidText', "-----") item.setNoneValue(invalidText) alarmEnabled = ext.get('alarmEnabled', True) alarmEnabled = alarmEnabled.lower().strip() in ["yes", "true", "1"] item.setShowQuality(alarmEnabled) unitVisible = ext.get('unitVisible', True) unitVisible = unitVisible.lower().strip() in ["yes", "true", "1"] item.setUnitVisible(unitVisible) userFormat = ext.get('userFormat', None) item.setUserFormat(userFormat)
[docs] def getImageObj(self, params): item = self.getGraphicsItem('Image', params) s = params.get('summit') x1, y1, x2, y2 = s item.setPos(x1, y1) fname = params.get('file_name') if fname: if os.path.isfile(fname): fname = os.path.realpath(fname) elif hasattr(self.myparent, 'path'): #self.info('using path param ...') fname = self.myparent.path + os.path.sep + fname self.debug('Opening JDImage(%s) = x,y,w,h=%f,%f,%f,%f' % (fname, x1, y1, x2 - x1, y2 - y1)) pixmap = Qt.QPixmap(fname) item.setPixmap(pixmap.scaled(x2 - x1, y2 - y1)) #item.scale(float(w)/pixmap.width(), float(h)/pixmap.height()) else: self.warning('No filename for image!?!') return item
[docs] def set_common_params(self, item, params): if not item: return item._params = params name = params.get('name') if name.lower() == "ignorerepaint": name = "" if not 'extensions' in params: params['extensions'] = {} params.get('extensions')["ignoreRepaint"] = "true" if self.alias: for k, v in self.alias.items(): name = str(name).replace(k, v) # Forcing not-Taurus items to have a name and be able to trigger events setattr(item, '_name', name) if name and not self._delayed: if isinstance(item, TaurusGraphicsItem): #self.debug('TaurusJDrawGraphicsFactory.set_common_params(): %s.setModel(%s)'%(item,name)) item.setModel(name) else: self.debug('TaurusJDrawGraphicsFactory.set_common_params(%s): %s is not a TaurusGraphicsItem' % ( name, type(item).__name__)) visibilitymapper = params.get('visibilitymapper') if not visibilitymapper is None: mapping_type = visibilitymapper['mapping_type'] mode = visibilitymapper['mode'] default = visibilitymapper['default'] item._default = default item._map = visibilitymapper['map'] visible = params.get('visible') if not visible is None: item.setVisible(visible) extensions = params.get('extensions') if extensions: item._extensions = extensions try: getattr(item, 'setPen') fg = params.get("foreground", (0, 0, 0)) lineWidth = params.get("lineWidth", 1) if lineWidth == 0: pen = Qt.QPen(Qt.Qt.NoPen) else: pen = Qt.QPen(Qt.QColor(fg[0], fg[1], fg[2])) pen.setWidth(lineWidth) pen.setStyle(LINESTYLE_JDW2QT[params.get("lineStyle", 0)]) item.setPen(pen) except AttributeError, ae: pass except Exception, e: self.warning('jdraw.set_common_params(%s(%s)).(foreground,width,style) failed!: \n\t%s' % ( type(item).__name__, name, traceback.format_exc())) fillStyle = FILLSTYLE_JDW2QT[params.get('fillStyle', 0)] item._fillStyle = fillStyle if hasattr(item, 'brush'): brush = Qt.QBrush() if fillStyle == Qt.Qt.LinearGradientPattern: ox, oy = params.get('origin', (0, 0)) gradient = Qt.QLinearGradient(ox + params.get('gradX1', 0), oy + params.get('gradY1', 0), ox + params.get('gradX2', 0), oy + params.get('gradY2', 0)) c = params.get('gradC1', (0, 0, 0)) gradient.setColorAt(0, Qt.QColor(c[0], c[1], c[2])) c = params.get('gradC2', (255, 255, 255)) gradient.setColorAt(1, Qt.QColor(c[0], c[1], c[2])) gradCyclic = params.get('gradCyclic', False) if gradCyclic: gradient.setSpread(Qt.QGradient.ReflectSpread) brush = Qt.QBrush(gradient) else: brush.setStyle(fillStyle) bg = params.get('background', (255, 255, 255)) brush.setColor(Qt.QColor(bg[0], bg[1], bg[2])) item.setBrush(brush)
[docs] def set_item_filling(self, item, pattern=Qt.Qt.Dense4Pattern, expand=False): count = 0 item._fillStyle = item._fillStyle or pattern if hasattr(item, 'brush'): br = item.brush() br.setStyle(item._fillStyle) item.setBrush(br) if expand: for c in item.childItems(): if not c._fillStyle: self.set_item_filling(c, pattern=pattern, expand=True) return
if __name__ == "__main__": import jdraw_view jdraw_view.jdraw_view_main()