source: orange/Orange/OrangeCanvas/scheme/node.py @ 11614:a4aa7f9b09fd

Revision 11614:a4aa7f9b09fd, 5.9 KB checked in by Ales Erjavec <ales.erjavec@…>, 10 months ago (diff)

Refactored widget state messages handling.

Moved the resposibility for handling messages (OWBaseWidget.widgetStateChanged)
to WidgetsScheme.

Added support for messages in base SchemeNode class.

RevLine 
[11101]1"""
2===========
3Scheme Node
4===========
5
6"""
7
8from PyQt4.QtCore import QObject
9from PyQt4.QtCore import pyqtSignal as Signal
10from PyQt4.QtCore import pyqtProperty as Property
11
12
[11614]13class UserMessage(object):
14    """
15    A user message that should be displayed in a scheme view.
16
17    Paramaters
18    ----------
19    contents : str
20        Message text.
21    severity : int
22        Message severity.
23    message_id : A hashable object
24        Message id.
25    data : dict
26        A dictionary with optional extra data.
27
28    """
29    #: Severity flags
30    Info, Warning, Error = 1, 2, 3
31
32    def __init__(self, contents, severity=Info, message_id=None, data={}):
33        self.contents = contents
34        self.severity = severity
35        self.message_id = message_id
36        self.data = dict(data)
37
38
[11101]39class SchemeNode(QObject):
[11367]40    """
41    A node in a :class:`.Scheme`.
[11101]42
43    Parameters
44    ----------
[11367]45    description : :class:`WidgetDescription`
46        Node description instance.
47    title : str, optional
48        Node title string (if None `description.name` is used).
[11101]49    position : tuple
[11367]50        (x, y) tuple of floats for node position in a visual display.
51    properties : dict
52        Additional extra instance properties (settings, widget geometry, ...)
53    parent : :class:`QObject`
[11101]54        Parent object.
55
56    """
57
58    def __init__(self, description, title=None, position=None,
59                 properties=None, parent=None):
60        QObject.__init__(self, parent)
61        self.description = description
62
63        if title is None:
64            title = description.name
65
66        self.__title = title
67        self.__position = position or (0, 0)
68        self.__progress = -1
69        self.__processing_state = 0
[11614]70        self.__state_messages = {}
[11101]71        self.properties = properties or {}
72
73    def input_channels(self):
74        """
[11367]75        Return a list of input channels (:class:`InputSignal`) for the node.
76        """
77        return list(self.description.inputs)
[11101]78
79    def output_channels(self):
80        """
[11367]81        Return a list of output channels (:class:`OutputSignal`) for the node.
82        """
83        return list(self.description.outputs)
[11101]84
85    def input_channel(self, name):
[11367]86        """
87        Return the input channel matching `name`. Raise a `ValueError`
[11101]88        if not found.
89
90        """
91        for channel in self.input_channels():
92            if channel.name == name:
93                return channel
[11302]94        raise ValueError("%r is not a valid input channel name for %r." % \
95                         (name, self.description.name))
[11101]96
97    def output_channel(self, name):
[11367]98        """
99        Return the output channel matching `name`. Raise an `ValueError`
[11101]100        if not found.
101
102        """
103        for channel in self.output_channels():
104            if channel.name == name:
105                return channel
[11302]106        raise ValueError("%r is not a valid output channel name for %r." % \
107                         (name, self.description.name))
[11101]108
[11419]109    #: The title of the node has changed
[11101]110    title_changed = Signal(unicode)
111
112    def set_title(self, title):
[11367]113        """
114        Set the node title.
[11101]115        """
116        if self.__title != title:
117            self.__title = unicode(title)
118            self.title_changed.emit(self.__title)
119
120    def title(self):
[11367]121        """
[11419]122        The node title.
[11101]123        """
124        return self.__title
125
126    title = Property(unicode, fset=set_title, fget=title)
127
[11419]128    #: Position of the node in the scheme has changed
[11101]129    position_changed = Signal(tuple)
130
131    def set_position(self, pos):
[11367]132        """
133        Set the position (``(x, y)`` tuple) of the node.
[11101]134        """
135        if self.__position != pos:
136            self.__position = pos
137            self.position_changed.emit(pos)
138
139    def position(self):
[11367]140        """
141        ``(x, y)`` tuple containing the position of the node in the scheme.
[11101]142        """
143        return self.__position
144
145    position = Property(tuple, fset=set_position, fget=position)
146
[11419]147    #: Node's progress value has changed.
[11101]148    progress_changed = Signal(float)
149
150    def set_progress(self, value):
[11367]151        """
152        Set the progress value.
[11101]153        """
154        if self.__progress != value:
155            self.__progress = value
156            self.progress_changed.emit(value)
157
158    def progress(self):
[11367]159        """
[11419]160        The current progress value. -1 if progress is not set.
[11101]161        """
162        return self.__progress
163
164    progress = Property(float, fset=set_progress, fget=progress)
165
[11419]166    #: Node's processing state has changed.
[11101]167    processing_state_changed = Signal(int)
168
169    def set_processing_state(self, state):
[11367]170        """
171        Set the node processing state.
[11101]172        """
173        if self.__processing_state != state:
174            self.__processing_state = state
175            self.processing_state_changed.emit(state)
176
177    def processing_state(self):
[11367]178        """
[11419]179        The node processing state, 0 for not processing, 1 the node is busy.
[11101]180        """
181        return self.__processing_state
182
183    processing_state = Property(int, fset=set_processing_state,
[11367]184                                fget=processing_state)
[11101]185
186    def set_tool_tip(self, tool_tip):
187        if self.__tool_tip != tool_tip:
188            self.__tool_tip = tool_tip
189
190    def tool_tip(self):
191        return self.__tool_tip
192
193    tool_tip = Property(str, fset=set_tool_tip,
[11367]194                        fget=tool_tip)
195
[11614]196    def set_state_message(self, message):
197        """
198        Set a message to be displayed by a scheme view for this node.
199        """
200        if message.message_id in self.__state_messages and \
201                not message.contents:
202            del self.__state_messages[message.message_id]
203
204        self.__state_messages[message.message_id] = message
205
206        self.state_message_changed.emit(message)
207
208    #: The node's state message has changed
209    state_message_changed = Signal(UserMessage)
210
[11367]211    def __str__(self):
212        return u"SchemeNode(description_id=%s, title=%r, ...)" % \
213                (str(self.description.id), self.title)
214
215    def __repr__(self):
216        return str(self)
Note: See TracBrowser for help on using the repository browser.