# Source code for taurus.qt.qtgui.display.qled

    #!/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/>.
    #
    # ###########################################################################

    """A pure Qt led widget
    """

    __docformat__ = "restructuredtext"

    import sys

    from taurus.external.qt import Qt
    from taurus.core.util.enumeration import Enumeration
    from taurus.qt.qtgui.icon import getCachedPixmap
    from taurus.qt.qtgui.display.qpixmapwidget import QPixmapWidget

    LedColor = Enumeration(
        "LedColor",
        [
            "BLUE",
            "GREEN",
            "RED",
            "YELLOW",
            "ORANGE",
            "MAGENTA",
            "GRENOBLE",
            "BLACK",
            "WHITE",
        ],
    )
    LedStatus = Enumeration("LedStatus", ["ON", "OFF"])
    LedSize = Enumeration("LedSize", [("SMALL", 24), ("LARGE", 48)])

    class QLed(QPixmapWidget):
        """A Led"""

        DefaultLedPattern = "leds_images256:led_{color}_{status}.png"
        DefaultLedColor = "green"
        DefaultLedStatus = True
        DefaultLedInverted = False
        DefaultBlinkingInterval = 0

        def __init__(self, parent=None, designMode=False):
            self._ledStatus = self.DefaultLedStatus
            self._ledColor = self.DefaultLedColor
            self._ledPatternName = self.DefaultLedPattern
            self._ledInverted = self.DefaultLedInverted
            self._ledName = self.toLedName()
            self._timer = None
            QPixmapWidget.__init__(self, parent)
            self._refresh()

        def sizeHint(self):
            if self.layout() is None:
                return Qt.QSize(24, 24)
            return QPixmapWidget.sizeHint(self)

        def minimumSizeHint(self):
            """Overwrite the default minimum size hint (0,0) to be (16,16)
            :return: the minimum size hint 16,16
            :rtype: PyQt5.Qt.QSize
            """
            return Qt.QSize(8, 8)

        def toLedName(self, status=None, color=None, inverted=None):
            """Gives the led name for the given status and color. If status or
            color are not given, the current led status or color are used.

            :param status: the status
            :type  status: bool
            :param color: the color
            :type  color: str
            :return: string containing the led name
            :rtype: str
            """
            if status is None:
                status = self._ledStatus
            if color is None:
                color = self._ledColor
            if inverted is None:
                inverted = self._ledInverted
            if inverted:
                status = not status
            status = status and "on" or "off"
            return self._ledPatternName.format(color=color, status=status)

        def isLedColorValid(self, name):
            """Determines if the given color name is valid.

            :param color: the color
            :type  color: str
            :return: True is the given color name is valid or False otherwise
            :rtype: bool
            """
            return name.upper() in LedColor

        def _refresh(self):
            """internal usage only"""
            self._ledName = self.toLedName()
            pixmap = getCachedPixmap(self._ledName)
            self.setPixmap(pixmap)
            return self.update()

        @classmethod
        def getQtDesignerPluginInfo(cls):
            return {
                "module": "taurus.qt.qtgui.display",
                "group": "Taurus Display",
                "icon": "designer:ledred.png",
                "container": False,
            }

        # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
        # QT property definition
        # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~

        def getLedPatternName(self):
            """Returns the current led pattern name
            :return: led pattern name
            :rtype: str
            """
            return self._ledPatternName

        def setLedPatternName(self, name):
            """Sets the led pattern name. Should be a string containing a path
            to valid images. The string can contain the keywords:

                1. {status} - transformed to 'on' of 'off' according to the status
                2. {color} - transformed to the current led color

            Example: **:leds/images256/led_{color}_{status}.png** will be
            transformed to **:leds/images256/led_red_on.png** when the led status
            is True and the led color is red.

            :param name: new pattern
            :type  name: str
            """
            self._ledPatternName = str(name)
            self._refresh()

        def resetLedPatternName(self):
            """Resets the led pattern to
            `leds/images256/led_{color}_{status}.png`
            """
            self.setLedPatternName(self.DefaultLedPattern)

        def getLedStatus(self):
            """Returns the led status
            :return: led status
            :rtype: bool
            """
            return self._ledStatus

        def setLedStatus(self, status):
            """Sets the led status

            :param status: the new status
            :type  status: bool
            """
            self._ledStatus = bool(status)
            self._refresh()

        def resetLedStatus(self):
            """Resets the led status"""
            self.setLedStatus(self.DefaultLedStatus)

        def toggleLedStatus(self):
            """toggles the current status of the led"""
            self.setLedStatus(not self.getLedStatus())

        def getLedInverted(self):
            """Returns if the led is inverted.
            :return: inverted mode
            :rtype: bool
            """
            return self._ledInverted

        def setLedInverted(self, inverted):
            """Sets the led inverted mode

            :param status: the new inverted mode
            :type  status: bool
            """
            self._ledInverted = bool(inverted)
            self._refresh()

        def resetLedInverted(self):
            """Resets the led inverted mode"""
            self.setLedInverted(self.DefaultLedInverted)

        def getLedColor(self):
            """Returns the led color
            :return: led color
            :rtype: str
            """
            return self._ledColor

        def setLedColor(self, color):
            """Sets the led color

            :param status: the new color
            :type  status: str
            """
            color = str(color).lower()
            if not self.isLedColorValid(color):
                raise Exception("Invalid color '%s'" % color)
            self._ledColor = color
            self._refresh()

        def resetLedColor(self):
            """Resets the led color"""
            self.setLedColor(self.DefaultLedColor)

        def setBlinkingInterval(self, interval):
            """sets the blinking interval (the time between status switching).
            Set to a nonpositive number for disabling blinking

            :param interval: the blinking interval in millisecs. Set to 0 for
                disabling blinking
            :type interval: int
            """
            if interval > 0:
                if self._timer is None:
                    self._timer = Qt.QTimer(self)
                    self._timer.timeout.connect(self.toggleLedStatus)
                self._timer.start(interval)
            else:
                if self._timer is not None:
                    self._timer.stop()
                    self._timer = None

        def getBlinkingInterval(self):
            """returns the blinking interval

            :return: blinking interval or 0 if blinking is not enabled.
            :rtype: int
            """
            if self._timer is None:
                return 0
            else:
                return self._timer.interval()

        def resetBlinkingInterval(self):
            """resets the blinking interval"""
            self.setBlinkingInterval(self.__class__.DefaultBlinkingInterval)

        #: This property holds the led status: False means OFF, True means ON
        #:
        #: **Access functions:**
        #:
        #:     * :meth:`QLed.getLedStatus`
        #:     * :meth:`QLed.setLedStatus`
        #:     * :meth:`QLed.resetLedStatus`
        ledStatus = Qt.pyqtProperty(
            "bool", getLedStatus, setLedStatus, resetLedStatus, doc="led status"
        )

        #: This property holds the led color
        #:
        #: **Access functions:**
        #:
        #:     * :meth:`QLed.getLedColor`
        #:     * :meth:`QLed.setLedColor`
        #:     * :meth:`QLed.resetLedColor`
        ledColor = Qt.pyqtProperty(
            "QString", getLedColor, setLedColor, resetLedColor, doc="led color"
        )

        #: This property holds the led inverted: False means do not invert the
        #: status, True means invert the status
        #:
        #: **Access functions:**
        #:
        #:     * :meth:`QLed.getLedInverted`
        #:     * :meth:`QLed.setLedInverted`
        #:     * :meth:`QLed.resetLedInverted`
        ledInverted = Qt.pyqtProperty(
            "bool",
            getLedInverted,
            setLedInverted,
            resetLedInverted,
            doc="led inverted mode",
        )

        #: This property holds the led pattern name
        #:
        #: **Access functions:**
        #:
        #:     * :meth:`QLed.getLedPatternName`
        #:     * :meth:`QLed.setLedPatternName`
        #:     * :meth:`QLed.resetLedPatternName`
        ledPattern = Qt.pyqtProperty(
            "QString",
            getLedPatternName,
            setLedPatternName,
            resetLedPatternName,
            doc="led pattern name",
        )

        #: This property holds the blinking interval in millisecs.
        #: 0 means no blinking
        #:
        #: **Access functions:**
        #:
        #:     * :meth:`QLed.getBlinkingInterval`
        #:     * :meth:`QLed.setBlinkingInterval`
        #:     * :meth:`QLed.resetBlinkingInterval`
        blinkingInterval = Qt.pyqtProperty(
            "int",
            getBlinkingInterval,
            setBlinkingInterval,
            resetBlinkingInterval,
            doc="blinking interval",
        )

    class QLedOld(Qt.QLabel):
        ledDirPattern = ":leds/images%(size)d"

        def __init__(
            self, parent=None, ledsize=LedSize.SMALL, ledcolor=LedColor.GREEN
        ):
            Qt.QLabel.__init__(self, parent)

            self.ledsize = ledsize
            self.status = LedStatus.OFF
            self.ledcolor = ledcolor

            self.setObjectName("Led")
            sizePolicy = Qt.QSizePolicy(
                Qt.QSizePolicy.Policy(0), Qt.QSizePolicy.Policy(0)
            )
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
            self.setSizePolicy(sizePolicy)

            # no need to call changeColor. changeSize calls it for us
            self.changeSize(ledsize)

            self.retranslateUi(self)
            Qt.QMetaObject.connectSlotsByName(self)

        def toLedName(self, status, color):
            name = "led" + LedColor.whatis(color).lower()
            if status == LedStatus.OFF:
                name += LedStatus.whatis(status).lower()
            return name

        def toCompleteLedName(self, size, status, color):
            ret = self.ledDirPattern % {"size": size}
            ret += "/" + self.toLedName(status, color) + ".png"
            return ret

        def tr(self, string):
            return Qt.QApplication.translate(
                "Led", string, None, Qt.QApplication.UnicodeUTF8
            )

        def retranslateUi(self, Led):
            Led.setWindowTitle(self.tr("Form"))

        def on(self):
            if self.status == LedStatus.OFF:
                self.status = LedStatus.ON
                self.setPixmap(self.onled)

        def off(self):
            if self.status == LedStatus.ON:
                self.status = LedStatus.OFF
                self.setPixmap(self.offled)

        def changeSize(self, ledSize):
            self.ledsize = ledSize
            self.resize(ledSize, ledSize)
            self.setMinimumSize(Qt.QSize(ledSize, ledSize))
            self.setMaximumSize(Qt.QSize(ledSize, ledSize))

            # force a call to led color to change the place from which the images
            # are fetched
            self.changeColor(self.ledcolor)

        def changeColor(self, ledColor):
            self.ledcolor = ledColor

            off_pixmap_name = self.toCompleteLedName(
                self.ledsize, LedStatus.OFF, ledColor
            )
            self.offled = Qt.QPixmap(off_pixmap_name)
            on_pixmap_name = self.toCompleteLedName(
                self.ledsize, LedStatus.ON, ledColor
            )
            self.onled = Qt.QPixmap(on_pixmap_name)

            if self.status == LedStatus.OFF:
                self.setPixmap(self.offled)
            else:
                self.setPixmap(self.onled)

        def _setProblemsBackground(self, doIt=True):
            if doIt:
                self.setAutoFillBackground(True)
                bg_brush = Qt.QBrush()
                bg_brush.setStyle(Qt.Qt.BDiagPattern)
                palette = self.palette()
                palette.setBrush(Qt.QPalette.Window, bg_brush)
                palette.setBrush(Qt.QPalette.Base, bg_brush)
            else:
                self.setAutoFillBackground(False)

    def main():
        """hello"""

        app = Qt.QApplication.instance()
        owns_app = app is None

        if owns_app:
            from taurus.qt.qtgui.application import TaurusApplication

            app = TaurusApplication(sys.argv, cmd_line_parser=None)

        w = Qt.QWidget()
        layout = Qt.QGridLayout()
        layout.setContentsMargins(2, 2, 2, 2)
        layout.setSpacing(2)
        w.setLayout(layout)
        for i, color in enumerate(LedColor.keys()):
            led = QLed()
            led.ledColor = color
            led.ledStatus = True
            layout.addWidget(led, i, 0)
            led = QLed()
            led.ledColor = color
            led.ledStatus = False
            layout.addWidget(led, i, 1)
            led = QLed()
            led.ledColor = color
            led.blinkingInterval = 500
            layout.addWidget(led, i, 2)
        w.show()

        if owns_app:
            sys.exit(app.exec_())
        else:
            return w

    if __name__ == "__main__":
        main()