#****************************************************************************** # # TASTE Msc Diagram Editor # http://taste.tuxfamily.org/ # # This file is part of TASTE Msc Editor. # # TASTE Msc Diagram Editor is free software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # TASTE Msc Diagram Editor 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with TASTE Msc Diagram Editor. If not, see # . # # Author: Angel Esquinas # # Copyright (c) 2012 European Space Agency # #****************************************************************************** """ .. This docstring is intended to use with sphinx. The :class:`msccore.MscElement` class is the base class of almost all msc \ elements. This class is intended to be subclassed. It is a subclass of :class:`QtCore.QObject`, so it can use \ :class:`QtCore.Signal`. The :class:`msccore.MscElement` declares two \ :class:`~QtCore.Signal`: :attr:`MscElement.dataHasChanged` to notify when \ internal data structures or attributes of elements have been modified, and \ :attr:`~MscElement.nameChanged` to notify when the element's name has been changed. The :class:`MscElement` has the attribute :attr:`MscElement.Name` to hold \ the name of the element. To modify the name of the element use the method :meth:`MscElement.setName` and to read the name of the element use :meth:`MscElement.name`. """ from PySide.QtCore import QObject, Signal from PySide.QtCore import QRegExp import mscregexp class MscElement(QObject): ''' Constructs a :class:`MscElement` with the `name` and the given `parent`. :param name: default empty string, Name of the element. :type name: unicode :param parent: default None :type parent: QObject ''' # String to print type of object TYPE = 'MscElement' # Signal that must be emitted when data of the element has changed. # dataChangedSignal = Signal() dataHasChanged = Signal() """ :attr:`dataHasChanged` notify when internal properties of the :class:`MscElement` instance have changed. This signal is emitted within :meth:`dataChanged` method. When :attr:`dataHasChanged` is emitted, :attr:`contentsChanged` should also be emitted, because if the internal properties of `MscElement` are modified this implies that the contents of the object have also changed. .. seealso:: :attr:`MscElement.contentsChanged`, :meth:`MscElement.dataChanged` """ nameChanged = Signal(unicode) """:param unicode: The new name. :type unicode: unicode""" contentsChanged = Signal() u""" :attr:`contentsChanged` signal is emitted when changes in the its child objects or changes in itself exist. When data is changed in an element, because of new objects or other change, this signal must be emitted. The difference with :attr:`dataHasChanged` signal is that dataHasChanged is only emitted when the data is changed in the object itself, not if it's changed in any of its child elements. .. seealso:: :meth:`MscElement.dataChanged`, :attr:`MscElement.dataHasChanged` """ deleted = Signal(QObject) u""" :attr:`deleted` signal is emitted before the :class:`MscElement` object \ is deleted. This signal is emitted within :meth:`MscElement.delete` method. .. seealso:: :meth:`MscElement.delete` """ def __init__(self, name='', parent=None, elemType=TYPE): ''' construct ''' super(MscElement, self).__init__(parent) self._name = '' self._NameRegExp = QRegExp('(' + mscregexp.Name + ')') self.elemType = elemType self.setName(name) self._comment = u"" def setNameRegExp(self, reg=None): u""" Set :class:`QtCore.QRegExp` `reg` as the validator to allow the change of `name` property using :meth:`MscElement.setName`. :param reg: default `None`, :class:Pyside.QtCore.RegExp """ self._NameRegExp = reg # Name def getName(self): return self.name() def name(self): u''' Return the name of the element :rtype: unicode ''' return self._name def setName(self, name): ''' Set the name of the element. :param unicode name: Name of the element. Each :class:`MscElement` object should have a different name. The `name` property is changed with the `name` content if the :data:`msccore.mscregexp.NameRegExpr` property is not set or in case it is, the `name` is partially or fully accepted. By default, this property contains an empty string ''' # isCorrect = self.filterName(name) if self._NameRegExp.indexIn(name) > -1: accepted = self._NameRegExp.cap(1) self._name = accepted self.nameChanged.emit(self._name) self.dataChanged() def setExpression(self, expr): u""" Sets or changes internal properties based on `expr`. :param unicode expr: Expression to obtain the data. If this function is needed it has to be subclassed. *Example:* "process <> extern" could be separated into 3 expressions, (process, <>, extern) to set class properties. By default, this function calls :meth:`MscElement.setName` with `expr` as argument. """ return self.setName(expr) # Comment def setComment(self, comment=u""): u""" Set the comment of the object. :param commment: unicode This property holds the comment of the object. By default, this property contains an empty string .. note:: After the property has changed this method calls \ :meth:`MscElement.dataChanged` emitting the \ :attr:`~MscElement.dataHasChanged` Signal. """ self._comment = comment self.dataChanged() def comment(self): u""" Return the comment. :rtype: unicode This property holds the comment of the object. By default, this property contains an empty string """ return self._comment def dataChanged(self): ''' This function must be called when internal properties of the object have changed. It emits both the "dataChanged" signal and 'contentsChanged' signal. ''' self.dataHasChanged.emit() self.contentsChanged.emit() #self.dataChangedSignal.emit() def _contentsChanged(self): """ This function must be called when internal properties of the object or any of its childs have changed. This function can be overriden to add more functionality. """ self.contentsChanged.emit() #Delete def delete(self): u""" This method must be overriden. By default only the signal :attr:`MscElement.deleted` is emitted. This method should be called inside the overriding method to emit the :attr:`MscElement.deleted` before any operation is done. This allows any other object that has a reference to this object know that it will be deleted and remove all of its references. """ self.deleted.emit(self) def accept(self, visitor): u''' Implements the visitor pattern. :param visitor: :type visitor: msccore.MscVisitor .. note:: This function must be overriden in a subclass to use the \ visitor pattern. ''' pass # OUTPUT def __str__(self): return "<<{0}: {1}. Comment {2}>>".format(self.elemType, self._name, self.comment())