Ignore:
Files:
26 added
33 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeCanvas/application/canvasmain.py

    r11350 r11375  
    15481548        log.info("Setting help to url: %r", url) 
    15491549        if self.open_in_external_browser: 
    1550             QDesktopServices.openUrl(QUrl(url)) 
     1550            url = QUrl(url) 
     1551            if not QDesktopServices.openUrl(url): 
     1552                # Try fixing some common problems. 
     1553                url = QUrl.fromUserInput(url.toString()) 
     1554                # 'fromUserInput' includes possible fragment into the path 
     1555                # (which prevents it to open local files) so we reparse it 
     1556                # again. 
     1557                url = QUrl(url.toString()) 
     1558                QDesktopServices.openUrl(url) 
    15511559        else: 
    15521560            self.help_view.load(QUrl(url)) 
  • Orange/OrangeCanvas/application/widgettoolbox.py

    r11309 r11372  
    3232 
    3333def iter_item(item): 
    34     """Iterate over child items of a `QStandardItem`. 
     34    """ 
     35    Iterate over child items of a `QStandardItem`. 
    3536    """ 
    3637    for i in range(item.rowCount()): 
     
    3940 
    4041class WidgetToolGrid(ToolGrid): 
    41     """A Tool Grid with widget buttons. Populates the widget buttons 
     42    """ 
     43    A Tool Grid with widget buttons. Populates the widget buttons 
    4244    from a item model. Also adds support for drag operations. 
    4345 
     
    5961 
    6062    def setModel(self, model, rootIndex=QModelIndex()): 
    61         """Set a model (`QStandardItemModel`) for the tool grid. The 
     63        """ 
     64        Set a model (`QStandardItemModel`) for the tool grid. The 
    6265        widget actions are children of the rootIndex. 
    6366 
     
    8184 
    8285    def model(self): 
    83         """Return the model for the tool grid. 
     86        """ 
     87        Return the model for the tool grid. 
    8488        """ 
    8589        return self.__model 
    8690 
    8791    def rootIndex(self): 
     92        """ 
     93        Return the root index of the model. 
     94        """ 
    8895        return self.__rootIndex 
    8996 
    9097    def setActionRole(self, role): 
    91         """Set the action role. 
     98        """ 
     99        Set the action role. This is the model role containing a 
     100        `QAction` instance. 
     101 
    92102        """ 
    93103        if self.__actionRole != role: 
     
    97107 
    98108    def actionRole(self): 
    99         """Return the action role. 
     109        """ 
     110        Return the action role. 
    100111        """ 
    101112        return self.__actionRole 
     
    114125            button.removeEventFilter(self.__dragListener) 
    115126            button.removeEventFilter(self.__statusTipPromoter) 
     127 
    116128            # Removes the button 
    117129            ToolGrid.actionEvent(self, event) 
     
    121133 
    122134    def __initFromModel(self, model, rootIndex): 
    123         """Initialize the grid from the model with rootIndex as the root. 
     135        """ 
     136        Initialize the grid from the model with rootIndex as the root. 
    124137        """ 
    125138        if not rootIndex.isValid(): 
     
    134147 
    135148    def __insertItem(self, index, item): 
    136         """Insert a widget action (from a `QStandardItem`) at index. 
     149        """ 
     150        Insert a widget action (from a `QStandardItem`) at index. 
    137151        """ 
    138152        value = item.data(self.__actionRole) 
     
    150164 
    151165    def __on_rowsInserted(self, parent, start, end): 
    152         """Insert items from range start:end into the grid. 
     166        """ 
     167        Insert items from range start:end into the grid. 
    153168        """ 
    154169        item = self.__model.itemForIndex(parent) 
     
    159174 
    160175    def __on_rowsRemoved(self, parent, start, end): 
    161         """Remove items from range start:end from the grid. 
     176        """ 
     177        Remove items from range start:end from the grid. 
    162178        """ 
    163179        item = self.__model.itemForIndex(parent) 
     
    168184 
    169185    def __startDrag(self, button): 
    170         """Start a drag from button 
     186        """ 
     187        Start a drag from button 
    171188        """ 
    172189        action = button.defaultAction() 
     
    185202 
    186203class DragStartEventListener(QObject): 
    187     """An event filter object that can be used to detect drag start 
     204    """ 
     205    An event filter object that can be used to detect drag start 
    188206    operation on buttons which otherwise do not support it. 
    189207 
    190208    """ 
    191209    dragStartOperationRequested = Signal(QAbstractButton) 
     210    """A drag operation started on a button.""" 
    192211 
    193212    def __init__(self, parent=None, **kwargs): 
     
    223242 
    224243class WidgetToolBox(ToolBox): 
     244    """ 
     245    `WidgetToolBox` widget shows a tool box containing button grids of 
     246    actions for a :class:`QtWidgetRegistry` item model. 
     247 
     248    """ 
    225249 
    226250    triggered = Signal(QAction) 
     
    236260 
    237261    def setIconSize(self, size): 
    238         """Set the widget icon size. 
     262        """ 
     263        Set the widget icon size (icons in the button grid). 
    239264        """ 
    240265        self.__iconSize = size 
     
    243268 
    244269    def iconSize(self): 
    245         """Return the widget buttons icon size. 
     270        """ 
     271        Return the widget buttons icon size. 
    246272        """ 
    247273        return self.__iconSize 
     
    251277 
    252278    def setButtonSize(self, size): 
    253         """Set fixed widget button size. 
     279        """ 
     280        Set fixed widget button size. 
    254281        """ 
    255282        self.__buttonSize = size 
     
    258285 
    259286    def buttonSize(self): 
     287        """Return the widget button size 
     288        """ 
    260289        return self.__buttonSize 
    261290 
     
    264293 
    265294    def saveState(self): 
    266         """Return the toolbox state. 
     295        """ 
     296        Return the toolbox state (as a `QByteArray`). 
    267297 
    268298        .. note:: Individual tabs are stored by their action's text. 
     
    283313 
    284314    def restoreState(self, state): 
    285         """Restore the toolbox from a :class:`QByteArray` `state`. 
     315        """ 
     316        Restore the toolbox from a :class:`QByteArray` `state`. 
    286317 
    287318        .. note:: The toolbox should already be populated for the state 
     
    304335 
    305336    def setModel(self, model): 
    306         """Set the widget registry model for this toolbox. 
     337        """ 
     338        Set the widget registry model (:class:`QStandardItemModel`) for 
     339        this toolbox. 
     340 
    307341        """ 
    308342        if self.__model is not None: 
    309343            self.__model.itemChanged.disconnect(self.__on_itemChanged) 
    310344            self.__model.rowsInserted.disconnect(self.__on_rowsInserted) 
    311             self.__model.rowsRemoved.disconect(self.__on_rowsRemoved) 
     345            self.__model.rowsRemoved.disconnect(self.__on_rowsRemoved) 
    312346 
    313347        self.__model = model 
     
    324358 
    325359    def __insertItem(self, item, index): 
    326         """Insert category item at index. 
     360        """ 
     361        Insert category item at index. 
    327362        """ 
    328363        grid = WidgetToolGrid() 
     
    363398 
    364399    def __on_itemChanged(self, item): 
    365         """Item contents have changed. 
     400        """ 
     401        Item contents have changed. 
    366402        """ 
    367403        parent = item.parent() 
     
    373409 
    374410    def __on_rowsInserted(self, parent, start, end): 
    375         """Items have been inserted in the model. 
     411        """ 
     412        Items have been inserted in the model. 
    376413        """ 
    377414        # Only the top level items (categories) are handled here. 
     
    383420 
    384421    def __on_rowsRemoved(self, parent, start, end): 
    385         """Rows have been removed from the model. 
     422        """ 
     423        Rows have been removed from the model. 
    386424        """ 
    387425        # Only the top level items (categories) are handled here. 
  • Orange/OrangeCanvas/canvas/__init__.py

    r11102 r11369  
     1""" 
     2====== 
     3Canvas 
     4====== 
     5 
     6The :mod:`canvas` package contains classes for visualizing the 
     7contents of a :class:`.scheme.Scheme`, based on the Qt's Graphics view 
     8framework. 
     9 
     10""" 
     11 
     12__all__ = ["scene", "layout", "view", "items"] 
  • Orange/OrangeCanvas/canvas/items/linkitem.py

    r11343 r11369  
    77    QGraphicsItem, QGraphicsEllipseItem, QGraphicsPathItem, QGraphicsObject, 
    88    QGraphicsTextItem, QGraphicsDropShadowEffect, QPen, QBrush, QColor, 
    9     QPainterPath, QFont, QTransform 
     9    QPainterPath, QTransform 
    1010) 
    1111 
     
    107107 
    108108class LinkItem(QGraphicsObject): 
    109     """A Link in the canvas. 
     109    """ 
     110    A Link in the canvas. 
    110111    """ 
    111112 
     
    144145 
    145146    def setSourceItem(self, item, anchor=None): 
    146         """Set the source `item` (:class:`CanvasNodeItem`). Use `anchor` 
    147         (:class:`AnchorPoint) as the curve start point (if `None` a new 
     147        """ 
     148        Set the source `item` (:class:`NodeItem`). Use `anchor` 
     149        (:class:`AnchorPoint`) as the curve start point (if ``None`` a new 
    148150        output anchor will be created). 
    149151 
    150         Setting item to `None` and a valid anchor is a valid operation 
    151         (for instance while mouse dragging one and of the link). 
     152        Setting item to ``None`` and a valid anchor is a valid operation 
     153        (for instance while mouse dragging one end of the link). 
    152154 
    153155        """ 
     
    193195 
    194196    def setSinkItem(self, item, anchor=None): 
    195         """Set the sink `item` (:class:`CanvasNodeItem`). Use `anchor` 
    196         (:class:`AnchorPoint) as the curve end point (if `None` a new 
     197        """ 
     198        Set the sink `item` (:class:`NodeItem`). Use `anchor` 
     199        (:class:`AnchorPoint`) as the curve end point (if ``None`` a new 
    197200        input anchor will be created). 
    198201 
    199         Setting item to `None` and a valid anchor is a valid operation 
     202        Setting item to ``None`` and a valid anchor is a valid operation 
    200203        (for instance while mouse dragging one and of the link). 
     204 
    201205        """ 
    202206        if item is not None and anchor is not None: 
     
    242246    def setFont(self, font): 
    243247        """ 
    244         Set the channel names font. 
     248        Set the font for the channel names text. 
    245249        """ 
    246250        if font != self.font(): 
     
    250254    def font(self): 
    251255        """ 
    252         Return the channel names font. 
     256        Return the font for the channel names text. 
    253257        """ 
    254258        return self.linkTextItem.font() 
    255259 
    256260    def setChannelNamesVisible(self, visible): 
     261        """ 
     262        Set the visibility of the channel name text. 
     263        """ 
    257264        self.linkTextItem.setVisible(visible) 
    258265 
    259266    def setSourceName(self, name): 
     267        """ 
     268        Set the name of the source (used in channel name text). 
     269        """ 
    260270        if self.__sourceName != name: 
    261271            self.__sourceName = name 
     
    263273 
    264274    def sourceName(self): 
     275        """ 
     276        Return the source name. 
     277        """ 
    265278        return self.__sourceName 
    266279 
    267280    def setSinkName(self, name): 
     281        """ 
     282        Set the name of the sink (used in channel name text). 
     283        """ 
    268284        if self.__sinkName != name: 
    269285            self.__sinkName = name 
     
    271287 
    272288    def sinkName(self): 
     289        """ 
     290        Return the sink name. 
     291        """ 
    273292        return self.__sinkName 
    274293 
     
    378397 
    379398    def setEnabled(self, enabled): 
     399        """ 
     400        Set link enabled state. When disabled the link is rendered with a 
     401        dashed line. 
     402 
     403        """ 
    380404        QGraphicsObject.setEnabled(self, enabled) 
    381405 
    382406    def setDynamicEnabled(self, enabled): 
     407        """ 
     408        Set the link's dynamic enabled state. 
     409 
     410        If the link is `dynamic` it will be rendered in red/green color 
     411        respectively depending on the state of the dynamic enabled state. 
     412 
     413        """ 
    383414        if self.__dynamicEnabled != enabled: 
    384415            self.__dynamicEnabled = enabled 
     
    387418 
    388419    def isDynamicEnabled(self): 
     420        """ 
     421        Is the link dynamic enabled. 
     422        """ 
    389423        return self.__dynamicEnabled 
    390424 
    391425    def setDynamic(self, dynamic): 
     426        """ 
     427        Mark the link as dynamic (e.i. it responds to the 
     428        ``setDynamicEnabled``). 
     429 
     430        """ 
    392431        if self.__dynamic != dynamic: 
    393432            self.__dynamic = dynamic 
     
    395434 
    396435    def isDynamic(self): 
     436        """ 
     437        Is the link dynamic. 
     438        """ 
    397439        return self.__dynamic 
    398440 
  • Orange/OrangeCanvas/canvas/items/nodeitem.py

    r11343 r11369  
    99    QGraphicsItem, QGraphicsPathItem, QGraphicsObject, 
    1010    QGraphicsTextItem, QGraphicsDropShadowEffect, QGraphicsView, 
    11     QPen, QBrush, QColor, QPalette, QFont, QIcon, QStyle, 
    12     QPainter, QPainterPath, QPainterPathStroker, QApplication 
     11    QPen, QBrush, QColor, QPalette, QIcon, QStyle, QPainter, 
     12    QPainterPath, QPainterPathStroker, QApplication 
    1313) 
    1414 
     
    2626 
    2727def create_palette(light_color, color): 
    28     """Return a new `QPalette` from for the NodeShapeItem. 
    29  
     28    """ 
     29    Return a new :class:`QPalette` from for the :class:`NodeBodyItem`. 
    3030    """ 
    3131    palette = QPalette() 
     
    4949 
    5050def default_palette(): 
    51     """Create and return a default palette for a node. 
    52  
     51    """ 
     52    Create and return a default palette for a node. 
    5353    """ 
    5454    return create_palette(QColor(NAMED_COLORS["light-orange"]), 
     
    6161 
    6262class NodeBodyItem(QGraphicsPathItem): 
    63     """The central part (body) of the `NodeItem`. 
    64  
     63    """ 
     64    The central part (body) of the `NodeItem`. 
    6565    """ 
    6666    def __init__(self, parent=None): 
     
    9696    # paths (for instance rounded rect, ...) 
    9797    def setShapeRect(self, rect): 
    98         """Set the shape items `rect`. The item should be confined within 
     98        """ 
     99        Set the item's shape `rect`. The item should be confined within 
    99100        this rect. 
    100101 
     
    106107 
    107108    def setPalette(self, palette): 
    108         """Set the shape color palette. 
     109        """ 
     110        Set the body color palette (:class:`QPalette`). 
    109111        """ 
    110112        self.palette = palette 
     
    112114 
    113115    def setProcessingState(self, state): 
    114         """Set the processing state of the node. 
     116        """ 
     117        Set the processing state of the node. 
    115118        """ 
    116119        self.__processingState = state 
     
    118121 
    119122    def setProgress(self, progress): 
     123        """ 
     124        Set the progress indicator state of the node. `progress` should 
     125        be a number between 0 and 100. 
     126 
     127        """ 
    120128        self.__progress = progress 
    121129        self.update() 
     
    132140 
    133141    def paint(self, painter, option, widget): 
    134         """Paint the shape and a progress meter. 
     142        """ 
     143        Paint the shape and a progress meter. 
    135144        """ 
    136145        # Let the default implementation draw the shape 
     
    186195 
    187196    def setSelected(self, selected): 
    188         """Set the `selected` state. 
    189  
    190         .. note:: The item does not have QGraphicsItem.ItemIsSelectable flag. 
     197        """ 
     198        Set the `selected` state. 
     199 
     200        .. note:: The item does not have `QGraphicsItem.ItemIsSelectable` flag. 
    191201                  This property is instead controlled by the parent NodeItem. 
    192202 
     
    196206 
    197207    def setHasFocus(self, focus): 
    198         """Set the `has focus` state. 
    199  
    200         .. note:: The item does not have QGraphicsItem.ItemIsFocusable flag. 
     208        """ 
     209        Set the `has focus` state. 
     210 
     211        .. note:: The item does not have `QGraphicsItem.ItemIsFocusable` flag. 
    201212                  This property is instead controlled by the parent NodeItem. 
     213 
    202214        """ 
    203215        self.__hasFocus = focus 
     
    206218 
    207219class AnchorPoint(QGraphicsObject): 
    208     """A anchor indicator on the NodeAnchorItem 
    209     """ 
    210  
     220    """ 
     221    A anchor indicator on the :class:`NodeAnchorItem`. 
     222    """ 
     223 
     224    # Signal emitted when the item's scene position changes. 
    211225    scenePositionChanged = Signal(QPointF) 
     226 
    212227    anchorDirectionChanged = Signal(QPointF) 
    213228 
     
    220235 
    221236    def anchorScenePos(self): 
    222         """Return anchor position in scene coordinates. 
     237        """ 
     238        Return anchor position in scene coordinates. 
    223239        """ 
    224240        return self.mapToScene(QPointF(0, 0)) 
    225241 
    226242    def setAnchorDirection(self, direction): 
    227         """Set the preferred direction (QPointF) in item coordinates. 
     243        """ 
     244        Set the preferred direction (QPointF) in item coordinates. 
    228245        """ 
    229246        if self.__direction != direction: 
     
    232249 
    233250    def anchorDirection(self): 
    234         """Return the preferred anchor direction. 
     251        """ 
     252        Return the preferred anchor direction. 
    235253        """ 
    236254        return self.__direction 
     
    247265 
    248266class NodeAnchorItem(GraphicsPathObject): 
    249     """The left/right widget input/output anchors. 
     267    """ 
     268    The left/right widget input/output anchors. 
    250269    """ 
    251270 
     
    284303 
    285304    def parentNodeItem(self): 
    286         """Return a parent `NodeItem` or `None` if this anchor's 
    287         parent is not a `NodeItem` instance. 
     305        """ 
     306        Return a parent :class:`NodeItem` or ``None`` if this anchor's 
     307        parent is not a :class:`NodeItem` instance. 
    288308 
    289309        """ 
     
    291311 
    292312    def setAnchorPath(self, path): 
    293         """Set the anchor's curve path as a QPainterPath. 
     313        """ 
     314        Set the anchor's curve path as a :class:`QPainterPath`. 
    294315        """ 
    295316        self.__anchorPath = path 
     
    318339 
    319340    def anchorPath(self): 
    320         """Return the QPainterPath of the anchor path (a curve on 
    321         which the anchor points lie) 
     341        """ 
     342        Return the anchor path (:class:`QPainterPath`). This is a curve on 
     343        which the anchor points lie. 
    322344 
    323345        """ 
     
    325347 
    326348    def setAnchored(self, anchored): 
    327         """Set the items anchored state. When false the item draws it self 
     349        """ 
     350        Set the items anchored state. When ``False`` the item draws it self 
    328351        with a dotted stroke. 
    329352 
     
    338361 
    339362    def setConnectionHint(self, hint=None): 
    340         """Set the connection hint. This can be used to indicate if 
     363        """ 
     364        Set the connection hint. This can be used to indicate if 
    341365        a connection can be made or not. 
    342366 
     
    345369 
    346370    def count(self): 
    347         """Return the number of anchor points. 
     371        """ 
     372        Return the number of anchor points. 
    348373        """ 
    349374        return len(self.__points) 
    350375 
    351376    def addAnchor(self, anchor, position=0.5): 
    352         """Add a new AnchorPoint to this item and return it's index. 
     377        """ 
     378        Add a new :class:`AnchorPoint` to this item and return it's index. 
     379 
     380        The `position` specifies where along the `anchorPath` is the new 
     381        point inserted. 
     382 
    353383        """ 
    354384        return self.insertAnchor(self.count(), anchor, position) 
    355385 
    356386    def insertAnchor(self, index, anchor, position=0.5): 
    357         """Insert a new AnchorPoint at `index`. 
     387        """ 
     388        Insert a new :class:`AnchorPoint` at `index`. 
     389 
     390        See also 
     391        -------- 
     392        NodeAnchorItem.addAnchor 
     393 
    358394        """ 
    359395        if anchor in self.__points: 
     
    374410 
    375411    def removeAnchor(self, anchor): 
    376         """Remove and delete the anchor point. 
     412        """ 
     413        Remove and delete the anchor point. 
    377414        """ 
    378415        anchor = self.takeAnchor(anchor) 
     
    383420 
    384421    def takeAnchor(self, anchor): 
    385         """Remove the anchor but don't delete it. 
     422        """ 
     423        Remove the anchor but don't delete it. 
    386424        """ 
    387425        index = self.__points.index(anchor) 
     
    408446 
    409447    def anchorPoints(self): 
    410         """Return a list of anchor points. 
     448        """ 
     449        Return a list of anchor points. 
    411450        """ 
    412451        return list(self.__points) 
    413452 
    414453    def anchorPoint(self, index): 
    415         """Return the anchor point at `index`. 
     454        """ 
     455        Return the anchor point at `index`. 
    416456        """ 
    417457        return self.__points[index] 
    418458 
    419459    def setAnchorPositions(self, positions): 
    420         """Set the anchor positions in percentages (0..1) along 
    421         the path curve. 
    422  
     460        """ 
     461        Set the anchor positions in percentages (0..1) along the path curve. 
    423462        """ 
    424463        if self.__pointPositions != positions: 
     
    428467 
    429468    def anchorPositions(self): 
    430         """Return the positions of anchor points as a list of floats where 
     469        """ 
     470        Return the positions of anchor points as a list of floats where 
    431471        each float is between 0 and 1 and specifies where along the anchor 
    432472        path does the point lie (0 is at start 1 is at the end). 
     
    464504 
    465505class SourceAnchorItem(NodeAnchorItem): 
    466     """A source anchor item 
     506    """ 
     507    A source anchor item 
    467508    """ 
    468509    pass 
     
    470511 
    471512class SinkAnchorItem(NodeAnchorItem): 
    472     """A sink anchor item. 
     513    """ 
     514    A sink anchor item. 
    473515    """ 
    474516    pass 
     
    476518 
    477519def standard_icon(standard_pixmap): 
    478     """Return return the application style's standard icon for a 
     520    """ 
     521    Return return the application style's standard icon for a 
    479522    `QStyle.StandardPixmap`. 
    480523 
     
    485528 
    486529class GraphicsIconItem(QGraphicsItem): 
    487     """A graphics item displaying an `QIcon`. 
     530    """ 
     531    A graphics item displaying an :class:`QIcon`. 
    488532    """ 
    489533    def __init__(self, parent=None, icon=None, iconSize=None, **kwargs): 
     
    505549 
    506550    def setIcon(self, icon): 
    507         """Set the icon (:class:`QIcon`). 
     551        """ 
     552        Set the icon (:class:`QIcon`). 
    508553        """ 
    509554        if self.__icon != icon: 
     
    512557 
    513558    def icon(self): 
    514         """Return the icon (:class:`QIcon`). 
     559        """ 
     560        Return the icon (:class:`QIcon`). 
    515561        """ 
    516562        return QIcon(self.__icon) 
    517563 
    518564    def setIconSize(self, size): 
    519         """Set the icon (and this item's) size (:class:`QSize`). 
     565        """ 
     566        Set the icon (and this item's) size (:class:`QSize`). 
    520567        """ 
    521568        if self.__iconSize != size: 
     
    525572 
    526573    def iconSize(self): 
    527         """Return the icon size (:class:`QSize`). 
     574        """ 
     575        Return the icon size (:class:`QSize`). 
    528576        """ 
    529577        return QSize(self.__iconSize) 
    530578 
    531579    def setTransformationMode(self, mode): 
    532         """Set pixmap transformation mode. (`Qt.SmoothTransformation` or 
     580        """ 
     581        Set pixmap transformation mode. (`Qt.SmoothTransformation` or 
    533582        `Qt.FastTransformation`). 
    534583 
     
    539588 
    540589    def transformationMode(self): 
    541         """Return the pixmap transformation mode. 
     590        """ 
     591        Return the pixmap transformation mode. 
    542592        """ 
    543593        return self.__transformationMode 
     
    588638 
    589639class NodeItem(QGraphicsObject): 
    590     """An widget node item in the canvas. 
    591     """ 
    592  
     640    """ 
     641    An widget node item in the canvas. 
     642    """ 
     643 
     644    # Scene position of the node has changed. 
    593645    positionChanged = Signal() 
    594     """Position of the node on the canvas changed""" 
    595  
     646 
     647    # Geometry of the channel anchors changed 
    596648    anchorGeometryChanged = Signal() 
    597     """Geometry of the channel anchors changed""" 
    598  
     649 
     650    # The item has been activated (by a mouse double click or a keyboard). 
    599651    activated = Signal() 
    600     """The item has been activated (by a mouse double click or a keyboard)""" 
    601  
     652 
     653    # The item is under the mouse. 
    602654    hovered = Signal() 
    603     """The item is under the mouse.""" 
    604  
     655 
     656    #: Span of the anchor in degrees 
    605657    ANCHOR_SPAN_ANGLE = 90 
    606     """Span of the anchor in degrees""" 
    607  
     658 
     659    #: Z value of the item 
    608660    Z_VALUE = 100 
    609     """Z value of the item""" 
    610661 
    611662    def __init__(self, widget_description=None, parent=None, **kwargs): 
     
    649700    @classmethod 
    650701    def from_node(cls, node): 
    651         """Create an `NodeItem` instance and initialize it from an 
    652         `SchemeNode` instance. 
     702        """ 
     703        Create an :class:`NodeItem` instance and initialize it from a 
     704        :class:`SchemeNode` instance. 
    653705 
    654706        """ 
     
    660712    @classmethod 
    661713    def from_node_meta(cls, meta_description): 
    662         """Create an `NodeItem` instance from a node meta description. 
     714        """ 
     715        Create an `NodeItem` instance from a node meta description. 
    663716        """ 
    664717        self = cls() 
     
    667720 
    668721    def setupGraphics(self): 
    669         """Set up the graphics. 
     722        """ 
     723        Set up the graphics. 
    670724        """ 
    671725        shape_rect = QRectF(-24, -24, 48, 48) 
     
    708762        self.infoItem = iconItem(QStyle.SP_MessageBoxInformation) 
    709763 
     764    # TODO: Remove the set[Widget|Category]Description. The user should 
     765    # handle setting of icons, title, ... 
    710766    def setWidgetDescription(self, desc): 
    711         """Set widget description. 
     767        """ 
     768        Set widget description. 
    712769        """ 
    713770        self.widget_description = desc 
     
    731788 
    732789    def setWidgetCategory(self, desc): 
     790        """ 
     791        Set the widget category. 
     792        """ 
    733793        self.category_description = desc 
    734794        if desc and desc.background: 
     
    739799 
    740800    def setIcon(self, icon): 
    741         """Set the widget's icon 
     801        """ 
     802        Set the node item's icon. 
    742803        """ 
    743804        if isinstance(icon, QIcon): 
     
    749810 
    750811    def setColor(self, color, selectedColor=None): 
    751         """Set the widget color. 
     812        """ 
     813        Set the widget color. 
    752814        """ 
    753815        if selectedColor is None: 
     
    756818        self.shapeItem.setPalette(palette) 
    757819 
    758     def setPalette(self): 
    759         """ 
    760         """ 
    761         pass 
     820    def setPalette(self, palette): 
     821        # TODO: The palette should override the `setColor` 
     822        raise NotImplementedError 
    762823 
    763824    def setTitle(self, title): 
    764         """Set the widget title. 
     825        """ 
     826        Set the node title. The title text is displayed at the bottom of the 
     827        node. 
     828 
    765829        """ 
    766830        self.__title = title 
     
    768832 
    769833    def title(self): 
     834        """ 
     835        Return the node title. 
     836        """ 
    770837        return self.__title 
    771838 
    772     title_ = Property(unicode, fget=title, fset=setTitle) 
     839    title_ = Property(unicode, fget=title, fset=setTitle, 
     840                      doc="Node title text.") 
    773841 
    774842    def setFont(self, font): 
    775843        """ 
    776         Set the title text font. 
     844        Set the title text font (:class:`QFont`). 
    777845        """ 
    778846        if font != self.font(): 
     
    788856 
    789857    def setProcessingState(self, state): 
    790         """Set the node processing state i.e. the node is processing 
     858        """ 
     859        Set the node processing state i.e. the node is processing 
    791860        (is busy) or is idle. 
    792861 
     
    800869 
    801870    def processingState(self): 
     871        """ 
     872        The node processing state. 
     873        """ 
    802874        return self.__processingState 
    803875 
     
    806878 
    807879    def setProgress(self, progress): 
    808         """Set the node work progress indicator. 
     880        """ 
     881        Set the node work progress state (number between 0 and 100). 
    809882        """ 
    810883        if progress is None or progress < 0: 
     
    818891 
    819892    def progress(self): 
     893        """ 
     894        Return the node work progress state. 
     895        """ 
    820896        return self.__progress 
    821897 
    822     progress_ = Property(float, fget=progress, fset=setProgress) 
     898    progress_ = Property(float, fget=progress, fset=setProgress, 
     899                         doc="Node progress state.") 
    823900 
    824901    def setProgressMessage(self, message): 
    825         """Set the node work progress message. 
     902        """ 
     903        Set the node work progress message. 
     904 
     905        .. note:: Not yet implemented 
     906 
    826907        """ 
    827908        pass 
     
    843924 
    844925    def newInputAnchor(self): 
    845         """Create and return a new input anchor point. 
     926        """ 
     927        Create and return a new input anchor point. 
    846928        """ 
    847929        if not (self.widget_description and self.widget_description.inputs): 
     
    858940 
    859941    def removeInputAnchor(self, anchor): 
    860         """Remove input anchor. 
     942        """ 
     943        Remove input anchor. 
    861944        """ 
    862945        self.inputAnchorItem.removeAnchor(anchor) 
     
    867950 
    868951    def newOutputAnchor(self): 
    869         """Create a new output anchor indicator. 
     952        """ 
     953        Create a new output anchor indicator. 
    870954        """ 
    871955        if not (self.widget_description and self.widget_description.outputs): 
     
    882966 
    883967    def removeOutputAnchor(self, anchor): 
    884         """Remove output anchor. 
     968        """ 
     969        Remove output anchor. 
    885970        """ 
    886971        self.outputAnchorItem.removeAnchor(anchor) 
     
    891976 
    892977    def inputAnchors(self): 
    893         """Return a list of input anchor points. 
     978        """ 
     979        Return a list of input anchor points. 
    894980        """ 
    895981        return self.inputAnchorItem.anchorPoints() 
    896982 
    897983    def outputAnchors(self): 
    898         """Return a list of output anchor points. 
     984        """ 
     985        Return a list of output anchor points. 
    899986        """ 
    900987        return self.outputAnchorItem.anchorPoints() 
    901988 
    902989    def setAnchorRotation(self, angle): 
    903         """Set the anchor rotation. 
     990        """ 
     991        Set the anchor rotation. 
    904992        """ 
    905993        self.inputAnchorItem.setRotation(angle) 
     
    908996 
    909997    def anchorRotation(self): 
    910         """Return the anchor rotation. 
     998        """ 
     999        Return the anchor rotation. 
    9111000        """ 
    9121001        return self.inputAnchorItem.rotation() 
     
    9191008 
    9201009    def shape(self): 
    921         """Reimplemented: Return the shape of the 'shapeItem', This is used 
    922         for hit testing in QGraphicsScene. 
    923  
    924         """ 
    925         # Should this return the union of all child items? 
     1010        # Shape for mouse hit detection. 
     1011        # TODO: Should this return the union of all child items? 
    9261012        return self.shapeItem.shape() 
    9271013 
    9281014    def __updateTitleText(self): 
    929         """Update the title text item. 
     1015        """ 
     1016        Update the title text item. 
    9301017        """ 
    9311018        title_safe = escape(self.title()) 
     
    9451032 
    9461033    def __updateMessages(self): 
    947         """Update message items (position, visibility and tool tips). 
     1034        """ 
     1035        Update message items (position, visibility and tool tips). 
    9481036        """ 
    9491037        items = [self.errorItem, self.warningItem, self.infoItem] 
     
    10171105 
    10181106def NodeItem_toolTipHelper(node, links_in=[], links_out=[]): 
    1019     """A helper function for constructing a standard tooltop for the node 
     1107    """ 
     1108    A helper function for constructing a standard tooltop for the node 
    10201109    in on the canvas. 
    10211110 
  • Orange/OrangeCanvas/canvas/scene.py

    r11343 r11369  
    11""" 
     2===================== 
    23Canvas Graphics Scene 
     4===================== 
    35 
    46""" 
     
    3335 
    3436class CanvasScene(QGraphicsScene): 
    35     """A Graphics Scene for displaying and editing an Orange Scheme. 
    3637    """ 
    37  
     38    A Graphics Scene for displaying and editing an :class:`Scheme`. 
     39    """ 
     40 
     41    #: An node item has been added to the scene. 
    3842    node_item_added = Signal(items.NodeItem) 
    39     """An node item has been added to the scene""" 
    40  
     43 
     44    #: An node item has been removed from the scene 
    4145    node_item_removed = Signal(items.LinkItem) 
    42     """An node item has been removed from the scene""" 
    43  
     46 
     47    #: A new link item has been added to the scene 
     48    link_item_added = Signal(items.LinkItem) 
     49 
     50    #: Link item has been removed 
     51    link_item_removed = Signal(items.LinkItem) 
     52 
     53    #: Annotation item has been added 
     54    annotation_added = Signal(items.annotationitem.Annotation) 
     55 
     56    #: Annotation item has been removed 
     57    annotation_removed = Signal(items.annotationitem.Annotation) 
     58 
     59    #: The position of a node has changed 
    4460    node_item_position_changed = Signal(items.NodeItem, QPointF) 
    45     """The position of a node has changed""" 
    46  
     61 
     62    #: An node item has been double clicked 
    4763    node_item_double_clicked = Signal(items.NodeItem) 
    48     """An node item has been double clicked""" 
    49  
     64 
     65    #: An node item has been activated (clicked) 
    5066    node_item_activated = Signal(items.NodeItem) 
    51     """An node item has been activated (clicked)""" 
    52  
     67 
     68    #: An node item has been hovered 
    5369    node_item_hovered = Signal(items.NodeItem) 
    54     """An node item has been hovered""" 
    55  
    56     link_item_added = Signal(items.LinkItem) 
    57     """A new link item has been added to the scene""" 
    58  
    59     link_item_removed = Signal(items.LinkItem) 
    60     """Link item has been removed""" 
    61  
     70 
     71    #: Link item has been hovered 
    6272    link_item_hovered = Signal(items.LinkItem) 
    63     """Link item has been hovered""" 
    64  
    65     annotation_added = Signal(items.annotationitem.Annotation) 
    66     """Annotation item has been added""" 
    67  
    68     annotation_removed = Signal(items.annotationitem.Annotation) 
    69     """Annotation item has been removed""" 
    7073 
    7174    def __init__(self, *args, **kwargs): 
  • Orange/OrangeCanvas/document/__init__.py

    r11149 r11371  
     1""" 
     2======== 
     3Document 
     4======== 
     5 
     6The ``document`` package implements and defines a :class:`SchemeEditWidget` 
     7 
     8""" 
     9 
     10__all__ = ["quickmenu", "schemeedit"] 
     11 
     12from .schemeedit import SchemeEditWidget 
  • Orange/OrangeCanvas/document/quickmenu.py

    r11229 r11371  
    11""" 
    2 Quick widget selector menu for the canvas. 
     2========== 
     3Quick Menu 
     4========== 
     5 
     6A :class:`QuickMenu` widget provides lists of actions organized in tabs 
     7with a quick search functionality. 
    38 
    49""" 
     10 
    511import sys 
    612import logging 
     
    3844 
    3945 
     46class MenuPage(ToolTree): 
     47    """ 
     48    A menu page in a :class:`QuickMenu` widget, showing a list of actions. 
     49    Shown actions can be disabled by setting a filtering function using the 
     50    :ref:`setFilterFunc`. 
     51 
     52    """ 
     53    def __init__(self, parent=None, title=None, icon=None, **kwargs): 
     54        ToolTree.__init__(self, parent, **kwargs) 
     55 
     56        if title is None: 
     57            title = "" 
     58 
     59        if icon is None: 
     60            icon = QIcon() 
     61 
     62        self.__title = title 
     63        self.__icon = icon 
     64 
     65        # Make sure the initial model is wrapped in a ItemDisableFilter. 
     66        self.setModel(self.model()) 
     67 
     68    def setTitle(self, title): 
     69        """ 
     70        Set the title of the page. 
     71        """ 
     72        if self.__title != title: 
     73            self.__title = title 
     74            self.update() 
     75 
     76    def title(self): 
     77        """ 
     78        Return the title of this page. 
     79        """ 
     80        return self.__title 
     81 
     82    title_ = Property(unicode, fget=title, fset=setTitle) 
     83 
     84    def setIcon(self, icon): 
     85        """ 
     86        Set icon for this menu page. 
     87        """ 
     88        if self.__icon != icon: 
     89            self.__icon = icon 
     90            self.update() 
     91 
     92    def icon(self): 
     93        """ 
     94        Return the icon of this manu page. 
     95        """ 
     96        return self.__icon 
     97 
     98    icon_ = Property(QIcon, fget=icon, fset=setIcon) 
     99 
     100    def setFilterFunc(self, func): 
     101        """ 
     102        Set the filtering function. `func` should a function taking a single 
     103        :class:`QModelIndex` argument and returning True if the item at index 
     104        should be disabled and False otherwise. To disable filtering `func` can 
     105        be set to ``None``. 
     106 
     107        """ 
     108        proxyModel = self.view().model() 
     109        proxyModel.setFilterFunc(func) 
     110 
     111    def setModel(self, model): 
     112        """ 
     113        Reimplemented from :ref:`ToolTree.setModel`. 
     114        """ 
     115        proxyModel = ItemDisableFilter(self) 
     116        proxyModel.setSourceModel(model) 
     117        ToolTree.setModel(self, proxyModel) 
     118 
     119    def setRootIndex(self, index): 
     120        """ 
     121        Reimplemented from :ref:`ToolTree.setRootIndex` 
     122        """ 
     123        proxyModel = self.view().model() 
     124        mappedIndex = proxyModel.mapFromSource(index) 
     125        ToolTree.setRootIndex(self, mappedIndex) 
     126 
     127    def rootIndex(self): 
     128        """ 
     129        Reimplemented from :ref:`ToolTree.rootIndex` 
     130        """ 
     131        proxyModel = self.view().model() 
     132        return proxyModel.mapToSource(ToolTree.rootIndex(self)) 
     133 
     134 
     135class ItemDisableFilter(QSortFilterProxyModel): 
     136    """ 
     137    An filter proxy model used to disable selected items based on 
     138    a filtering function. 
     139 
     140    """ 
     141    def __init__(self, parent=None): 
     142        QSortFilterProxyModel.__init__(self, parent) 
     143 
     144        self.__filterFunc = None 
     145 
     146    def setFilterFunc(self, func): 
     147        """ 
     148        Set the filtering function. 
     149        """ 
     150        if not (isinstance(func, Callable) or func is None): 
     151            raise ValueError("A callable object or None expected.") 
     152 
     153        if self.__filterFunc != func: 
     154            self.__filterFunc = func 
     155            # Mark the whole model as changed. 
     156            self.dataChanged.emit(self.index(0, 0), 
     157                                  self.index(self.rowCount(), 0)) 
     158 
     159    def flags(self, index): 
     160        """ 
     161        Reimplemented from :class:`QSortFilterProxyModel.flags` 
     162        """ 
     163        source = self.mapToSource(index) 
     164        flags = source.flags() 
     165 
     166        if self.__filterFunc is not None: 
     167            enabled = flags & Qt.ItemIsEnabled 
     168            if enabled and not self.__filterFunc(source): 
     169                flags ^= Qt.ItemIsEnabled 
     170 
     171        return flags 
     172 
     173 
     174class SuggestMenuPage(MenuPage): 
     175    """ 
     176    A MenuMage for the QuickMenu widget supporting item filtering 
     177    (searching). 
     178 
     179    """ 
     180    def __init__(self, *args, **kwargs): 
     181        MenuPage.__init__(self, *args, **kwargs) 
     182 
     183    def setModel(self, model): 
     184        """ 
     185        Reimplmemented from :ref:`MenuPage.setModel`. 
     186        """ 
     187        flat = FlattenedTreeItemModel(self) 
     188        flat.setSourceModel(model) 
     189        flat.setFlatteningMode(flat.InternalNodesDisabled) 
     190        flat.setFlatteningMode(flat.LeavesOnly) 
     191        proxy = SortFilterProxyModel(self) 
     192        proxy.setFilterCaseSensitivity(False) 
     193        proxy.setSourceModel(flat) 
     194        ToolTree.setModel(self, proxy) 
     195        self.ensureCurrent() 
     196 
     197    def setFilterFixedString(self, pattern): 
     198        """ 
     199        Set the fixed string filtering pattern. Only items which contain the 
     200        `pattern` string will be shown. 
     201 
     202        """ 
     203        proxy = self.view().model() 
     204        proxy.setFilterFixedString(pattern) 
     205        self.ensureCurrent() 
     206 
     207    def setFilterRegExp(self, pattern): 
     208        """ 
     209        Set the regular expression filtering pattern. Only items matching 
     210        the `pattern` expression will be shown. 
     211 
     212        """ 
     213        filter_proxy = self.view().model() 
     214        filter_proxy.setFilterRegExp(pattern) 
     215        self.ensureCurrent() 
     216 
     217    def setFilterWildCard(self, pattern): 
     218        """ 
     219        Set a wildcard filtering pattern. 
     220        """ 
     221        filter_proxy = self.view().model() 
     222        filter_proxy.setFilterWildCard(pattern) 
     223        self.ensureCurrent() 
     224 
     225    def setFilterFunc(self, func): 
     226        """ 
     227        Set a filtering function. 
     228        """ 
     229        filter_proxy = self.view().model() 
     230        filter_proxy.setFilterFunc(func) 
     231 
     232 
     233class SortFilterProxyModel(QSortFilterProxyModel): 
     234    """ 
     235    An filter proxy model used to filter items based on a filtering 
     236    function. 
     237 
     238    """ 
     239    def __init__(self, parent=None): 
     240        QSortFilterProxyModel.__init__(self, parent) 
     241 
     242        self.__filterFunc = None 
     243 
     244    def setFilterFunc(self, func): 
     245        """ 
     246        Set the filtering function. 
     247        """ 
     248        if not (isinstance(func, Callable) or func is None): 
     249            raise ValueError("A callable object or None expected.") 
     250 
     251        if self.__filterFunc is not func: 
     252            self.__filterFunc = func 
     253            self.invalidateFilter() 
     254 
     255    def filterFunc(self): 
     256        return self.__filterFunc 
     257 
     258    def filterAcceptsRow(self, row, parent=QModelIndex()): 
     259        accepted = QSortFilterProxyModel.filterAcceptsRow(self, row, parent) 
     260        if accepted and self.__filterFunc is not None: 
     261            model = self.sourceModel() 
     262            index = model.index(row, self.filterKeyColumn(), parent) 
     263            return self.__filterFunc(index) 
     264        else: 
     265            return accepted 
     266 
     267 
    40268class SearchWidget(LineEdit): 
    41269    def __init__(self, parent=None, **kwargs): 
     
    50278 
    51279class MenuStackWidget(QStackedWidget): 
    52     """Stack widget for the menu pages (ToolTree instances). 
     280    """ 
     281    Stack widget for the menu pages. 
    53282    """ 
    54283 
    55284    def sizeHint(self): 
    56         """Size hint is the median size hint of the widgets contained 
    57         within. 
     285        """ 
     286        Size hint is the maximum width and median height of the widgets 
     287        contained in the stack. 
    58288 
    59289        """ 
     
    132362 
    133363 
     364# TODO: ..application.canvastooldock.QuickCategoryToolbar is very similar, 
     365#       to TobBarWidget. Maybe common functionality could factored our. 
     366 
    134367class TabBarWidget(QWidget): 
    135     """A tab bar widget using tool buttons as tabs. 
    136  
     368    """ 
     369    A tab bar widget using tool buttons as tabs. 
    137370    """ 
    138371    # TODO: A uniform size box layout. 
     
    157390 
    158391    def count(self): 
    159         """Return the number of tabs in the widget. 
     392        """ 
     393        Return the number of tabs in the widget. 
    160394        """ 
    161395        return len(self.__tabs) 
    162396 
    163397    def addTab(self, text, icon=None, toolTip=None): 
    164         """Add a tab and return it's index. 
     398        """ 
     399        Add a new tab and return it's index. 
    165400        """ 
    166401        return self.insertTab(self.count(), text, icon, toolTip) 
    167402 
    168     def insertTab(self, index, text, icon, toolTip): 
    169         """Insert a tab at `index` 
     403    def insertTab(self, index, text, icon=None, toolTip=None): 
     404        """ 
     405        Insert a tab at `index` 
    170406        """ 
    171407        button = TabButton(self, objectName="tab-button") 
     
    185421 
    186422    def removeTab(self, index): 
     423        """ 
     424        Remove a tab at `index`. 
     425        """ 
    187426        if index >= 0 and index < self.count(): 
    188427            self.layout().takeItem(index) 
     
    198437 
    199438    def setTabIcon(self, index, icon): 
    200         """Set the `icon` for tab at `index`. 
     439        """ 
     440        Set the `icon` for tab at `index`. 
    201441        """ 
    202442        self.__tabs[index] = self.__tabs[index]._replace(icon=icon) 
     
    204444 
    205445    def setTabToolTip(self, index, toolTip): 
    206         """Set `toolTip` for tab at `index`. 
     446        """ 
     447        Set `toolTip` for tab at `index`. 
    207448        """ 
    208449        self.__tabs[index] = self.__tabs[index]._replace(toolTip=toolTip) 
     
    210451 
    211452    def setTabText(self, index, text): 
    212         """Set tab `text` for tab at `index` 
     453        """ 
     454        Set tab `text` for tab at `index` 
    213455        """ 
    214456        self.__tabs[index] = self.__tabs[index]._replace(text=text) 
     
    216458 
    217459    def setTabPalette(self, index, palette): 
    218         """Set the tab button palette. 
     460        """ 
     461        Set the tab button palette. 
    219462        """ 
    220463        self.__tabs[index] = self.__tabs[index]._replace(palette=palette) 
     
    222465 
    223466    def setCurrentIndex(self, index): 
     467        """ 
     468        Set the current tab index. 
     469        """ 
    224470        if self.__currentIndex != index: 
    225471            self.__currentIndex = index 
     
    230476            self.currentChanged.emit(index) 
    231477 
     478    def currentIndex(self): 
     479        """ 
     480        Return the current index. 
     481        """ 
     482        return self.__currentIndex 
     483 
    232484    def button(self, index): 
    233         """Return the `TabButton` instance for index. 
     485        """ 
     486        Return the `TabButton` instance for index. 
    234487        """ 
    235488        return self.__tabs[index].button 
    236489 
    237     def currentIndex(self): 
    238         """Return the current index. 
    239         """ 
    240         return self.__currentIndex 
    241  
    242490    def __updateTab(self, index): 
    243         """Update the tab button. 
     491        """ 
     492        Update the tab button. 
    244493        """ 
    245494        tab = self.__tabs[index] 
     
    266515 
    267516class PagedMenu(QWidget): 
    268     """Tabed container for `ToolTree` instances. 
     517    """ 
     518    Tabbed container for :class:`MenuPage` instances. 
    269519    """ 
    270520    triggered = Signal(QAction) 
     
    295545 
    296546    def addPage(self, page, title, icon=None, toolTip=None): 
    297         """Add a `page` to the menu and return its index. 
     547        """ 
     548        Add a `page` to the menu and return its index. 
    298549        """ 
    299550        return self.insertPage(self.count(), page, title, icon, toolTip) 
    300551 
    301552    def insertPage(self, index, page, title, icon=None, toolTip=None): 
    302         """Insert `page` at `index`. 
     553        """ 
     554        Insert `page` at `index`. 
    303555        """ 
    304556        page.triggered.connect(self.triggered) 
     
    310562 
    311563    def page(self, index): 
    312         """Return the page at index. 
     564        """ 
     565        Return the page at index. 
    313566        """ 
    314567        return self.__stack.widget(index) 
    315568 
    316569    def removePage(self, index): 
    317         """Remove the page at `index`. 
     570        """ 
     571        Remove the page at `index`. 
    318572        """ 
    319573        page = self.__stack.widget(index) 
     
    325579 
    326580    def count(self): 
    327         """Return the number of pages. 
     581        """ 
     582        Return the number of pages. 
    328583        """ 
    329584        return self.__stack.count() 
    330585 
    331586    def setCurrentIndex(self, index): 
    332         """Set the current page index. 
     587        """ 
     588        Set the current page index. 
    333589        """ 
    334590        if self.__currentIndex != index: 
     
    339595 
    340596    def currentIndex(self): 
    341         """Return the index of the current page. 
     597        """ 
     598        Return the index of the current page. 
    342599        """ 
    343600        return self.__currentIndex 
    344601 
    345602    def setCurrentPage(self, page): 
    346         """Set `page` to be the current shown page. 
     603        """ 
     604        Set `page` to be the current shown page. 
    347605        """ 
    348606        index = self.__stack.indexOf(page) 
     
    350608 
    351609    def currentPage(self): 
    352         """Return the current page. 
     610        """ 
     611        Return the current page. 
    353612        """ 
    354613        return self.__stack.currentWidget() 
    355614 
    356615    def indexOf(self, page): 
    357         """Return the index of `page`. 
     616        """ 
     617        Return the index of `page`. 
    358618        """ 
    359619        return self.__stack.indexOf(page) 
    360620 
    361621    def tabButton(self, index): 
    362         """Return the tab button instance for index. 
     622        """ 
     623        Return the tab button instance for index. 
    363624        """ 
    364625        return self.__tab.button(index) 
    365626 
    366627 
    367 class ItemDisableFilter(QSortFilterProxyModel): 
    368     def __init__(self, parent=None): 
    369         QSortFilterProxyModel.__init__(self, parent) 
    370  
    371         self.__filterFunc = None 
    372  
    373     def setFilterFunc(self, func): 
    374         if not (isinstance(func, Callable) or func is None): 
    375             raise ValueError("A callable object or None expected.") 
    376  
    377         if self.__filterFunc != func: 
    378             self.__filterFunc = func 
    379             # Mark the whole model as changed. 
    380             self.dataChanged.emit(self.index(0, 0), 
    381                                   self.index(self.rowCount(), 0)) 
    382  
    383     def flags(self, index): 
    384         source = self.mapToSource(index) 
    385         flags = source.flags() 
    386  
    387         if self.__filterFunc is not None: 
    388             enabled = flags & Qt.ItemIsEnabled 
    389             if enabled and not self.__filterFunc(source): 
    390                 flags ^= Qt.ItemIsEnabled 
    391  
    392         return flags 
    393  
    394  
    395 class MenuPage(ToolTree): 
    396     def __init__(self, *args, **kwargs): 
    397         ToolTree.__init__(self, *args, **kwargs) 
    398  
    399         # Make sure the initial model is wrapped in a ItemDisableFilter. 
    400         self.setModel(self.model()) 
    401  
    402     def setFilterFunc(self, func): 
    403         proxyModel = self.view().model() 
    404         proxyModel.setFilterFunc(func) 
    405  
    406     def setModel(self, model): 
    407         proxyModel = ItemDisableFilter(self) 
    408         proxyModel.setSourceModel(model) 
    409         ToolTree.setModel(self, proxyModel) 
    410  
    411     def setRootIndex(self, index): 
    412         proxyModel = self.view().model() 
    413         mappedIndex = proxyModel.mapFromSource(index) 
    414         ToolTree.setRootIndex(self, mappedIndex) 
    415  
    416     def rootIndex(self): 
    417         proxyModel = self.view().model() 
    418         return proxyModel.mapToSource(ToolTree.rootIndex(self)) 
    419  
    420  
    421 class SortFilterProxyModel(QSortFilterProxyModel): 
    422     def __init__(self, parent=None): 
    423         QSortFilterProxyModel.__init__(self, parent) 
    424  
    425         self.__filterFunc = None 
    426  
    427     def setFilterFunc(self, func): 
    428         if not (isinstance(func, Callable) or func is None): 
    429             raise ValueError("A callable object or None expected.") 
    430  
    431         if self.__filterFunc is not func: 
    432             self.__filterFunc = func 
    433             self.invalidateFilter() 
    434  
    435     def filterFunc(self): 
    436         return self.__filterFunc 
    437  
    438     def filterAcceptsRow(self, row, parent=QModelIndex()): 
    439         accepted = QSortFilterProxyModel.filterAcceptsRow(self, row, parent) 
    440         if accepted and self.__filterFunc is not None: 
    441             model = self.sourceModel() 
    442             index = model.index(row, self.filterKeyColumn(), parent) 
    443             return self.__filterFunc(index) 
    444         else: 
    445             return accepted 
    446  
    447  
    448 class SuggestMenuPage(ToolTree): 
    449     def __init__(self, *args, **kwargs): 
    450         ToolTree.__init__(self, *args, **kwargs) 
    451  
    452         # Make sure the initial model is wrapped in a FlattenedTreeItemModel. 
    453         self.setModel(self.model()) 
    454  
    455     def setModel(self, model): 
    456         flat = FlattenedTreeItemModel(self) 
    457         flat.setSourceModel(model) 
    458         flat.setFlatteningMode(flat.InternalNodesDisabled) 
    459         flat.setFlatteningMode(flat.LeavesOnly) 
    460         proxy = SortFilterProxyModel(self) 
    461         proxy.setFilterCaseSensitivity(False) 
    462         proxy.setSourceModel(flat) 
    463         ToolTree.setModel(self, proxy) 
    464         self.ensureCurrent() 
    465  
    466     def setFilterFixedString(self, pattern): 
    467         proxy = self.view().model() 
    468         proxy.setFilterFixedString(pattern) 
    469         self.ensureCurrent() 
    470  
    471     def setFilterRegExp(self, pattern): 
    472         filter_proxy = self.view().model() 
    473         filter_proxy.setFilterRegExp(pattern) 
    474         self.ensureCurrent() 
    475  
    476     def setFilterWildCard(self, pattern): 
    477         filter_proxy = self.view().model() 
    478         filter_proxy.setFilterWildCard(pattern) 
    479         self.ensureCurrent() 
    480  
    481     def setFilterFunc(self, func): 
    482         filter_proxy = self.view().model() 
    483         filter_proxy.setFilterFunc(func) 
    484  
    485  
    486628class QuickMenu(FramelessWindow): 
    487     """A quick menu popup for the widgets. 
    488  
    489     The widgets are set using setModel which must be a 
     629    """ 
     630    A quick menu popup for the widgets. 
     631 
     632    The widgets are set using :ref:`setModel` which must be a 
    490633    model as returned by QtWidgetRegistry.model() 
    491634 
     
    559702 
    560703    def setSizeGripEnabled(self, enabled): 
    561         """Enable the resizing of the menu with a size grip in a bottom 
     704        """ 
     705        Enable the resizing of the menu with a size grip in a bottom 
    562706        right corner (enabled by default). 
    563707 
     
    572716 
    573717    def sizeGripEnabled(self): 
    574         """Is the size grip enabled. 
     718        """ 
     719        Is the size grip enabled. 
    575720        """ 
    576721        return bool(self.__grip) 
    577722 
    578723    def addPage(self, name, page): 
    579         """Add the page and return it's index. 
     724        """ 
     725        Add the page and return it's index. 
    580726        """ 
    581727        icon = page.icon() 
     
    598744 
    599745    def createPage(self, index): 
     746        """ 
     747        Create a new page based on the contents of an index 
     748        (:class:`QModeIndex`) item. 
     749 
     750        """ 
    600751        page = MenuPage(self) 
    601752        view = page.view() 
     
    625776 
    626777    def setModel(self, model): 
     778        """ 
     779        Set the model containing the actions. 
     780        """ 
    627781        root = model.invisibleRootItem() 
    628782        for i in range(root.rowCount()): 
     
    641795                button.setStyleSheet( 
    642796                    "TabButton {\n" 
    643                     "    qproperty-flat_: false;" 
     797                    "    qproperty-flat_: false;\n" 
    644798                    "    background-color: %s;\n" 
    645799                    "    border: none;\n" 
     
    655809 
    656810    def setFilterFunc(self, func): 
     811        """ 
     812        Set a filter function. 
     813        """ 
    657814        if func != self.__filterFunc: 
    658815            self.__filterFunc = func 
     
    661818 
    662819    def popup(self, pos=None): 
    663         """Popup the menu at `pos` (in screen coordinates).. 
     820        """ 
     821        Popup the menu at `pos` (in screen coordinates). 
    664822        """ 
    665823        if pos is None: 
     
    729887 
    730888    def setCurrentPage(self, page): 
     889        """ 
     890        Set the current shown page to `page`. 
     891        """ 
    731892        self.__pages.setCurrentPage(page) 
    732893 
    733894    def setCurrentIndex(self, index): 
     895        """ 
     896        Set the current page index. 
     897        """ 
    734898        self.__pages.setCurrentIndex(index) 
    735899 
    736900    def __onTriggered(self, action): 
    737         """Re-emit the action from the page. 
     901        """ 
     902        Re-emit the action from the page. 
    738903        """ 
    739904        self.__triggeredAction = action 
     
    748913 
    749914    def triggerSearch(self): 
     915        """ 
     916        Trigger action search. This changes to current page to the 
     917        'Suggest' page and sets the keyboard focus to the search line edit. 
     918 
     919        """ 
    750920        self.__pages.setCurrentPage(self.__suggestPage) 
    751921        self.__search.setFocus(Qt.ShortcutFocusReason) 
     
    823993 
    824994    def moveCurrent(self, rows, columns=0): 
    825         """Move the current index by rows, columns. 
     995        """ 
     996        Move the current index by rows, columns. 
    826997        """ 
    827998        if self.__view is not None: 
     
    8441015 
    8451016    def activateCurrent(self): 
    846         """Activate the current index. 
     1017        """ 
     1018        Activate the current index. 
    8471019        """ 
    8481020        if self.__view is not None: 
     
    8531025 
    8541026    def ensureCurrent(self): 
    855         """Ensure the view has a current item if one is available. 
     1027        """ 
     1028        Ensure the view has a current item if one is available. 
    8561029        """ 
    8571030        if self.__view is not None: 
     
    8671040 
    8681041class WindowSizeGrip(QSizeGrip): 
    869     """Automatically positioning SizeGrip. 
     1042    """ 
     1043    Automatically positioning :class:`QSizeGrip`. 
    8701044    """ 
    8711045    def __init__(self, parent): 
     
    8781052 
    8791053    def setCorner(self, corner): 
    880         """Set the corner where the size grip should position itself. 
     1054        """ 
     1055        Set the corner where the size grip should position itself. 
    8811056        """ 
    8821057        if corner not in [Qt.TopLeftCorner, Qt.TopRightCorner, 
     
    8891064 
    8901065    def corner(self): 
    891         """Return the corner where the size grip is positioned. 
     1066        """ 
     1067        Return the corner where the size grip is positioned. 
    8921068        """ 
    8931069        return self.__corner 
  • Orange/OrangeCanvas/document/schemeedit.py

    r11343 r11373  
    6969 
    7070class SchemeEditWidget(QWidget): 
     71    """ 
     72    An editor for a :class:`Scheme` instance. 
     73 
     74    """ 
     75    #: Undo command has become available/unavailable. 
    7176    undoAvailable = Signal(bool) 
     77 
     78    #: Redo command has become available/unavailable. 
    7279    redoAvailable = Signal(bool) 
     80 
     81    #: Document modified state has changed. 
    7382    modificationChanged = Signal(bool) 
     83 
     84    #: Undo command was added to the undo stack. 
    7485    undoCommandAdded = Signal() 
     86 
     87    #: Item selection has changed. 
    7588    selectionChanged = Signal() 
    7689 
     90    #: Document title has changed. 
    7791    titleChanged = Signal(unicode) 
    7892 
     93    #: Document path has changed. 
    7994    pathChanged = Signal(unicode) 
    8095 
     
    148163                    shortcut=QKeySequence.ZoomIn, 
    149164                    toolTip=self.tr("Zoom in the scheme."), 
    150                     toggled=self.toogleZoom, 
     165                    toggled=self.toggleZoom, 
    151166                    ) 
    152167 
     
    351366 
    352367    def toolbarActions(self): 
    353         """Return a list of actions that can be inserted into a toolbar. 
     368        """ 
     369        Return a list of actions that can be inserted into a toolbar. 
    354370        """ 
    355371        return [self.__zoomAction, 
     
    359375 
    360376    def menuBarActions(self): 
    361         """Return a list of actions that can be inserted into a QMenuBar. 
    362         These actions should have a menu. 
     377        """ 
     378        Return a list of actions that can be inserted into a QMenuBar. 
     379        These actions should have a menu (i.e. a 'File' action should 
     380        have a menu with "New", "Open", ...) 
    363381 
    364382        """ 
     
    366384 
    367385    def isModified(self): 
    368         """Is the document modified. 
     386        """ 
     387        Is the document is a modified state. 
    369388        """ 
    370389        return self.__modified or not self.__undoStack.isClean() 
    371390 
    372391    def setModified(self, modified): 
     392        """ 
     393        Set the document modified state. 
     394        """ 
    373395        if self.__modified != modified: 
    374396            self.__modified = modified 
     
    383405 
    384406    def isModifiedStrict(self): 
    385         """Is the document modified. Run a strict check against all node 
     407        """ 
     408        Is the document modified. Run a strict check against all node 
    386409        properties as they were at the time when the last call to 
    387410        `setModified(True)` was made. 
     
    400423 
    401424    def setQuickMenuTriggers(self, triggers): 
    402         """Set quick menu triggers. 
     425        """ 
     426        Set quick menu trigger flags. 
    403427        """ 
    404428        if self.__quickMenuTriggers != triggers: 
     
    406430 
    407431    def quickMenuTriggres(self): 
     432        """ 
     433        Return quick menu trigger flags. 
     434        """ 
    408435        return self.__quickMenuTriggers 
    409436 
    410437    def setChannelNamesVisible(self, visible): 
    411         """Set channel names visibility state. When enabled the links 
    412         in the view will have a visible source/sink channel names 
    413         displayed over them. 
     438        """ 
     439        Set channel names visibility state. When enabled the links 
     440        in the view will have a source/sink channel names displayed over 
     441        them. 
    414442 
    415443        """ 
     
    419447 
    420448    def channelNamesVisible(self): 
    421         """Return the channel name visibility state. 
     449        """ 
     450        Return the channel name visibility state. 
    422451        """ 
    423452        return self.__channelNamesVisible 
    424453 
    425454    def undoStack(self): 
    426         """Return the undo stack. 
     455        """ 
     456        Return the undo stack. 
    427457        """ 
    428458        return self.__undoStack 
    429459 
    430460    def setPath(self, path): 
    431         """Set the path associated with the current scheme. 
     461        """ 
     462        Set the path associated with the current scheme. 
    432463 
    433464        .. note:: Calling `setScheme` will invalidate the path (i.e. set it 
     
    440471 
    441472    def path(self): 
    442         """Return the path associated with the scene 
     473        """ 
     474        Return the path associated with the scheme 
    443475        """ 
    444476        return self.__path 
    445477 
    446478    def setScheme(self, scheme): 
     479        """ 
     480        Set the :class:`Scheme` instance to display/edit. 
     481 
     482        """ 
    447483        if self.__scheme is not scheme: 
    448484            if self.__scheme: 
     
    533569 
    534570    def scheme(self): 
    535         """Return the :class:`Scheme` edited by the widget. 
     571        """ 
     572        Return the :class:`Scheme` edited by the widget. 
    536573        """ 
    537574        return self.__scheme 
    538575 
    539576    def scene(self): 
    540         """Return the QGraphicsScene instance used to display the scheme. 
     577        """ 
     578        Return the :class:`QGraphicsScene` instance used to display the 
     579        current scheme. 
     580 
    541581        """ 
    542582        return self.__scene 
    543583 
    544584    def view(self): 
    545         """Return the QGraphicsView instance used to display the scene. 
     585        """ 
     586        Return the class:`QGraphicsView` instance used to display the 
     587        current scene. 
     588 
    546589        """ 
    547590        return self.__view 
    548591 
    549592    def setRegistry(self, registry): 
    550         # Is this method necessary 
     593        # Is this method necessary? 
     594        # It should be removed when the scene (items) is fixed 
     595        # so all information regarding the visual appearance is 
     596        # included in the node/widget description. 
    551597        self.__registry = registry 
    552598        if self.__scene: 
     
    555601 
    556602    def quickMenu(self): 
    557         """Return a quick menu instance for quick new node creation. 
     603        """ 
     604        Return a quick menu instance for quick new node creation. 
    558605        """ 
    559606        if self.__quickMenu is None: 
     
    589636    def createNewNode(self, description, title=None, position=None): 
    590637        """ 
    591         Create a new `SchemeNode` and add it to the document. The new 
    592         node is constructed using `newNodeHelper` method. 
     638        Create a new :class:`SchemeNode` and add it to the document. The new 
     639        node is constructed using :ref:`newNodeHelper` method. 
    593640 
    594641        """ 
     
    600647    def newNodeHelper(self, description, title=None, position=None): 
    601648        """ 
    602         Return a new initialized `SchemeNode`. If title and position are 
    603         not supplied they are initialized to a sensible defaults. 
     649        Return a new initialized :class:`SchemeNode`. If `title` and 
     650        `position` are not supplied they are initialized to sensible 
     651        defaults. 
    604652 
    605653        """ 
     
    614662    def enumerateTitle(self, title): 
    615663        """ 
    616         Enumerate a title string (i.e. add a number in parentheses) so it is 
    617         not equal to any node title in the current scheme. 
     664        Enumerate a `title` string (i.e. add a number in parentheses) so 
     665        it is not equal to any node title in the current scheme. 
    618666 
    619667        """ 
     
    642690 
    643691    def removeNode(self, node): 
    644         """Remove a `node` (:class:`SchemeNode`) from the scheme 
     692        """ 
     693        Remove a `node` (:class:`SchemeNode`) from the scheme 
    645694        """ 
    646695        command = commands.RemoveNodeCommand(self.__scheme, node) 
     
    648697 
    649698    def renameNode(self, node, title): 
    650         """Rename a `node` (:class:`SchemeNode`) to `title`. 
     699        """ 
     700        Rename a `node` (:class:`SchemeNode`) to `title`. 
    651701        """ 
    652702        command = commands.RenameNodeCommand(self.__scheme, node, title) 
     
    654704 
    655705    def addLink(self, link): 
    656         """Add a `link` (:class:`SchemeLink`) to the scheme. 
     706        """ 
     707        Add a `link` (:class:`SchemeLink`) to the scheme. 
    657708        """ 
    658709        command = commands.AddLinkCommand(self.__scheme, link) 
     
    660711 
    661712    def removeLink(self, link): 
    662         """Remove a link (:class:`SchemeLink`) from the scheme. 
     713        """ 
     714        Remove a link (:class:`SchemeLink`) from the scheme. 
    663715        """ 
    664716        command = commands.RemoveLinkCommand(self.__scheme, link) 
     
    666718 
    667719    def addAnnotation(self, annotation): 
    668         """Add `annotation` (:class:`BaseSchemeAnnotation`) to the scheme 
     720        """ 
     721        Add `annotation` (:class:`BaseSchemeAnnotation`) to the scheme 
    669722        """ 
    670723        command = commands.AddAnnotationCommand(self.__scheme, annotation) 
     
    672725 
    673726    def removeAnnotation(self, annotation): 
    674         """Remove `annotation` (:class:`BaseSchemeAnnotation`) from the scheme. 
     727        """ 
     728        Remove `annotation` (:class:`BaseSchemeAnnotation`) from the scheme. 
    675729        """ 
    676730        command = commands.RemoveAnnotationCommand(self.__scheme, annotation) 
     
    678732 
    679733    def removeSelected(self): 
    680         """Remove all selected items in the scheme. 
     734        """ 
     735        Remove all selected items in the scheme. 
    681736        """ 
    682737        selected = self.scene().selectedItems() 
     
    699754 
    700755    def selectAll(self): 
    701         """Select all selectable items in the scheme. 
     756        """ 
     757        Select all selectable items in the scheme. 
    702758        """ 
    703759        for item in self.__scene.items(): 
     
    705761                item.setSelected(True) 
    706762 
    707     def toogleZoom(self, zoom): 
     763    def toggleZoom(self, zoom): 
     764        """ 
     765        Toggle view zoom. If `zoom` is True the scheme is displayed 
     766        scaled to 150%. 
     767 
     768        """ 
    708769        view = self.view() 
    709770        if zoom: 
     
    713774 
    714775    def alignToGrid(self): 
    715         """Align nodes to a grid. 
    716         """ 
     776        """ 
     777        Align nodes to a grid. 
     778        """ 
     779        # TODO: The the current layout implementation is BAD (fix is urgent). 
    717780        tile_size = 150 
    718781        tiles = {} 
     
    741804 
    742805    def focusNode(self): 
    743         """Return the current focused `SchemeNode` or None if no 
     806        """ 
     807        Return the current focused :class:`SchemeNode` or ``None`` if no 
    744808        node has focus. 
    745809 
     
    757821 
    758822    def selectedNodes(self): 
    759         """Return all selected `SchemeNode` items. 
     823        """ 
     824        Return all selected :class:`SchemeNode` items. 
    760825        """ 
    761826        return map(self.scene().node_for_item, 
     
    763828 
    764829    def selectedAnnotations(self): 
    765         """Return all selected `SchemeAnnotation` items. 
     830        """ 
     831        Return all selected :class:`SchemeAnnotation` items. 
    766832        """ 
    767833        return map(self.scene().annotation_for_item, 
     
    769835 
    770836    def openSelected(self): 
    771         """Open (show and raise) all widgets for selected nodes. 
     837        """ 
     838        Open (show and raise) all widgets for the current selected nodes. 
    772839        """ 
    773840        selected = self.scene().selected_node_items() 
     
    776843 
    777844    def editNodeTitle(self, node): 
    778         """Edit the `node`'s title. 
     845        """ 
     846        Edit (rename) the `node`'s title. Opens an input dialog. 
    779847        """ 
    780848        name, ok = QInputDialog.getText( 
     
    10351103 
    10361104    def _setUserInteractionHandler(self, handler): 
    1037         """Helper method for setting the user interaction handlers. 
     1105        """ 
     1106        Helper method for setting the user interaction handlers. 
    10381107        """ 
    10391108        if self.__scene.user_interaction_handler: 
     
    11881257 
    11891258    def __onItemFocusedIn(self, item): 
    1190         """Annotation item has gained focus. 
     1259        """ 
     1260        Annotation item has gained focus. 
    11911261        """ 
    11921262        if not self.__scene.user_interaction_handler: 
     
    11941264 
    11951265    def __onItemFocusedOut(self, item): 
    1196         """Annotation item lost focus. 
     1266        """ 
     1267        Annotation item lost focus. 
    11971268        """ 
    11981269        self.__endControlPointEdit() 
    11991270 
    12001271    def __onEditingFinished(self, item): 
    1201         """Text annotation editing has finished. 
     1272        """ 
     1273        Text annotation editing has finished. 
    12021274        """ 
    12031275        annot = self.__scene.annotation_for_item(item) 
     
    12111283    def __toggleNewArrowAnnotation(self, checked): 
    12121284        if self.__newTextAnnotationAction.isChecked(): 
     1285            # Uncheck the text annotation action if needed. 
    12131286            self.__newTextAnnotationAction.setChecked(not checked) 
    12141287 
     
    12161289 
    12171290        if not checked: 
     1291            # The action was unchecked (canceled by the user) 
    12181292            handler = self.__scene.user_interaction_handler 
    12191293            if isinstance(handler, interactions.NewArrowAnnotation): 
     
    12341308    def __onFontSizeTriggered(self, action): 
    12351309        if not self.__newTextAnnotationAction.isChecked(): 
    1236             # Trigger the action 
     1310            # When selecting from the (font size) menu the 'Text' 
     1311            # action does not get triggered automatically. 
    12371312            self.__newTextAnnotationAction.trigger() 
    12381313        else: 
    1239             # just update the preferred font on the interaction handler 
     1314            # Update the preferred font on the interaction handler. 
    12401315            handler = self.__scene.user_interaction_handler 
    12411316            if isinstance(handler, interactions.NewTextAnnotation): 
     
    12441319    def __toggleNewTextAnnotation(self, checked): 
    12451320        if self.__newArrowAnnotationAction.isChecked(): 
     1321            # Uncheck the arrow annotation if needed. 
    12461322            self.__newArrowAnnotationAction.setChecked(not checked) 
    12471323 
     
    12491325 
    12501326        if not checked: 
     1327            # The action was unchecked (canceled by the user) 
    12511328            handler = self.__scene.user_interaction_handler 
    12521329            if isinstance(handler, interactions.NewTextAnnotation): 
     
    12671344    def __onArrowColorTriggered(self, action): 
    12681345        if not self.__newArrowAnnotationAction.isChecked(): 
    1269             # Trigger the action 
     1346            # When selecting from the (color) menu the 'Arrow' 
     1347            # action does not get triggered automatically. 
    12701348            self.__newArrowAnnotationAction.trigger() 
    12711349        else: 
    1272             # just update the preferred color on the interaction handler 
     1350            # Update the preferred color on the interaction handler 
    12731351            handler = self.__scene.user_interaction_handler 
    12741352            if isinstance(handler, interactions.NewArrowAnnotation): 
     
    12941372 
    12951373    def __onRenameAction(self): 
     1374        """ 
     1375        Rename was requested for the selected widget. 
     1376        """ 
    12961377        selected = self.selectedNodes() 
    12971378        if len(selected) == 1: 
     
    12991380 
    13001381    def __onHelpAction(self): 
    1301         """Help was requested for the selected widget. 
     1382        """ 
     1383        Help was requested for the selected widget. 
    13021384        """ 
    13031385        nodes = self.selectedNodes() 
     
    13251407 
    13261408    def __toggleLinkEnabled(self, enabled): 
    1327         """Link enabled state was toggled in the context menu. 
     1409        """ 
     1410        Link 'enabled' state was toggled in the context menu. 
    13281411        """ 
    13291412        if self.__contextMenuTarget: 
     
    13351418 
    13361419    def __linkRemove(self): 
    1337         """Remove link was requested from the context menu. 
     1420        """ 
     1421        Remove link was requested from the context menu. 
    13381422        """ 
    13391423        if self.__contextMenuTarget: 
     
    13411425 
    13421426    def __linkReset(self): 
    1343         """Link reset from the context menu was requested. 
     1427        """ 
     1428        Link reset from the context menu was requested. 
    13441429        """ 
    13451430        if self.__contextMenuTarget: 
     
    13511436 
    13521437    def __startControlPointEdit(self, item): 
    1353         """Start a control point edit interaction for item. 
     1438        """ 
     1439        Start a control point edit interaction for `item`. 
    13541440        """ 
    13551441        if isinstance(item, items.ArrowAnnotation): 
     
    13671453 
    13681454    def __endControlPointEdit(self): 
    1369         """End the current control point edit interaction. 
     1455        """ 
     1456        End the current control point edit interaction. 
    13701457        """ 
    13711458        handler = self.__scene.user_interaction_handler 
     
    13791466 
    13801467    def __updateFont(self): 
     1468        """ 
     1469        Update the font for the "Text size' menu and the default font 
     1470        used in the `CanvasScene`. 
     1471 
     1472        """ 
    13811473        actions = self.__fontActionGroup.actions() 
    13821474        font = self.font() 
     
    14031495 
    14041496def mouse_drag_distance(event, button=Qt.LeftButton): 
    1405     """Return the (manhattan) distance between the (screen position) 
     1497    """ 
     1498    Return the (manhattan) distance between the mouse position 
    14061499    when the `button` was pressed and the current mouse position. 
    14071500 
     
    14121505 
    14131506def set_enabled_all(objects, enable): 
    1414     """Set enabled properties on all objects (QObjects with setEnabled). 
     1507    """ 
     1508    Set `enabled` properties on all objects (objects with `setEnabled` method). 
    14151509    """ 
    14161510    for obj in objects: 
  • Orange/OrangeCanvas/document/tests/test_quickmenu.py

    r11333 r11370  
    33 
    44from ..quickmenu import QuickMenu, SuggestMenuPage, FlattenedTreeItemModel, \ 
    5                         ToolTree, QAction 
     5                        MenuPage, QAction 
    66 
    77from ...gui.test import QAppTestCase 
     
    2323        menu.hovered.connect(hovered) 
    2424 
    25         items_page = ToolTree() 
     25        items_page = MenuPage() 
    2626        model = QStringListModel(["one", "two", "file not found"]) 
    2727        items_page.setModel(model) 
    2828        menu.addPage("w", items_page) 
    2929 
    30         page_c = ToolTree() 
     30        page_c = MenuPage() 
    3131        menu.addPage("c", page_c) 
    3232 
     
    7171        menu.setFilterFixedString("la") 
    7272        self.singleShot(2500, lambda: menu.setFilterFixedString("ba")) 
     73        self.singleShot(5000, lambda: menu.setFilterFixedString("ab")) 
    7374        self.app.exec_() 
    7475 
  • Orange/OrangeCanvas/gui/dock.py

    r11232 r11366  
    44======================= 
    55 
    6 A dock widget with a header that can be a collapsed/expanded. 
     6A dock widget that can be a collapsed/expanded. 
    77 
    88""" 
     
    1414) 
    1515 
    16 from PyQt4.QtCore import Qt, QTimer, QEvent 
     16from PyQt4.QtCore import Qt, QEvent 
    1717 
    1818from PyQt4.QtCore import pyqtProperty as Property 
     
    2525 
    2626class CollapsibleDockWidget(QDockWidget): 
    27     """A Dock widget for which the close action collapses the widget 
    28     to a smaller size. 
     27    """ 
     28    This :class:`QDockWidget` subclass overrides the `close` header 
     29    button to instead collapse to a smaller size. The contents contents 
     30    to show when in each state can be set using the ``setExpandedWidget`` 
     31    and ``setCollapsedWidget``. 
     32 
     33    .. note:: Do use the base class ``QDockWidget.setWidget`` method to set 
     34              the contents. 
    2935 
    3036    """ 
     
    7985 
    8086    def setExpanded(self, state): 
    81         """Set the expanded state. 
     87        """ 
     88        Set the widgets `expanded` state. 
    8289        """ 
    8390        if self.__expanded != state: 
     
    9299 
    93100    def expanded(self): 
    94         """Is the dock widget in expanded state 
     101        """ 
     102        Is the dock widget in expanded state. When `True` the 
     103        ``expandedWidget`` will be shown, and ``collapsedWidget`` otherwise. 
     104 
    95105        """ 
    96106        return self.__expanded 
     
    100110    def setWidget(self, w): 
    101111        raise NotImplementedError( 
    102                 "Please use the setExpandedWidget/setCollapsedWidget method." 
     112                "Please use the 'setExpandedWidget'/'setCollapsedWidget' " 
     113                "methods to set the contents of the dock widget." 
    103114              ) 
    104115 
    105116    def setExpandedWidget(self, widget): 
    106         """Set the widget with contents to show while expanded. 
     117        """ 
     118        Set the widget with contents to show while expanded. 
    107119        """ 
    108120        if widget is self.__expandedWidget: 
     
    119131            self.updateGeometry() 
    120132 
     133    def expandedWidet(self): 
     134        """ 
     135        Return the widget previously set with ``setExpandedWidget``, 
     136        or ``None`` if no widget has been set. 
     137 
     138        """ 
     139        return self.__expandedWidget 
     140 
    121141    def setCollapsedWidget(self, widget): 
    122         """Set the widget with contents to show while collapsed. 
     142        """ 
     143        Set the widget with contents to show while collapsed. 
    123144        """ 
    124145        if widget is self.__collapsedWidget: 
     
    135156            self.updateGeometry() 
    136157 
     158    def collapsedWidget(self): 
     159        """ 
     160        Return the widget previously set with ``setCollapsedWidget``, 
     161        or ``None`` if no widget has been set. 
     162 
     163        """ 
     164        return self.__collapsedWidget 
     165 
    137166    def setAnimationEnabled(self, animationEnabled): 
    138         """Enable/disable the transition animation. 
     167        """ 
     168        Enable/disable the transition animation. 
    139169        """ 
    140170        self.__stack.setAnimationEnabled(animationEnabled) 
    141171 
    142172    def animationEnabled(self): 
     173        """ 
     174        Is transition animation enabled. 
     175        """ 
    143176        return self.__stack.animationEnabled() 
    144177 
    145178    def currentWidget(self): 
    146         """Return the current widget. 
     179        """ 
     180        Return the current shown widget depending on the `expanded` state. 
    147181        """ 
    148182        if self.__expanded: 
     
    152186 
    153187    def expand(self): 
    154         """Expand the dock (same as `setExpanded(True)`) 
     188        """ 
     189        Expand the dock (same as ``setExpanded(True)``) 
    155190        """ 
    156191        self.setExpanded(True) 
    157192 
    158193    def collapse(self): 
    159         """Collapse the dock (same as `setExpanded(False)`) 
     194        """ 
     195        Collapse the dock (same as ``setExpanded(False)``) 
    160196        """ 
    161197        self.setExpanded(False) 
  • Orange/OrangeCanvas/gui/dropshadow.py

    r11130 r11366  
    11""" 
    2 A DropShadowWidget 
     2================= 
     3Drop Shadow Frame 
     4================= 
     5 
     6A widget providing a drop shadow (gaussian blur effect) around another 
     7widget. 
    38 
    49""" 
     
    4247 
    4348class DropShadowFrame(QWidget): 
    44     """A widget drawing a drop shadow effect around the geometry of 
    45     another widget (similar to QFocusFrame). 
     49    """ 
     50    A widget drawing a drop shadow effect around the geometry of 
     51    another widget (works similar to :class:`QFocusFrame`). 
     52 
     53    Parameters 
     54    ---------- 
     55    parent : :class:`QObject` 
     56        Parent object. 
     57    color : :class:`QColor` 
     58        The color of the drop shadow. 
     59    radius : float 
     60        Shadow radius. 
    4661 
    4762    """ 
     
    6479 
    6580    def setColor(self, color): 
    66         """Set the color of the shadow. 
     81        """ 
     82        Set the color of the shadow. 
    6783        """ 
    6884        if not isinstance(color, QColor): 
     
    7086 
    7187        if self.__color != color: 
    72             self.__color = color 
     88            self.__color = QColor(color) 
    7389            self.__updatePixmap() 
    7490 
    7591    def color(self): 
    76         return self.__color 
    77  
    78     color_ = Property(QColor, fget=color, fset=setColor, designable=True) 
     92        """ 
     93        Return the color of the drop shadow. 
     94        """ 
     95        return QColor(self.__color) 
     96 
     97    color_ = Property(QColor, fget=color, fset=setColor, designable=True, 
     98                      doc="Drop shadow color") 
    7999 
    80100    def setRadius(self, radius): 
    81         """Set the drop shadow blur radius. 
     101        """ 
     102        Set the drop shadow's blur radius. 
    82103        """ 
    83104        if self.__radius != radius: 
     
    87108 
    88109    def radius(self): 
     110        """ 
     111        Return the shadow blur radius. 
     112        """ 
    89113        return self.__radius 
    90114 
    91     radius_ = Property(int, fget=radius, fset=setRadius, designable=True) 
     115    radius_ = Property(int, fget=radius, fset=setRadius, designable=True, 
     116                       doc="Drop shadow blur radius.") 
    92117 
    93118    def setWidget(self, widget): 
    94         """Set the widget to show the shadow around. 
     119        """ 
     120        Set the widget around which to show the shadow. 
    95121        """ 
    96122        if self.__widget: 
     
    119145 
    120146    def widget(self): 
    121         """Return the widget taht was set by `setWidget`. 
     147        """ 
     148        Return the widget that was set by `setWidget`. 
    122149        """ 
    123150        return self.__widget 
     
    160187 
    161188    def __updateGeometry(self): 
    162         """Update the shadow geometry to fit the widget's changed 
     189        """ 
     190        Update the shadow geometry to fit the widget's changed 
    163191        geometry. 
     192 
    164193        """ 
    165194        widget = self.__widget 
     
    185214 
    186215    def __updatePixmap(self): 
    187         """Update the cached shadow pixmap. 
     216        """ 
     217        Update the cached shadow pixmap. 
    188218        """ 
    189219        rect_size = QSize(50, 50) 
     
    211241 
    212242    def __shadowPixmapFragments(self, pixmap_rect, shadow_rect): 
    213         """Return a list of 8 QRectF fragments for drawing a shadow. 
     243        """ 
     244        Return a list of 8 QRectF fragments for drawing a shadow. 
    214245        """ 
    215246        s_left, s_top, s_right, s_bottom = \ 
  • Orange/OrangeCanvas/gui/framelesswindow.py

    r11170 r11366  
    11""" 
    2 A Frameless window widget 
     2A frameless window widget 
    33 
    44""" 
     
    1212 
    1313class FramelessWindow(QWidget): 
    14     """A Basic frameless window widget with rounded corners (if supported by 
     14    """ 
     15    A basic frameless window widget with rounded corners (if supported by 
    1516    the windowing system). 
    1617 
     
    2627 
    2728    def setRadius(self, radius): 
    28         """Set the window rounded border radius. 
     29        """ 
     30        Set the window rounded border radius. 
    2931        """ 
    3032        if self.__radius != radius: 
     
    3537 
    3638    def radius(self): 
    37         """Return the border radius. 
     39        """ 
     40        Return the border radius. 
    3841        """ 
    3942        return self.__radius 
    4043 
    4144    radius_ = Property(int, fget=radius, fset=setRadius, 
    42                        designable=True) 
     45                       designable=True, 
     46                       doc="Window border radius") 
    4347 
    4448    def resizeEvent(self, event): 
  • Orange/OrangeCanvas/gui/lineedit.py

    r11105 r11366  
    2424 
    2525class LineEditButton(QToolButton): 
     26    """ 
     27    A button in the :class:`LineEdit`. 
     28    """ 
    2629    def __init__(self, parent=None, flat=True, **kwargs): 
    2730        QToolButton.__init__(self, parent, **kwargs) 
     
    5154 
    5255class LineEdit(QLineEdit): 
    53     """A line edit widget with support for adding actions (buttons) to 
     56    """ 
     57    A line edit widget with support for adding actions (buttons) to 
    5458    the left/right of the edited text 
    5559 
    5660    """ 
     61    #: Position flags 
    5762    LeftPosition, RightPosition = 1, 2 
    5863 
     64    #: Emitted when the action is triggered. 
    5965    triggered = Signal(QAction) 
     66 
     67    #: The left action was triggered. 
    6068    leftTriggered = Signal() 
     69 
     70    #: The right action was triggered. 
    6171    rightTriggered = Signal() 
    6272 
     
    6676 
    6777    def setAction(self, action, position=LeftPosition): 
    68         """Set `action` to be displayed at `position`. Existing action 
    69         if present will be removed. 
     78        """ 
     79        Set `action` to be displayed at `position`. Existing action 
     80        (if present) will be removed. 
     81 
     82        Parameters 
     83        ---------- 
     84        action : :class:`QAction` 
     85        position : int 
     86            Position where to set the action (default: ``LeftPosition``). 
    7087 
    7188        """ 
     
    93110 
    94111    def actionAt(self, position): 
    95         """Return `action` at `position`. 
     112        """ 
     113        Return :class:`QAction` at `position`. 
    96114        """ 
    97115        self._checkPosition(position) 
     
    103121 
    104122    def removeActionAt(self, position): 
    105         """Remove action at position. 
     123        """ 
     124        Remove the action at position. 
    106125        """ 
    107126        self._checkPosition(position) 
     
    116135 
    117136    def button(self, position): 
    118         """Return the actions button at position. 
     137        """ 
     138        Return the button (:class:`LineEditButton`) for the action 
     139        at `position`. 
     140 
    119141        """ 
    120142        self._checkPosition(position) 
  • Orange/OrangeCanvas/gui/quickhelp.py

    r11264 r11366  
    77 
    88class QuickHelp(QTextBrowser): 
     9 
     10    #: Emitted when the shown text changes. 
    911    textChanged = Signal() 
    1012 
     
    2325 
    2426    def showHelp(self, text, timeout=0): 
    25         """Show help for `timeout` milliseconds. if timeout is 0 then 
     27        """ 
     28        Show help for `timeout` milliseconds. if timeout is 0 then 
    2629        show the text until it is cleared with clearHelp or showHelp is 
    2730        called with an empty string. 
     
    3740 
    3841    def clearHelp(self): 
    39         """Clear help text previously set with `showHelp`. 
     42        """ 
     43        Clear help text previously set with `showHelp`. 
    4044        """ 
    4145        self.__timer.stop() 
     
    4347 
    4448    def showPermanentHelp(self, text): 
    45         """Set permanent help text. The text may be temporarily 
    46         overridden by showHelp but will be shown again when that is cleared 
     49        """ 
     50        Set permanent help text. The text may be temporarily overridden 
     51        by showHelp but will be shown again when that is cleared. 
    4752 
    4853        """ 
     
    5358 
    5459    def currentText(self): 
    55         """Return the current shown text. 
     60        """ 
     61        Return the current shown text. 
    5662        """ 
    5763        return self.__text or self.__permanentText 
     
    103109 
    104110class StatusTipPromoter(QObject): 
    105     """Promotes `QStatusTipEvent` to `QuickHelpTipEvent` using whatsThis 
     111    """ 
     112    Promotes `QStatusTipEvent` to `QuickHelpTipEvent` using ``whatsThis`` 
    106113    property of the object. 
    107114 
  • Orange/OrangeCanvas/gui/splashscreen.py

    r11123 r11366  
    11""" 
    2 Orange Canvas Splash Screen 
     2A splash screen widget with support for positioning of the message text. 
     3 
    34""" 
    45 
     
    1314 
    1415class SplashScreen(QSplashScreen): 
     16    """ 
     17    Splash screen widget. 
     18 
     19    Parameters 
     20    ---------- 
     21    parent : :class:`QWidget` 
     22        Parent widget 
     23 
     24    pixmap : :class:`QPixmap` 
     25        Splash window pixmap. 
     26 
     27    textRect : :class:`QRect` 
     28        Bounding rectangle of the shown message on the widget. 
     29 
     30    """ 
    1531    def __init__(self, parent=None, pixmap=None, textRect=None, **kwargs): 
    1632        QSplashScreen.__init__(self, parent, **kwargs) 
     
    3046 
    3147    def setTextRect(self, rect): 
    32         """Set the rectangle in which to show the message text. 
     48        """ 
     49        Set the rectangle (:class:`QRect`) in which to show the message text. 
    3350        """ 
    3451        if self.__textRect != rect: 
     
    3754 
    3855    def textRect(self): 
    39         """Return the text rect. 
     56        """ 
     57        Return the text message rectangle. 
    4058        """ 
    4159        return self.__textRect 
     
    4765 
    4866    def drawContents(self, painter): 
    49         """Reimplementation of drawContents to limit the drawing 
     67        """ 
     68        Reimplementation of drawContents to limit the drawing 
    5069        inside `textRext`. 
    5170 
     
    7594 
    7695    def showMessage(self, message, alignment=Qt.AlignLeft, color=Qt.black): 
     96        """ 
     97        Show the `message` with `color` and `alignment`. 
     98        """ 
    7799        # Need to store all this arguments for drawContents (no access 
    78100        # methods) 
  • Orange/OrangeCanvas/gui/stackedwidget.py

    r11100 r11366  
    44===================== 
    55 
    6 A widget similar to QStackedWidget that supports animated 
     6A widget similar to :class:`QStackedWidget` supporting animated 
    77transitions between widgets. 
    88 
     
    2525 
    2626def clipMinMax(size, minSize, maxSize): 
    27     """Clip the size so it is bigger then minSize but smaller than maxSize. 
     27    """ 
     28    Clip the size so it is bigger then minSize but smaller than maxSize. 
    2829    """ 
    2930    return size.expandedTo(minSize).boundedTo(maxSize) 
     
    3132 
    3233def fixSizePolicy(size, hint, policy): 
    33     """Fix size so it conforms to the size policy and the given size hint. 
     34    """ 
     35    Fix size so it conforms to the size policy and the given size hint. 
    3436    """ 
    3537    width, height = hint.width(), hint.height() 
     
    5355 
    5456class StackLayout(QStackedLayout): 
    55     """A stacked layout with `sizeHint` always the same as that 
    56     of the current widget. 
     57    """ 
     58    A stacked layout with ``sizeHint`` always the same as that of the 
     59    `current` widget. 
    5760 
    5861    """ 
     
    99102 
    100103    def _onCurrentChanged(self, index): 
    101         """Current widget changed, invalidate the layout. 
     104        """ 
     105        Current widget changed, invalidate the layout. 
    102106        """ 
    103107        self.invalidate() 
     
    105109 
    106110class AnimatedStackedWidget(QFrame): 
     111    # Current widget has changed 
    107112    currentChanged = Signal(int) 
     113 
     114    # Transition animation has started 
    108115    transitionStarted = Signal() 
     116 
     117    # Transition animation has finished 
    109118    transitionFinished = Signal() 
    110119 
     
    136145 
    137146    def setAnimationEnabled(self, animationEnabled): 
    138         """Enable/disable transition animations. 
     147        """ 
     148        Enable/disable transition animations. 
    139149        """ 
    140150        if self.__animationEnabled != animationEnabled: 
     
    145155 
    146156    def animationEnabled(self): 
     157        """ 
     158        Is the transition animation enabled. 
     159        """ 
    147160        return self.__animationEnabled 
    148161 
    149162    def addWidget(self, widget): 
    150         """Add the widget to the stack in the last place. 
     163        """ 
     164        Append the widget to the stack and return its index. 
    151165        """ 
    152166        return self.insertWidget(self.layout().count(), widget) 
    153167 
    154168    def insertWidget(self, index, widget): 
    155         """Insert widget at index. 
     169        """ 
     170        Insert `widget` into the stack at `index`. 
    156171        """ 
    157172        index = min(index, self.count()) 
     
    162177 
    163178    def removeWidget(self, widget): 
    164         """Remove `widget` from the stack. 
     179        """ 
     180        Remove `widget` from the stack. 
     181 
     182        .. note:: The widget is hidden but is not deleted. 
     183 
    165184        """ 
    166185        index = self.__widgets.index(widget) 
    167         item = self.layout().takeAt(index) 
    168         assert(item.widget() is widget) 
     186        self.layout().removeWidget(widget) 
    169187        self.__widgets.pop(index) 
    170         widget.deleteLater() 
    171188 
    172189    def widget(self, index): 
    173         """Return the widget at `index` 
     190        """ 
     191        Return the widget at `index` 
    174192        """ 
    175193        return self.__widgets[index] 
    176194 
    177195    def indexOf(self, widget): 
    178         """Return the index of `widget` in the stack. 
     196        """ 
     197        Return the index of `widget` in the stack. 
    179198        """ 
    180199        return self.__widgets.index(widget) 
    181200 
    182201    def count(self): 
    183         """Return the number of widgets in the stack. 
     202        """ 
     203        Return the number of widgets in the stack. 
    184204        """ 
    185205        return max(self.layout().count() - 1, 0) 
    186206 
    187207    def setCurrentWidget(self, widget): 
    188         """Set the current shown widget. 
     208        """ 
     209        Set the current shown widget. 
    189210        """ 
    190211        index = self.__widgets.index(widget) 
     
    192213 
    193214    def setCurrentIndex(self, index): 
    194         """Set the current shown widget index. 
     215        """ 
     216        Set the current shown widget index. 
    195217        """ 
    196218        index = max(min(index, self.count() - 1), 0) 
     
    219241 
    220242    def currentIndex(self): 
     243        """ 
     244        Return the current shown widget index. 
     245        """ 
    221246        return self.__currentIndex 
    222247 
     
    228253 
    229254    def __transitionStart(self): 
    230         """Start the transition. 
     255        """ 
     256        Start the transition. 
    231257        """ 
    232258        log.debug("Stack transition start (%s)", str(self.objectName())) 
     
    238264 
    239265    def __onTransitionFinished(self): 
    240         """Transition has finished. 
     266        """ 
     267        Transition has finished. 
    241268        """ 
    242269        log.debug("Stack transition finished (%s)" % str(self.objectName())) 
     
    254281 
    255282class CrossFadePixmapWidget(QWidget): 
    256     """A widget for cross fading between two pixmaps. 
     283    """ 
     284    A widget for cross fading between two pixmaps. 
    257285    """ 
    258286    def __init__(self, parent=None, pixmap1=None, pixmap2=None): 
     
    264292 
    265293    def setPixmap(self, pixmap): 
    266         """Set pixmap 1 
     294        """ 
     295        Set pixmap 1 
    267296        """ 
    268297        self.pixmap1 = pixmap 
     
    270299 
    271300    def setPixmap2(self, pixmap): 
    272         """Set pixmap 2 
     301        """ 
     302        Set pixmap 2 
    273303        """ 
    274304        self.pixmap2 = pixmap 
     
    276306 
    277307    def setBlendingFactor(self, factor): 
    278         """Set the blending factor between the two pixmaps. 
     308        """ 
     309        Set the blending factor between the two pixmaps. 
    279310        """ 
    280311        self.__blendingFactor = factor 
     
    282313 
    283314    def blendingFactor(self): 
    284         """Pixmap blending factor between 0.0 and 1.0 
     315        """ 
     316        Pixmap blending factor between 0.0 and 1.0 
    285317        """ 
    286318        return self.__blendingFactor 
     
    290322 
    291323    def sizeHint(self): 
    292         """Return an interpolated size between pixmap1.size() 
     324        """ 
     325        Return an interpolated size between pixmap1.size() 
    293326        and pixmap2.size() 
    294327 
     
    302335 
    303336    def paintEvent(self, event): 
    304         """Paint the interpolated pixmap image. 
     337        """ 
     338        Paint the interpolated pixmap image. 
    305339        """ 
    306340        p = QPainter(self) 
  • Orange/OrangeCanvas/gui/toolbar.py

    r11179 r11366  
    11""" 
    2 A custom toolbar. 
     2A custom toolbar with linear uniform size layout. 
    33 
    44""" 
     
    1515 
    1616class DynamicResizeToolBar(QToolBar): 
    17     """A QToolBar subclass that dynamically resizes its tool buttons 
     17    """ 
     18    A :class:`QToolBar` subclass that dynamically resizes its tool buttons 
    1819    to fit available space (this is done by setting fixed size on the 
    1920    button instances). 
  • Orange/OrangeCanvas/gui/toolbox.py

    r11280 r11366  
    11""" 
    22============== 
    3 ToolBox Widget 
     3Tool Box Widget 
    44============== 
    55 
    6 A reimplementation of the QToolBox widget but with all the tabs 
    7 in a single QScrollArea and support for multiple open tabs. 
     6A reimplementation of the :class:`QToolBox` widget that keeps all the tabs 
     7in a single :class:`QScrollArea` instance and can keep multiple open tabs. 
    88 
    99""" 
     
    4040 
    4141def create_tab_gradient(base_color): 
    42     """Create a default background gradient for a tab button from a single 
     42    """ 
     43    Create a default background gradient for a tab button from a single 
    4344    color. 
    4445 
     
    5556 
    5657class ToolBoxTabButton(QToolButton): 
    57     """A tab button for an item in a ToolBox. 
     58    """ 
     59    A tab button for an item in a :class:`ToolBox`. 
    5860    """ 
    5961 
    6062    def setNativeStyling(self, state): 
    61         """Render tab buttons as native QToolButtons. 
     63        """ 
     64        Render tab buttons as native :class:`QToolButtons`. 
     65        If set to `False` (default) the button is pained using a 
     66        custom routine. 
     67 
    6268        """ 
    6369        self.__nativeStyling = state 
     
    6571 
    6672    def nativeStyling(self): 
    67         """Use native QStyle's QToolButton look. 
     73        """ 
     74        Use :class:`QStyle`'s to paint the class:`QToolButton` look. 
    6875        """ 
    6976        return self.__nativeStyling 
     
    210217 
    211218class ToolBox(QFrame): 
    212     """A tool box widget. 
    213     """ 
     219    """ 
     220    A tool box widget. 
     221    """ 
     222    # Emitted when a tab is toggled. 
    214223    tabToogled = Signal(int, bool) 
    215224 
    216225    def setExclusive(self, exclusive): 
    217         """Set exclusive tabs (only one tab can be open at a time). 
     226        """ 
     227        Set exclusive tabs (only one tab can be open at a time). 
    218228        """ 
    219229        if self.__exclusive != exclusive: 
     
    222232 
    223233    def exclusive(self): 
     234        """ 
     235        Are the tabs in the toolbox exclusive. 
     236        """ 
    224237        return self.__exclusive 
    225238 
    226239    exclusive_ = Property(bool, 
    227                          fget=exclusive, 
    228                          fset=setExclusive, 
    229                          designable=True) 
     240                          fget=exclusive, 
     241                          fset=setExclusive, 
     242                          designable=True, 
     243                          doc="Exclusive tabs") 
    230244 
    231245    def __init__(self, parent=None, **kwargs): 
     
    283297 
    284298    def setTabButtonHeight(self, height): 
    285         """Set the tab button height. 
     299        """ 
     300        Set the tab button height. 
    286301        """ 
    287302        if self.__tabButtonHeight != height: 
     
    291306 
    292307    def tabButtonHeight(self): 
     308        """ 
     309        Return the tab button height. 
     310        """ 
    293311        return self.__tabButtonHeight 
    294312 
    295313    def setTabIconSize(self, size): 
    296         """Set the tab button icon size. 
     314        """ 
     315        Set the tab button icon size. 
    297316        """ 
    298317        if self.__tabIconSize != size: 
     
    302321 
    303322    def tabIconSize(self): 
     323        """ 
     324        Return the tab icon size. 
     325        """ 
    304326        return self.__tabIconSize 
    305327 
    306     def tabButton(self, i): 
    307         """Return the tab button for the `i`-th item. 
    308         """ 
    309         return self.__pages[i].button 
    310  
    311     def tabAction(self, i): 
    312         """Return open/close action for the `i`-th tab. 
    313         """ 
    314         return self.__pages[i].action 
     328    def tabButton(self, index): 
     329        """ 
     330        Return the tab button at `index` 
     331        """ 
     332        return self.__pages[index].button 
     333 
     334    def tabAction(self, index): 
     335        """ 
     336        Return open/close action for the tab at `index`. 
     337        """ 
     338        return self.__pages[index].action 
    315339 
    316340    def addItem(self, widget, text, icon=None, toolTip=None): 
    317         """Add the `widget` in a new tab. Return the index of the new tab. 
     341        """ 
     342        Append the `widget` in a new tab and return its index. 
     343 
     344        Parameters 
     345        ---------- 
     346        widget : :class:`QWidget` 
     347            A widget to be inserted. The toolbox takes ownership 
     348            of the widget. 
     349 
     350        text : str 
     351            Name/title of the new tab. 
     352 
     353        icon : :class:`QIcon`, optional 
     354            An icon for the tab button. 
     355 
     356        toolTip : str, optional 
     357            Tool tip for the tab button. 
     358 
    318359        """ 
    319360        return self.insertItem(self.count(), widget, text, icon, toolTip) 
    320361 
    321362    def insertItem(self, index, widget, text, icon=None, toolTip=None): 
    322         """Insert the `widget` in a new tab at position `index`. 
     363        """ 
     364        Insert the `widget` in a new tab at position `index`. 
     365 
     366        See also 
     367        -------- 
     368        ToolBox.addItem 
     369 
    323370        """ 
    324371        button = self.createTabButton(widget, text, icon, toolTip) 
     
    347394 
    348395    def removeItem(self, index): 
     396        """ 
     397        Remove the widget at `index`. 
     398 
     399        .. note:: The widget hidden but is is not deleted. 
     400 
     401        """ 
    349402        self.__contentsLayout.takeAt(2 * index + 1) 
    350403        self.__contentsLayout.takeAt(2 * index) 
    351404        page = self.__pages.pop(index) 
    352405 
     406        # Update the page indexes 
    353407        for i in range(index, self.count()): 
    354408            self.__pages[i] = self.__pages[i]._replace(index=i) 
    355409 
    356410        page.button.deleteLater() 
    357         page.widget.deleteLater() 
     411 
     412        # Hide the widget and reparent to self 
     413        # This follows QToolBox.removeItem 
     414        page.widget.hide() 
     415        page.widget.setParent(self) 
    358416 
    359417        self.__updatePositions() 
     
    363421 
    364422    def count(self): 
     423        """ 
     424        Return the number of widgets inserted in the toolbox. 
     425        """ 
    365426        return len(self.__pages) 
    366427 
    367428    def widget(self, index): 
    368         """Return the widget at index. 
     429        """ 
     430        Return the widget at `index`. 
    369431        """ 
    370432        return self.__pages[index].widget 
    371433 
    372434    def createTabButton(self, widget, text, icon=None, toolTip=None): 
    373         """Create the tab button for `widget`. 
     435        """ 
     436        Create the tab button for `widget`. 
    374437        """ 
    375438        action = QAction(text, self) 
     
    400463 
    401464    def ensureWidgetVisible(self, child, xmargin=50, ymargin=50): 
    402         """Scroll the contents so child widget instance is visible inside 
     465        """ 
     466        Scroll the contents so child widget instance is visible inside 
    403467        the viewport. 
    404468 
     
    503567 
    504568def find(iterable, *what, **kwargs): 
    505     """find(iterable, [what, [key=None, [predicate=operator.eq]]]) 
     569    """ 
     570    find(iterable, [what, [key=None, [predicate=operator.eq]]]) 
    506571    """ 
    507572    if what: 
  • Orange/OrangeCanvas/gui/toolgrid.py

    r11345 r11366  
    11""" 
    2 Tool Grid Widget. 
    3 ================ 
    4  
    5 A Widget containing a grid of clickable actions/buttons. 
     2A widget containing a grid of clickable actions/buttons. 
    63 
    74""" 
     
    110107 
    111108class ToolGrid(QFrame): 
    112     """A widget containing a grid of actions/buttons. 
    113  
    114     Actions can be added using standard QWidget addAction and insertAction 
    115     methods. 
    116  
    117109    """ 
     110    A widget containing a grid of actions/buttons. 
     111 
     112    Actions can be added using standard :ref:`QWidget.addAction(QAction)` 
     113    and :ref:`QWidget.insertAction(int, QAction)` methods. 
     114 
     115    Parameters 
     116    ---------- 
     117    parent : :class:`QWidget` 
     118        Parent widget. 
     119    columns : int 
     120        Number of columns in the grid layout. 
     121    buttonSize : :class:`QSize`, optional 
     122        Size of tool buttons in the grid. 
     123    iconSize : :class:`QSize`, optional 
     124        Size of icons in the buttons. 
     125    toolButtonStyle : :class:`Qt.ToolButtonStyle` 
     126        Tool button style. 
     127 
     128    """ 
     129 
    118130    actionTriggered = Signal(QAction) 
    119131    actionHovered = Signal(QAction) 
     
    157169 
    158170    def setButtonSize(self, size): 
    159         """Set the button size. 
     171        """ 
     172        Set the button size. 
    160173        """ 
    161174        if self.__buttonSize != size: 
     
    165178 
    166179    def buttonSize(self): 
     180        """ 
     181        Return the button size. 
     182        """ 
    167183        return QSize(self.__buttonSize) 
    168184 
    169185    def setIconSize(self, size): 
    170         """Set the button icon size. 
     186        """ 
     187        Set the button icon size. 
    171188        """ 
    172189        if self.__iconSize != size: 
     
    176193 
    177194    def iconSize(self): 
     195        """ 
     196        Return the icon size 
     197        """ 
    178198        return QSize(self.__iconSize) 
    179199 
    180200    def setToolButtonStyle(self, style): 
    181         """Set the tool button style. 
     201        """ 
     202        Set the tool button style. 
    182203        """ 
    183204        if self.__toolButtonStyle != style: 
     
    187208 
    188209    def toolButtonStyle(self): 
     210        """ 
     211        Return the tool button style. 
     212        """ 
    189213        return self.__toolButtonStyle 
    190214 
    191215    def setColumnCount(self, columns): 
    192         """Set the number of button/action columns. 
     216        """ 
     217        Set the number of button/action columns. 
    193218        """ 
    194219        if self.__columns != columns: 
     
    197222 
    198223    def columns(self): 
     224        """ 
     225        Return the number of columns in the grid. 
     226        """ 
    199227        return self.__columns 
    200228 
    201229    def clear(self): 
    202         """Clear all actions. 
     230        """ 
     231        Clear all actions/buttons. 
    203232        """ 
    204233        for slot in reversed(list(self.__gridSlots)): 
     
    207236 
    208237    def insertAction(self, before, action): 
    209         """Insert a new action at the position currently occupied 
     238        """ 
     239        Insert a new action at the position currently occupied 
    210240        by `before` (can also be an index). 
     241 
     242        Parameters 
     243        ---------- 
     244        before : :class:`QAction` or int 
     245            Position where the `action` should be inserted. 
     246        action : :class:`QAction` 
     247            Action to insert 
    211248 
    212249        """ 
     
    214251            actions = list(self.actions()) 
    215252            if len(actions) == 0 or before >= len(actions): 
    216                 # Insert as the first action of the last action. 
     253                # Insert as the first action or the last action. 
    217254                return self.addAction(action) 
    218255 
     
    222259 
    223260    def setActions(self, actions): 
    224         """Clear the grid and add actions. 
     261        """ 
     262        Clear the grid and add `actions`. 
    225263        """ 
    226264        self.clear() 
     
    230268 
    231269    def buttonForAction(self, action): 
    232         """Return the `QToolButton` instance button for `action`. 
     270        """ 
     271        Return the :class:`QToolButton` instance button for `action`. 
    233272        """ 
    234273        actions = [slot.action for slot in self.__gridSlots] 
     
    237276 
    238277    def createButtonForAction(self, action): 
    239         """Create and return a QToolButton for action. 
     278        """ 
     279        Create and return a :class:`QToolButton` for action. 
    240280        """ 
    241281        button = _ToolGridButton(self) 
     
    252292 
    253293    def count(self): 
     294        """ 
     295        Return the number of buttons/actions in the grid. 
     296        """ 
    254297        return len(self.__gridSlots) 
    255298 
     
    349392 
    350393    def __onButtonRightClick(self, button): 
    351         print button 
     394        pass 
    352395 
    353396    def __onButtonEnter(self, button): 
     
    397440 
    398441class ToolButtonEventListener(QObject): 
    399     """An event listener(filter) for QToolButtons. 
     442    """ 
     443    An event listener(filter) for :class:`QToolButtons`. 
    400444    """ 
    401445    buttonLeftClicked = Signal(QToolButton) 
  • Orange/OrangeCanvas/gui/tooltree.py

    r11228 r11370  
    11""" 
     2========= 
     3Tool Tree 
     4========= 
     5 
    26A ToolTree widget presenting the user with a set of actions 
    37organized in a tree structure. 
     
    913from PyQt4.QtGui import ( 
    1014    QTreeView, QWidget, QVBoxLayout, QSizePolicy, QStandardItemModel, 
    11     QAbstractProxyModel, QStyledItemDelegate, QStyle, QAction, QIcon 
     15    QAbstractProxyModel, QStyledItemDelegate, QStyle, QAction 
    1216) 
    1317 
    1418from PyQt4.QtCore import Qt, QEvent, QModelIndex 
    15 from PyQt4.QtCore import pyqtSignal as Signal, pyqtProperty as Property 
     19from PyQt4.QtCore import pyqtSignal as Signal 
    1620 
    1721log = logging.getLogger(__name__) 
     
    1923 
    2024class ToolTree(QWidget): 
    21     """A ListView like presentation of a list of actions. 
     25    """ 
     26    A ListView like presentation of a list of actions. 
    2227    """ 
    2328    triggered = Signal(QAction) 
    2429    hovered = Signal(QAction) 
    2530 
    26     def __init__(self, parent=None, title=None, icon=None, **kwargs): 
     31    def __init__(self, parent=None, **kwargs): 
    2732        QTreeView.__init__(self, parent, **kwargs) 
    2833        self.setSizePolicy(QSizePolicy.MinimumExpanding, 
    2934                           QSizePolicy.Expanding) 
    30  
    31         if title is None: 
    32             title = "" 
    33  
    34         if icon is None: 
    35             icon = QIcon() 
    36  
    37         self.__title = title 
    38         self.__icon = icon 
    3935 
    4036        self.__model = QStandardItemModel() 
     
    7167        self.setLayout(layout) 
    7268 
    73     def setTitle(self, title): 
    74         """Set the title 
    75         """ 
    76         if self.__title != title: 
    77             self.__title = title 
    78             self.update() 
    79  
    80     def title(self): 
    81         """Return the title of this tool tree. 
    82         """ 
    83         return self.__title 
    84  
    85     title_ = Property(unicode, fget=title, fset=setTitle) 
    86  
    87     def setIcon(self, icon): 
    88         """Set icon for this tool tree. 
    89         """ 
    90         if self.__icon != icon: 
    91             self.__icon = icon 
    92             self.update() 
    93  
    94     def icon(self): 
    95         """Return the icon of this tool tree. 
    96         """ 
    97         return self.__icon 
    98  
    99     icon_ = Property(QIcon, fget=icon, fset=setIcon) 
    100  
    10169    def setFlattened(self, flatten): 
    102         """Show the actions in a flattened view. 
     70        """ 
     71        Show the actions in a flattened view. 
    10372        """ 
    10473        if self.__flattened != flatten: 
     
    11382 
    11483    def flattened(self): 
     84        """ 
     85        Are actions shown in a flattened tree (a list). 
     86        """ 
    11587        return self.__flattened 
    11688 
  • Orange/OrangeCanvas/registry/__init__.py

    r11285 r11368  
    11""" 
    2 =============== 
    3 Widget Registry 
    4 =============== 
     2The registry module implements discovery and description of the widgets 
     3that are available/installed. The :class:`WidgetRegistry` is a repository 
     4of :class:`WidgetDescription` and :class:`CategoryDescription` instances 
     5forming a two level widget hierarchy ([category]/[widget]). 
    56 
    6 A registry (and discovery) of available widgets. 
     7The :class:`WidgetDiscovery` can be used to populate the registry. 
     8 
    79 
    810""" 
     
    4143from .base import WidgetRegistry, VERSION_HEX 
    4244from . import discovery 
     45from .discovery import WidgetDiscovery 
    4346 
    4447log = logging.getLogger(__name__) 
  • Orange/OrangeCanvas/registry/base.py

    r11282 r11368  
    1818 
    1919class WidgetRegistry(object): 
    20     """A container for widget and category descriptions. 
     20    """ 
     21    A container for widget and category descriptions. 
    2122 
    2223    This class is most often used with WidgetDiscovery class but can 
     
    2425 
    2526    >>> reg = WidgetRegistry() 
    26     >>> file_desc = description.WidgetDescription.from_module( 
     27    >>> file_desc = WidgetDescription.from_module( 
    2728    ...     "Orange.OrangeWidgets.Data.OWFile" 
    2829    ... ) 
    2930    ... 
    30     >>> reg.register_widget(file_desc) 
    31     >>> reg.widgets() 
     31    >>> reg.register_widget(file_desc)  # register the description 
     32    >>> print reg.widgets() 
    3233    [... 
     34 
     35    Parameters 
     36    ---------- 
     37    other : :class:`WidgetRegistry`, optional 
     38        If supplied the registry is initialized with the contents of `other`. 
    3339 
    3440    """ 
     
    5258 
    5359    def categories(self): 
    54         """List all top level widget categories ordered by priority. 
     60        """ 
     61        Return a list all top level :class:`CategoryDescription` instances 
     62        ordered by priority. 
     63 
    5564        """ 
    5665        return [c for c, _ in self.registry] 
    5766 
    5867    def category(self, name): 
    59         """Return category with `name`. 
     68        """ 
     69        Find a :class:`CategoryDescription` by its `name`. 
    6070 
    6171        .. note:: Categories are identified by `name` attribute in contrast 
    62             with widgets which are identified by `qualified_name`. 
     72                  with widgets which are identified by `qualified_name`. 
     73 
     74        Parameters 
     75        ---------- 
     76        name : str 
     77            Category name 
    6378 
    6479        """ 
     
    6681 
    6782    def has_category(self, name): 
    68         """Does the category with `name` exist in this registry. 
     83        """ 
     84        Does a category with `name` exist in this registry. 
     85 
     86        Parameters 
     87        ---------- 
     88        name : str 
     89            Category name 
     90 
    6991        """ 
    7092        return name in self._categories_dict 
    7193 
    7294    def widgets(self, category=None): 
    73         """List all widgets in a `category`. If no category is 
    74         specified list widgets in all categories. 
     95        """ 
     96        Return a list of all widgets in the registry. If `category` is 
     97        specified return only widgets which belong to the category. 
     98 
     99        Parameters 
     100        ---------- 
     101        category : :class:`CategoryDescription` or str, optional 
     102            Return only descriptions of widgets belonging to the category. 
    75103 
    76104        """ 
     
    92120 
    93121    def widget(self, qualified_name): 
    94         """Return widget description for `qualified_name`. 
    95         Raise KeyError if the description does not exist. 
     122        """ 
     123        Return a :class:`WidgetDescription` identified by `qualified_name`. 
     124 
     125        Raise :class:`KeyError` if the description does not exist. 
     126 
     127        Parameters 
     128        ---------- 
     129        qualified_name : str 
     130            Widget description qualified name 
     131 
     132        See also 
     133        -------- 
     134        WidgetDescription 
    96135 
    97136        """ 
     
    99138 
    100139    def has_widget(self, qualified_name): 
    101         """Does the widget with `qualified_name` exist in this registry. 
     140        """ 
     141        Does the widget with `qualified_name` exist in this registry. 
    102142        """ 
    103143        return qualified_name in self._widgets_dict 
    104144 
    105145    def register_widget(self, desc): 
    106         """Register a widget by its description. 
     146        """ 
     147        Register a :class:`WidgetDescription` instance. 
    107148        """ 
    108149        if not isinstance(desc, description.WidgetDescription): 
     
    128169 
    129170    def register_category(self, desc): 
    130         """Register category by its description. 
     171        """ 
     172        Register a :class:`CategoryDescription` instance. 
    131173 
    132174        .. note:: It is always best to register the category 
    133             before the widgets belonging to it. 
     175                  before the widgets belonging to it. 
    134176 
    135177        """ 
     
    150192 
    151193    def _insert_category(self, desc): 
    152         """Insert category description into 'registry' list 
     194        """ 
     195        Insert category description into 'registry' list 
    153196        """ 
    154197        priority = desc.priority 
     
    161204 
    162205    def _insert_widget(self, category, desc): 
    163         """Insert widget description `desc` into `category`. 
     206        """ 
     207        Insert widget description `desc` into `category`. 
    164208        """ 
    165209        assert(isinstance(category, description.CategoryDescription)) 
  • Orange/OrangeCanvas/registry/description.py

    r11290 r11368  
    11""" 
    2 Widget meta description classes. 
     2Widget meta description classes 
     3=============================== 
    34 
    45""" 
     
    212213    help : str, optional 
    213214        URL or an Resource template of a detailed widget help page. 
    214     help_ref: str, optional 
     215    help_ref : str, optional 
    215216        A text reference id that can be used to identify the help 
    216217        page, for instance an intersphinx reference. 
     
    231232    background : str, optional 
    232233        Widget's background color (in the canvas GUI). 
    233     replaces: list-of-str, optional 
     234    replaces : list-of-str, optional 
    234235        A list of `id`s this widget replaces (optional). 
    235236 
  • Orange/OrangeCanvas/registry/discovery.py

    r11295 r11368  
    408408    def cache_has_valid_entry(self, mod_path, distribution=None): 
    409409        """ 
    410         Does the cache have a valid entry for `mod_path. 
     410        Does the cache have a valid entry for `mod_path`. 
    411411        """ 
    412412        mod_path = fix_pyext(mod_path) 
  • Orange/OrangeCanvas/scheme/__init__.py

    r11101 r11367  
    11""" 
    2 ===================== 
    3 Scheme Workflow Model 
    4 ===================== 
     2====== 
     3Scheme 
     4====== 
     5 
     6The scheme package implements and defines the underlying workflow model. 
     7 
     8The :class:`Scheme` class represents the workflow and is composed of a set 
     9of :class:`SchemeNode` connected with :class:`SchemeLink`, defining an 
     10directed acyclic graph (DAG). Additionally instances of 
     11:class:`SchemeArrowAnnotation` or :class:`SchemeTextAnnotation` can be 
     12inserted into the scheme. 
    513 
    614""" 
  • Orange/OrangeCanvas/scheme/annotations.py

    r11202 r11367  
    11""" 
     2================== 
    23Scheme Annotations 
     4================== 
    35 
    46""" 
     
    1214 
    1315class BaseSchemeAnnotation(QObject): 
    14     """Base class for scheme annotations. 
    1516    """ 
     17    Base class for scheme annotations. 
     18    """ 
     19    # Signal emitted when the geometry of the annotation changes 
    1620    geometry_changed = Signal() 
    1721 
    1822 
    1923class SchemeArrowAnnotation(BaseSchemeAnnotation): 
    20     """An arrow annotation in the scheme. 
     24    """ 
     25    An arrow annotation in the scheme. 
    2126    """ 
    2227 
     
    3237 
    3338    def set_line(self, start_pos, end_pos): 
    34         """Set arrow lines start and end position ((x, y) tuples). 
     39        """ 
     40        Set arrow lines start and end position (``(x, y)`` tuples). 
    3541        """ 
    3642        if self.__start_pos != start_pos or self.__end_pos != end_pos: 
     
    4046 
    4147    def start_pos(self): 
    42         """Start position. 
     48        """ 
     49        Start position of the arrow (base point). 
    4350        """ 
    4451        return self.__start_pos 
     
    4754 
    4855    def end_pos(self): 
    49         """Arrows end position (arrow head points toward the end).""" 
     56        """ 
     57        End position of the arrow (arrow head points toward the end). 
     58        """ 
    5059        return self.__end_pos 
    5160 
     
    5362 
    5463    def set_geometry(self, (start_pos, end_pos)): 
    55         """Set the geometry of the arrow as a start and end position tuples 
    56         (e.g. `set_geometry(((0, 0), (100, 0))). 
     64        """ 
     65        Set the geometry of the arrow as a start and end position tuples 
     66        (e.g. ``set_geometry(((0, 0), (100, 0))``). 
    5767 
    5868        """ 
     
    6070 
    6171    def geometry(self): 
    62         """Return the start and end positions of the arrow. 
    63  
     72        """ 
     73        Return the start and end positions of the arrow. 
    6474        """ 
    6575        return (self.start_pos, self.end_pos) 
     
    6878 
    6979    def set_color(self, color): 
    70         """Set the fill color for the arrow as a string (#RGB, #RRGGBB, 
    71         #RRRGGGBBB, #RRRRGGGGBBBB format or one of SVG color keyword 
     80        """ 
     81        Set the fill color for the arrow as a string (`#RGB`, `#RRGGBB`, 
     82        `#RRRGGGBBB`, `#RRRRGGGGBBBB` format or one of SVG color keyword 
    7283        names). 
    7384 
     
    8091 
    8192    def color(self): 
    82         """Return the arrow's fill color. 
     93        """ 
     94        The arrow's fill color. 
    8395        """ 
    8496        return self.__color 
     
    88100 
    89101class SchemeTextAnnotation(BaseSchemeAnnotation): 
    90     """Text annotation in the scheme. 
    91102    """ 
     103    Text annotation in the scheme. 
     104    """ 
     105 
     106    # Signal emitted when the annotation text changes. 
    92107    text_changed = Signal(unicode) 
     108 
     109    # Signal emitted when the annotation text font changes. 
    93110    font_changed = Signal(dict) 
    94111 
     
    101118 
    102119    def set_rect(self, (x, y, w, h)): 
    103         """Set the text geometry bounding rectangle 
    104         ((x, y, width, height) tuple). 
     120        """ 
     121        Set the text geometry bounding rectangle (``(x, y, width, height)`` 
     122        tuple). 
    105123 
    106124        """ 
     
    111129 
    112130    def rect(self): 
    113         """Text bounding rectangle 
     131        """ 
     132        Text bounding rectangle 
    114133        """ 
    115134        return self.__rect 
     
    118137 
    119138    def set_geometry(self, rect): 
    120         """Set the text geometry (same as `set_rect`) 
     139        """ 
     140        Set the text geometry (same as ``set_rect``) 
    121141        """ 
    122142        self.set_rect(rect) 
    123143 
    124144    def geometry(self): 
     145        """ 
     146        Text annotation geometry (same as ``rect`` 
     147        """ 
    125148        return self.rect 
    126149 
     
    128151 
    129152    def set_text(self, text): 
    130         """Set the annotation text. 
     153        """ 
     154        Set the annotation text. 
    131155        """ 
    132156        check_type(text, (basestring, QString)) 
     
    137161 
    138162    def text(self): 
    139         """Annotation text. 
     163        """ 
     164        Annotation text. 
    140165        """ 
    141166        return self.__text 
     
    144169 
    145170    def set_font(self, font): 
    146         """Set the annotation's font as a dictionary of font properties 
     171        """ 
     172        Set the annotation's font as a dictionary of font properties 
    147173        (at the moment only family and size are used). 
    148174 
    149             annotation.set_font({"family": "Helvetica", "size": 16}) 
     175            >>> annotation.set_font({"family": "Helvetica", "size": 16}) 
    150176 
    151177        """ 
     
    157183 
    158184    def font(self): 
    159         """Return the annotation's font property dictionary. 
     185        """ 
     186        Annotation's font property dictionary. 
    160187        """ 
    161188        return dict(self.__font) 
  • Orange/OrangeCanvas/scheme/link.py

    r11302 r11367  
    1515 
    1616def compatible_channels(source_channel, sink_channel): 
    17     """Do the channels in link have compatible types, i.e. can they be 
     17    """ 
     18    Do the channels in link have compatible types, i.e. can they be 
    1819    connected based on their type. 
    1920 
     
    2829 
    2930def can_connect(source_node, sink_node): 
    30     """Return True if any output from `source_node` can be connected to 
     31    """ 
     32    Return True if any output from `source_node` can be connected to 
    3133    any input of `sink_node`. 
    3234 
     
    3638 
    3739def possible_links(source_node, sink_node): 
    38     """Return a list of (OutputSignal, InputSignal) tuples, that 
     40    """ 
     41    Return a list of (OutputSignal, InputSignal) tuples, that 
    3942    can connect the two nodes. 
    4043 
     
    4952 
    5053class SchemeLink(QObject): 
    51     """A instantiation of a link between two widget nodes in the scheme. 
     54    """ 
     55    A instantiation of a link between two :class:`.SchemeNode` instances 
     56    in a :class:`.Scheme`. 
    5257 
    5358    Parameters 
    5459    ---------- 
    55     source_node : `SchemeNode` 
     60    source_node : :class:`.SchemeNode` 
    5661        Source node. 
    57     source_channel : `OutputSignal` 
     62    source_channel : :class:`OutputSignal` 
    5863        The source widget's signal. 
    59     sink_node : `SchemeNode` 
     64    sink_node : :class:`.SchemeNode` 
    6065        The sink node. 
    61     sink_channel : `InputSignal` 
     66    sink_channel : :class:`InputSignal` 
    6267        The sink widget's input signal. 
    6368    properties : `dict` 
     
    105110 
    106111    def source_type(self): 
    107         """Return the type of the source channel. 
     112        """ 
     113        Return the type of the source channel. 
    108114        """ 
    109115        return name_lookup(self.source_channel.type) 
    110116 
    111117    def sink_type(self): 
    112         """Return the type of the sink channel. 
     118        """ 
     119        Return the type of the sink channel. 
    113120        """ 
    114121        return name_lookup(self.sink_channel.type) 
    115122 
    116123    def is_dynamic(self): 
    117         """Is this link dynamic. 
     124        """ 
     125        Is this link dynamic. 
    118126        """ 
    119127        return self.source_channel.dynamic and \ 
     
    121129            not (self.sink_type() is self.source_type()) 
    122130 
    123     def enabled(self): 
    124         """Is this link enabled. 
     131    def set_enabled(self, enabled): 
    125132        """ 
    126         return self.__enabled 
    127  
    128     def set_enabled(self, enabled): 
    129         """Enable/disable the link. 
     133        Enable/disable the link. 
    130134        """ 
    131135        if self.__enabled != enabled: 
     
    133137            self.enabled_changed.emit(enabled) 
    134138 
     139    def enabled(self): 
     140        """ 
     141        Is this link enabled. 
     142        """ 
     143        return self.__enabled 
     144 
    135145    enabled = Property(bool, fget=enabled, fset=set_enabled) 
    136146 
    137147    def set_dynamic_enabled(self, enabled): 
    138         """Enable/disable the dynamic link. Has no effect if 
    139         the link is not dynamic. 
     148        """ 
     149        Enable/disable the dynamic link. Has no effect if the link 
     150        is not dynamic. 
    140151 
    141152        """ 
     
    145156 
    146157    def dynamic_enabled(self): 
    147         """Is this dynamic link and `dynamic_enabled` set to True 
     158        """ 
     159        Is this a dynamic link and is `dynamic_enabled` set to `True` 
    148160        """ 
    149161        return self.is_dynamic() and self.__dynamic_enabled 
    150162 
    151163    dynamic_enabled = Property(bool, fget=dynamic_enabled, 
    152                                  fset=set_dynamic_enabled) 
     164                               fset=set_dynamic_enabled) 
    153165 
    154166    def set_tool_tip(self, tool_tip): 
    155         """Set the link tool tip. 
     167        """ 
     168        Set the link tool tip. 
    156169        """ 
    157170        if self.__tool_tip != tool_tip: 
     
    159172 
    160173    def tool_tip(self): 
    161         """Return the link's tool tip 
     174        """ 
     175        Link tool tip. 
    162176        """ 
    163177        return self.__tool_tip 
    164178 
    165179    tool_tip = Property(str, fget=tool_tip, 
    166                           fset=set_tool_tip) 
     180                        fset=set_tool_tip) 
    167181 
    168182    def __str__(self): 
  • Orange/OrangeCanvas/scheme/node.py

    r11302 r11367  
    1212 
    1313class SchemeNode(QObject): 
    14     """A widget node instantiation in the scheme. 
     14    """ 
     15    A node in a :class:`.Scheme`. 
    1516 
    1617    Parameters 
    1718    ---------- 
    18     description : `WidgetDescription` 
    19         Widget description. 
    20     title : `str` 
    21         Node title string (if None description.name is used). 
     19    description : :class:`WidgetDescription` 
     20        Node description instance. 
     21    title : str, optional 
     22        Node title string (if None `description.name` is used). 
    2223    position : tuple 
    23         (x, y) two-tuple for node position in a visual display. 
    24     properties : `dict` 
    25         Additional instance properties (settings, widget geometry, ...) 
    26     parent : `QObject` 
     24        (x, y) tuple of floats for node position in a visual display. 
     25    properties : dict 
     26        Additional extra instance properties (settings, widget geometry, ...) 
     27    parent : :class:`QObject` 
    2728        Parent object. 
    2829 
     
    4445 
    4546    def input_channels(self): 
    46         """Return the input channels for the node. 
    4747        """ 
    48         return self.description.inputs 
     48        Return a list of input channels (:class:`InputSignal`) for the node. 
     49        """ 
     50        return list(self.description.inputs) 
    4951 
    5052    def output_channels(self): 
    51         """Return the output channels for the node. 
    5253        """ 
    53         return self.description.outputs 
     54        Return a list of output channels (:class:`OutputSignal`) for the node. 
     55        """ 
     56        return list(self.description.outputs) 
    5457 
    5558    def input_channel(self, name): 
    56         """Return the input channel matching `name`. Raise an ValueError 
     59        """ 
     60        Return the input channel matching `name`. Raise a `ValueError` 
    5761        if not found. 
    5862 
     
    6569 
    6670    def output_channel(self, name): 
    67         """Return the output channel matching `name`. Raise an ValueError 
     71        """ 
     72        Return the output channel matching `name`. Raise an `ValueError` 
    6873        if not found. 
    6974 
     
    7580                         (name, self.description.name)) 
    7681 
    77     def __str__(self): 
    78         return u"SchemeNode(description_id=%s, title=%r, ...)" % \ 
    79                 (str(self.description.id), self.title) 
    80  
    81     def __repr__(self): 
    82         return str(self) 
    83  
     82    # The title of the node has changed 
    8483    title_changed = Signal(unicode) 
    85     """The title of the node has changed""" 
    8684 
    8785    def set_title(self, title): 
    88         """Set the node's title 
     86        """ 
     87        Set the node title. 
    8988        """ 
    9089        if self.__title != title: 
     
    9392 
    9493    def title(self): 
    95         """Return the nodes title. 
     94        """ 
     95        Return the node title. 
    9696        """ 
    9797        return self.__title 
     
    9999    title = Property(unicode, fset=set_title, fget=title) 
    100100 
     101    # Position of the node in the scheme has changed 
    101102    position_changed = Signal(tuple) 
    102     """Position of the node in the scheme has changed""" 
    103103 
    104104    def set_position(self, pos): 
    105         """Set the position of the node 
     105        """ 
     106        Set the position (``(x, y)`` tuple) of the node. 
    106107        """ 
    107108        if self.__position != pos: 
     
    110111 
    111112    def position(self): 
    112         """(x, y) tuple containing the position of the node in the scheme. 
     113        """ 
     114        ``(x, y)`` tuple containing the position of the node in the scheme. 
    113115        """ 
    114116        return self.__position 
     
    116118    position = Property(tuple, fset=set_position, fget=position) 
    117119 
     120    # Node's progress value has changed. 
    118121    progress_changed = Signal(float) 
    119     """Node's progress value has changed.""" 
    120122 
    121123    def set_progress(self, value): 
    122         """Set the progress value. 
     124        """ 
     125        Set the progress value. 
    123126        """ 
    124127        if self.__progress != value: 
     
    127130 
    128131    def progress(self): 
    129         """Return the current progress value. -1 if progress is not set. 
     132        """ 
     133        Return the current progress value. -1 if progress is not set. 
    130134        """ 
    131135        return self.__progress 
     
    133137    progress = Property(float, fset=set_progress, fget=progress) 
    134138 
     139    # Node's processing state has changed. 
    135140    processing_state_changed = Signal(int) 
    136     """Node's processing state has changed.""" 
    137141 
    138142    def set_processing_state(self, state): 
    139         """Set the node's processing state 
     143        """ 
     144        Set the node processing state. 
    140145        """ 
    141146        if self.__processing_state != state: 
     
    144149 
    145150    def processing_state(self): 
    146         """Return the node's processing state, 0 for not processing, 1 the 
     151        """ 
     152        Return the node processing state, 0 for not processing, 1 the 
    147153        node is busy. 
    148154 
     
    151157 
    152158    processing_state = Property(int, fset=set_processing_state, 
    153                                   fget=processing_state) 
     159                                fget=processing_state) 
    154160 
    155161    def set_tool_tip(self, tool_tip): 
     
    161167 
    162168    tool_tip = Property(str, fset=set_tool_tip, 
    163                           fget=tool_tip) 
     169                        fget=tool_tip) 
     170 
     171    def __str__(self): 
     172        return u"SchemeNode(description_id=%s, title=%r, ...)" % \ 
     173                (str(self.description.id), self.title) 
     174 
     175    def __repr__(self): 
     176        return str(self) 
  • Orange/OrangeCanvas/scheme/readwrite.py

    r11307 r11367  
    11""" 
    22Scheme save/load routines. 
     3 
    34""" 
    45import sys 
    5 import shutil 
    66 
    77from xml.etree.ElementTree import TreeBuilder, Element, ElementTree, parse 
     
    3030def sniff_version(stream): 
    3131    """ 
    32     Parse a scheme stream and return the scheme's version string. 
     32    Parse a scheme stream and return the scheme's serialization 
     33    version string. 
     34 
    3335    """ 
    3436    doc = parse(stream) 
     
    447449    """ 
    448450    Indent an instance of a :class:`Element`. Based on 
    449     `http://effbot.org/zone/element-lib.htm#prettyprint`_). 
     451    (http://effbot.org/zone/element-lib.htm#prettyprint). 
    450452 
    451453    """ 
  • Orange/OrangeCanvas/scheme/scheme.py

    r11275 r11367  
    11""" 
     2=============== 
    23Scheme Workflow 
     4=============== 
     5 
     6The :class:`Scheme` class defines a DAG (Directed Acyclic Graph) workflow. 
    37 
    48""" 
     
    3236 
    3337class Scheme(QObject): 
    34     """An QObject representing the scheme widget workflow 
    35     with annotations, etc. 
    36  
    3738    """ 
    38  
     39    An :class:`QObject` subclass representing the scheme widget workflow 
     40    with annotations. 
     41 
     42    Parameters 
     43    ---------- 
     44    parent : :class:`QObject` 
     45        A parent QObject item (default `None`). 
     46    title : str 
     47        The scheme title. 
     48    description : str 
     49        A longer description of the scheme. 
     50 
     51 
     52    Attributes 
     53    ---------- 
     54    nodes : list of :class:`.SchemeNode` 
     55        A list of all the nodes in the scheme. 
     56 
     57    links : list of :class:`.SchemeLink` 
     58        A list of all links in the scheme. 
     59 
     60    annotations : list of :class:`BaseSchemeAnnotation` 
     61        A list of all the annotations in the scheme. 
     62 
     63    """ 
     64 
     65    # Signal emitted when a `node` is added to the scheme. 
    3966    node_added = Signal(SchemeNode) 
     67 
     68    # Signal emitted when a `node` is removed from the scheme. 
    4069    node_removed = Signal(SchemeNode) 
    4170 
     71    # Signal emitted when a `link` is added to the scheme. 
    4272    link_added = Signal(SchemeLink) 
     73 
     74    # Signal emitted when a `link` is removed from the scheme. 
    4375    link_removed = Signal(SchemeLink) 
    4476 
    45     topology_changed = Signal() 
     77    # Signal emitted when a `annotation` is added to the scheme. 
     78    annotation_added = Signal(BaseSchemeAnnotation) 
     79 
     80    # Signal emitted when a `annotation` is removed from the scheme. 
     81    annotation_removed = Signal(BaseSchemeAnnotation) 
     82 
     83    # Signal emitted when the title of scheme changes. 
     84    title_changed = Signal(unicode) 
     85 
     86    # Signal emitted when the description of scheme changes. 
     87    description_changed = Signal(unicode) 
    4688 
    4789    node_state_changed = Signal() 
    4890    channel_state_changed = Signal() 
    49  
    50     annotation_added = Signal(BaseSchemeAnnotation) 
    51     annotation_removed = Signal(BaseSchemeAnnotation) 
    52  
    53     node_property_changed = Signal(SchemeNode, str, object) 
    54  
    55     title_changed = Signal(unicode) 
    56     description_changed = Signal(unicode) 
     91    topology_changed = Signal() 
    5792 
    5893    def __init__(self, parent=None, title=None, description=None): 
     
    71106    @property 
    72107    def nodes(self): 
     108        """ 
     109        A list of all nodes (:class:`.SchemeNode`) currently in the scheme. 
     110        """ 
    73111        return list(self.__nodes) 
    74112 
    75113    @property 
    76114    def links(self): 
     115        """ 
     116        A list of all links (:class:`.SchemeLink`) currently in the scheme. 
     117        """ 
    77118        return list(self.__links) 
    78119 
    79120    @property 
    80121    def annotations(self): 
     122        """ 
     123        A list of all annotations (:class:`.BaseSchemeAnnotation`) in the 
     124        scheme. 
     125 
     126        """ 
    81127        return list(self.__annotations) 
    82128 
    83129    def set_title(self, title): 
     130        """ 
     131        Set the scheme title text. 
     132        """ 
    84133        if self.__title != title: 
    85134            self.__title = title 
     
    87136 
    88137    def title(self): 
     138        """ 
     139        The title (human readable string) of the scheme. 
     140        """ 
    89141        return self.__title 
    90142 
     
    92144 
    93145    def set_description(self, description): 
     146        """ 
     147        Set the scheme description text. 
     148        """ 
    94149        if self.__description != description: 
    95150            self.__description = description 
     
    97152 
    98153    def description(self): 
     154        """ 
     155        Scheme description text. 
     156        """ 
    99157        return self.__description 
    100158 
     
    102160 
    103161    def add_node(self, node): 
    104         """Add a node to the scheme. 
     162        """ 
     163        Add a node to the scheme. An error is raised if the node is 
     164        already in the scheme. 
    105165 
    106166        Parameters 
    107167        ---------- 
    108         node : `SchemeNode` 
    109             Node to add to the scheme. 
     168        node : :class:`.SchemeNode` 
     169            Node instance to add to the scheme. 
    110170 
    111171        """ 
     
    120180    def new_node(self, description, title=None, position=None, 
    121181                 properties=None): 
    122         """Create a new SchemeNode and add it to the scheme. 
    123         Same as: 
     182        """ 
     183        Create a new :class:`.SchemeNode` and add it to the scheme. 
     184 
     185        Same as:: 
    124186 
    125187            scheme.add_node(SchemeNode(description, title, position, 
    126188                                       properties)) 
     189 
     190        Parameters 
     191        ---------- 
     192        description : :class:`WidgetDescription` 
     193            The new node's description. 
     194        title : str, optional 
     195            Optional new nodes title. By default `description.name` is used. 
     196        position : `(x, y)` tuple of floats, optional 
     197            Optional position in a 2D space. 
     198        properties : dict, optional 
     199            A dictionary of optional extra properties. 
     200 
     201        See also 
     202        -------- 
     203        SchemeNode, Scheme.add_node 
    127204 
    128205        """ 
     
    138215 
    139216    def remove_node(self, node): 
    140         """Remove a `node` from the scheme. All links into and out of the node 
    141         are also removed. 
     217        """ 
     218        Remove a `node` from the scheme. All links into and out of the 
     219        `node` are also removed. If the node in not in the scheme an error 
     220        is raised. 
     221 
     222        Parameters 
     223        ---------- 
     224        node : :class:`.SchemeNode` 
     225            Node instance to remove. 
    142226 
    143227        """ 
     
    152236 
    153237    def __remove_node_links(self, node): 
    154         """Remove all links for node. 
     238        """ 
     239        Remove all links for node. 
    155240        """ 
    156241        links_in, links_out = [], [] 
     
    166251    def add_link(self, link): 
    167252        """ 
    168         Add a link to the scheme. 
     253        Add a `link` to the scheme. 
     254 
     255        Parameters 
     256        ---------- 
     257        link : :class:`.SchemeLink` 
     258            An initialized link instance to add to the scheme. 
     259 
    169260        """ 
    170261        check_type(link, SchemeLink) 
     
    186277        Create a new SchemeLink and add it to the scheme. 
    187278 
    188         Same as: 
     279        Same as:: 
    189280 
    190281            scheme.add_link(SchemeLink(source_node, source_channel, 
    191                                        sink_node, sink_channel) 
     282                                       sink_node, sink_channel)) 
     283 
     284        Parameters 
     285        ---------- 
     286        source_node : :class:`.SchemeNode` 
     287            Source node of the new link. 
     288        source_channel : :class:`OutputSignal` 
     289            Source channel of the new node. The instance must be from 
     290            `source_node.output_channels()` 
     291        sink_node : :class:`.SchemeNode` 
     292            Sink node of the new link. 
     293        sink_channel : :class:`InputSignal` 
     294            Sink channel of the new node. The instance must be from 
     295            `sink_node.input_channels()` 
     296 
     297        See also 
     298        -------- 
     299        SchemeLink, Scheme.add_link 
    192300 
    193301        """ 
     
    198306 
    199307    def remove_link(self, link): 
    200         """Remove a link from the scheme. 
     308        """ 
     309        Remove a link from the scheme. 
     310 
     311        Parameters 
     312        ---------- 
     313        link : :class:`.SchemeLink` 
     314            Link instance to remove. 
     315 
    201316        """ 
    202317        check_arg(link in self.__links, 
     
    213328    def check_connect(self, link): 
    214329        """ 
    215         Check if the link can be added to the scheme. 
     330        Check if the `link` can be added to the scheme. 
    216331 
    217332        Can raise: 
    218             - `TypeError` if link is not an instance of :class:`SchemeLink`. 
    219             - `SchemeCycleError` if the link would introduce a cycle 
    220             - `IncompatibleChannelTypeError` if the channel types are not 
    221                compatible 
    222             - `SinkChannelError` if a sink channel has a `Single` flag 
    223                specification and there is already connected. 
    224             - `DuplicatedLinkError` if a link duplicates an already present 
    225                link. 
     333            - :class:`TypeError` if `link` is not an instance of 
     334              :class:`.SchemeLink` 
     335            - :class:`SchemeCycleError` if the `link` would introduce a cycle 
     336            - :class:`IncompatibleChannelTypeError` if the channel types are 
     337              not compatible 
     338            - :class:`SinkChannelError` if a sink channel has a `Single` flag 
     339              specification and the channel is already connected. 
     340            - :class:`DuplicatedLinkError` if a `link` duplicates an already 
     341              present link. 
    226342 
    227343        """ 
     
    258374 
    259375    def creates_cycle(self, link): 
    260         """Would the `link` if added to the scheme introduce a cycle. 
     376        """ 
     377        Would the `link` if added to the scheme introduce a cycle. 
    261378        """ 
    262379        check_type(link, SchemeLink) 
     
    267384 
    268385    def compatible_channels(self, link): 
    269         """Do the channels in link have compatible types. 
     386        """ 
     387        Do the channels in `link` have compatible types. 
    270388        """ 
    271389        check_type(link, SchemeLink) 
     
    282400 
    283401    def upstream_nodes(self, start_node): 
    284         """Return a set of all nodes upstream from `start_node`. 
     402        """ 
     403        Return a set of all nodes upstream from `start_node`. 
    285404        """ 
    286405        visited = set() 
     
    298417 
    299418    def downstream_nodes(self, start_node): 
    300         """Return a set of all nodes downstream from `start_node`. 
     419        """ 
     420        Return a set of all nodes downstream from `start_node`. 
    301421        """ 
    302422        visited = set() 
     
    314434 
    315435    def is_ancestor(self, node, child): 
    316         """Return True if `node` is an ancestor node of `child` (is upstream 
     436        """ 
     437        Return True if `node` is an ancestor node of `child` (is upstream 
    317438        of the child in the workflow). Both nodes must be in the scheme. 
    318439 
     
    321442 
    322443    def children(self, node): 
    323         """Return a set of all children of `node`. 
     444        """ 
     445        Return a set of all children of `node`. 
    324446        """ 
    325447        return set(link.sink_node for link in self.output_links(node)) 
    326448 
    327449    def parents(self, node): 
    328         """Return a set if all parents of `node`. 
     450        """ 
     451        Return a set of all parents of `node`. 
    329452        """ 
    330453        return set(link.source_node for link in self.input_links(node)) 
    331454 
    332455    def input_links(self, node): 
    333         """Return all input links connected to the `node`. 
     456        """ 
     457        Return all input links connected to the `node` instance. 
    334458        """ 
    335459        return self.find_links(sink_node=node) 
    336460 
    337461    def output_links(self, node): 
    338         """Return all output links connected to the `node`. 
     462        """ 
     463        Return all output links connected to the `node` instance. 
    339464        """ 
    340465        return self.find_links(source_node=node) 
     
    355480 
    356481    def propose_links(self, source_node, sink_node): 
    357         """Return a list of ordered (`OutputSignal`, `InputSignal`, weight) 
    358         tuples that could be added to the scheme between `source_node` and 
    359         `sink_node`. 
     482        """ 
     483        Return a list of ordered (:class:`OutputSignal`, 
     484        :class:`InputSignal`, weight) tuples that could be added to 
     485        the scheme between `source_node` and `sink_node`. 
    360486 
    361487        .. note:: This can depend on the links already in the scheme. 
     
    398524 
    399525    def add_annotation(self, annotation): 
    400         """Add an annotation (`BaseSchemeAnnotation`) subclass to the scheme. 
     526        """ 
     527        Add an annotation (:class:`BaseSchemeAnnotation` subclass) instance 
     528        to the scheme. 
    401529 
    402530        """ 
     
    409537 
    410538    def remove_annotation(self, annotation): 
     539        """ 
     540        Remove the `annotation` instance from the scheme. 
     541        """ 
    411542        check_arg(annotation in self.__annotations, 
    412543                  "Annotation is not in the scheme.") 
     
    415546 
    416547    def save_to(self, stream, pretty=True): 
    417         """Save the scheme as an xml formated file to `stream` 
     548        """ 
     549        Save the scheme as an xml formated file to `stream` 
    418550        """ 
    419551        if isinstance(stream, basestring): 
     
    423555 
    424556    def load_from(self, stream): 
    425         """Load the scheme from xml formated stream. 
     557        """ 
     558        Load the scheme from xml formated stream. 
    426559        """ 
    427560        if self.__nodes or self.__links or self.__annotations: 
  • Orange/OrangeCanvas/scheme/utils.py

    r11101 r11367  
    66 
    77def name_lookup(qualified_name, globals={}): 
    8     """Return the object referenced by a qualified name (doted name). 
     8    """ 
     9    Return the object referenced by a qualified name (doted name). 
    910    """ 
    1011    module_name, class_name = qualified_name.rsplit(".", 1) 
     
    1415 
    1516def qualified_name(qualified_object): 
    16     """Return a qualifeid name for `qualified_obj` (type or function). 
     17    """ 
     18    Return a qualified name for `qualified_obj` (type or function). 
    1719    """ 
    1820    return "%s.%s" % (qualified_object.__module__, qualified_object.__name__) 
  • docs/index.rst

    r11070 r11366  
    1414 
    1515- :doc:`Widget development manual <extend-widgets/rst/index>` 
     16- :doc:`Canvas development reference <canvas/index>` 
    1617- `Wiki pages for developers <http://orange.biolab.si/trac>`_ 
    1718 
Note: See TracChangeset for help on using the changeset viewer.