class TaurusPlotDataItem(PlotDataItem, TaurusBaseComponent):
    """A taurus-ified PlotDataItem"""
    def __init__(self, *args, **kwargs):
        """
        Accepts same args and kwargs as PlotDataItem, plus:
        :param xModel: (str) Taurus model name for abscissas values.
                       Default=None
        :param yModel: (str) Taurus model name for ordinate values.
                       Default=None
        """
        xModel = kwargs.pop('xModel', None)
        yModel = kwargs.pop('yModel', None)
        PlotDataItem.__init__(self, *args, **kwargs)
        TaurusBaseComponent.__init__(self, 'TaurusBaseComponent')
        self._x = None
        self._y = None
        self.xModel = None
        if xModel is not None:
            self.setXModel(xModel)
        if yModel is not None:
            self.setModel(yModel)

        self.registerConfigProperty(self.getOpts, self.setOpts, 'opts')
        self.setModelInConfig(True)
        self.registerConfigProperty(self.getXModelName, self.setXModel,
                                    'XModel')

    def setXModel(self, xModel):
        if not xModel:
            if self.xModel is not None:
                self.xModel.removeListener(self)
            self.xModel = None
            return
        self.xModel = Attribute(xModel)
        self._x = self.xModel.read().rvalue
        self.xModel.addListener(self)

    def getXModelName(self):
        if self.xModel is None:
            return None
        else:
            return self.xModel.getFullName()

    def handleEvent(self, evt_src, evt_type, evt_value):
        if evt_type not in (TaurusEventType.Change, TaurusEventType.Periodic):
            return
        yModel = self.getModelObj()
        if yModel == evt_src and yModel is not None:
            self._y = evt_value.rvalue
        if self.xModel == evt_src and self.xModel is not None:
            self._x = evt_value.rvalue
        self.setData(x=self._x, y=self._y)

    def getOpts(self):
        from taurus.qt.qtgui.tpg import serialize_opts
        return serialize_opts(copy.copy(self.opts))

    def setOpts(self, opts):
        # creates QPainters (QPen or QBrush) from a pickle loaded file
        # for adapt the serialized objects into PlotDataItem properties

        from taurus.qt.qtgui.tpg import deserialize_opts
        self.opts = deserialize_opts(opts)

        # This is a workaround for the following pyqtgraph's bug:
        # https://github.com/pyqtgraph/pyqtgraph/issues/531
        if opts['connect'] == 'all':
            self.opts['connect'] = 'all'
        elif opts['connect'] == 'pairs':
            self.opts['connect'] = 'pairs'
        elif opts['connect'] == 'finite':
            self.opts['connect'] = 'finite'

    def getFullModelNames(self):
        return (self.getXModelName(), self.getFullModelName())
class TaurusPlotDataItem(PlotDataItem, TaurusBaseComponent):
    """A taurus-ified PlotDataItem"""

    def __init__(self, *args, **kwargs):
        """
        Accepts same args and kwargs as PlotDataItem, plus:
        :param xModel: (str) Taurus model name for abscissas values.
                       Default=None
        :param yModel: (str) Taurus model name for ordinate values.
                       Default=None
        :param colors: (generator) An infinite generator of QColor objects
        """
        xModel = kwargs.pop("xModel", None)
        yModel = kwargs.pop("yModel", None)
        colors = kwargs.pop("colors", LoopList(CURVE_COLORS))
        if "pen" not in kwargs:
            kwargs["pen"] = next(colors)
        PlotDataItem.__init__(self, *args, **kwargs)
        TaurusBaseComponent.__init__(self, "TaurusBaseComponent")
        self._x = None
        self._y = None
        self.xModel = None
        if xModel is not None:
            self.setXModel(xModel)
        if yModel is not None:
            self.setModel(yModel)

        self.registerConfigProperty(self.getOpts, self.setOpts, "opts")
        self.setModelInConfig(True)
        self.registerConfigProperty(
            self.getXModelName, self.setXModel, "XModel"
        )

    def setXModel(self, xModel):
        if self.xModel is not None:
            self.xModel.removeListener(self)

        if not xModel:
            self.xModel = None
            return

        self.xModel = Attribute(xModel)
        self.xModel.addListener(self)

    def getXModelName(self):
        if self.xModel is None:
            return None
        else:
            return self.xModel.getFullName()

    def handleEvent(self, evt_src, evt_type, evt_value):
        if evt_type not in (TaurusEventType.Change, TaurusEventType.Periodic):
            return
        yModel = self.getModelObj()
        if yModel == evt_src:
            if yModel is not None:
                self._y = evt_value.rvalue
            else:
                self._y = None
        if self.xModel == evt_src:
            if self.xModel is not None:
                self._x = evt_value.rvalue
            else:
                self._x = None
        try:
            self.setData(x=self._x, y=self._y)
        except Exception as e:
            self.debug("Could not set data. Reason: %r", e)

    def getOpts(self):
        from taurus_pyqtgraph import serialize_opts

        return serialize_opts(copy.copy(self.opts))

    def setOpts(self, opts):
        # creates QPainters (QPen or QBrush) from a pickle loaded file
        # for adapt the serialized objects into PlotDataItem properties

        from taurus_pyqtgraph import deserialize_opts

        self.opts = deserialize_opts(opts)

        # This is a workaround for the following pyqtgraph's bug:
        # https://github.com/pyqtgraph/pyqtgraph/issues/531
        if opts["connect"] == "all":
            self.opts["connect"] = "all"
        elif opts["connect"] == "pairs":
            self.opts["connect"] = "pairs"
        elif opts["connect"] == "finite":
            self.opts["connect"] = "finite"

    def getFullModelNames(self):
        return (self.getXModelName(), self.getFullModelName())