source: orange/Orange/OrangeCanvas/scheme/link.py @ 11419:719c8b4b6b69

Revision 11419:719c8b4b6b69, 5.4 KB checked in by Ales Erjavec <ales.erjavec@…>, 13 months ago (diff)

Fixed docstrings for scheme subpackage.

RevLine 
[11101]1"""
2===========
3Scheme Link
4===========
5
6"""
7
8from PyQt4.QtCore import QObject
9from PyQt4.QtCore import pyqtSignal as Signal
10from PyQt4.QtCore import pyqtProperty as Property
11
12from .utils import name_lookup
13from .errors import IncompatibleChannelTypeError
14
15
16def compatible_channels(source_channel, sink_channel):
[11367]17    """
18    Do the channels in link have compatible types, i.e. can they be
[11101]19    connected based on their type.
20
21    """
22    source_type = name_lookup(source_channel.type)
23    sink_type = name_lookup(sink_channel.type)
24    ret = issubclass(source_type, sink_type)
25    if source_channel.dynamic:
26        ret = ret or issubclass(sink_type, source_type)
27    return ret
28
29
30def can_connect(source_node, sink_node):
[11367]31    """
32    Return True if any output from `source_node` can be connected to
[11101]33    any input of `sink_node`.
34
35    """
36    return bool(possible_links(source_node, sink_node))
37
38
39def possible_links(source_node, sink_node):
[11367]40    """
41    Return a list of (OutputSignal, InputSignal) tuples, that
[11101]42    can connect the two nodes.
43
44    """
45    possible = []
46    for source in source_node.output_channels():
47        for sink in sink_node.input_channels():
48            if compatible_channels(source, sink):
49                possible.append((source, sink))
50    return possible
51
52
53class SchemeLink(QObject):
[11367]54    """
55    A instantiation of a link between two :class:`.SchemeNode` instances
56    in a :class:`.Scheme`.
[11101]57
58    Parameters
59    ----------
[11367]60    source_node : :class:`.SchemeNode`
[11101]61        Source node.
[11367]62    source_channel : :class:`OutputSignal`
[11101]63        The source widget's signal.
[11367]64    sink_node : :class:`.SchemeNode`
[11101]65        The sink node.
[11367]66    sink_channel : :class:`InputSignal`
[11101]67        The sink widget's input signal.
68    properties : `dict`
69        Additional link properties.
70
71    """
72
[11419]73    #: The link enabled state has changed
[11101]74    enabled_changed = Signal(bool)
[11419]75
76    #: The link dynamic enabled state has changed.
[11101]77    dynamic_enabled_changed = Signal(bool)
78
79    def __init__(self, source_node, source_channel,
80                 sink_node, sink_channel, enabled=True, properties=None,
81                 parent=None):
82        QObject.__init__(self, parent)
83        self.source_node = source_node
84
85        if isinstance(source_channel, basestring):
86            source_channel = source_node.output_channel(source_channel)
87        elif source_channel not in source_node.output_channels():
88            raise ValueError("%r not in in nodes output channels." \
89                             % source_channel)
90
91        self.source_channel = source_channel
92
93        self.sink_node = sink_node
94
95        if isinstance(sink_channel, basestring):
96            sink_channel = sink_node.input_channel(sink_channel)
97        elif sink_channel not in sink_node.input_channels():
98            raise ValueError("%r not in in nodes input channels." \
99                             % source_channel)
100
101        self.sink_channel = sink_channel
102
103        if not compatible_channels(source_channel, sink_channel):
104            raise IncompatibleChannelTypeError(
105                    "Cannot connect %r to %r" \
[11302]106                    % (source_channel.type, sink_channel.type)
[11101]107                )
108
109        self.__enabled = enabled
110        self.__dynamic_enabled = False
111        self.__tool_tip = ""
112        self.properties = properties or {}
113
114    def source_type(self):
[11367]115        """
116        Return the type of the source channel.
[11101]117        """
118        return name_lookup(self.source_channel.type)
119
120    def sink_type(self):
[11367]121        """
122        Return the type of the sink channel.
[11101]123        """
124        return name_lookup(self.sink_channel.type)
125
126    def is_dynamic(self):
[11367]127        """
128        Is this link dynamic.
[11101]129        """
130        return self.source_channel.dynamic and \
[11182]131            issubclass(self.sink_type(), self.source_type()) and \
132            not (self.sink_type() is self.source_type())
[11101]133
[11367]134    def set_enabled(self, enabled):
[11101]135        """
[11367]136        Enable/disable the link.
[11101]137        """
138        if self.__enabled != enabled:
139            self.__enabled = enabled
140            self.enabled_changed.emit(enabled)
141
[11367]142    def enabled(self):
143        """
144        Is this link enabled.
145        """
146        return self.__enabled
147
[11101]148    enabled = Property(bool, fget=enabled, fset=set_enabled)
149
150    def set_dynamic_enabled(self, enabled):
[11367]151        """
152        Enable/disable the dynamic link. Has no effect if the link
153        is not dynamic.
[11101]154
155        """
156        if self.is_dynamic() and self.__dynamic_enabled != enabled:
157            self.__dynamic_enabled = enabled
158            self.dynamic_enabled_changed.emit(enabled)
159
160    def dynamic_enabled(self):
[11367]161        """
162        Is this a dynamic link and is `dynamic_enabled` set to `True`
[11101]163        """
164        return self.is_dynamic() and self.__dynamic_enabled
165
166    dynamic_enabled = Property(bool, fget=dynamic_enabled,
[11367]167                               fset=set_dynamic_enabled)
[11101]168
169    def set_tool_tip(self, tool_tip):
[11367]170        """
171        Set the link tool tip.
[11101]172        """
173        if self.__tool_tip != tool_tip:
174            self.__tool_tip = tool_tip
175
176    def tool_tip(self):
[11367]177        """
178        Link tool tip.
[11101]179        """
180        return self.__tool_tip
181
182    tool_tip = Property(str, fget=tool_tip,
[11367]183                        fset=set_tool_tip)
[11267]184
185    def __str__(self):
186        return u"{0}(({1}, {2}) -> ({3}, {4}))".format(
187                    type(self).__name__,
188                    self.source_node.title,
189                    self.source_channel.name,
190                    self.sink_node.title,
191                    self.sink_channel.name
192                )
Note: See TracBrowser for help on using the repository browser.