2929)
3030
3131from AnyQt .QtCore import (
32- Qt , QObject , QEvent , QSignalMapper , QRectF , QCoreApplication
33- )
32+ Qt , QObject , QEvent , QSignalMapper , QRectF , QCoreApplication ,
33+ QPoint )
3434
3535from AnyQt .QtCore import pyqtProperty as Property , pyqtSignal as Signal
3636
37+ from Orange .canvas .registry import WidgetDescription
3738from .suggestions import Suggestions
38- from ..registry .qt import whats_this_helper
39+ from ..registry .qt import whats_this_helper , QtWidgetRegistry
3940from ..gui .quickhelp import QuickHelpTipEvent
4041from ..gui .utils import message_information , disabled
4142from ..scheme import (
@@ -171,6 +172,8 @@ def __init__(self, parent=None, ):
171172 self .__linkMenu = QMenu (self .tr ("Link" ), self )
172173 self .__linkMenu .addAction (self .__linkEnableAction )
173174 self .__linkMenu .addSeparator ()
175+ self .__linkMenu .addAction (self .__nodeInsertAction )
176+ self .__linkMenu .addSeparator ()
174177 self .__linkMenu .addAction (self .__linkRemoveAction )
175178 self .__linkMenu .addAction (self .__linkResetAction )
176179
@@ -328,6 +331,13 @@ def color_icon(color):
328331 toolTip = self .tr ("Remove link." ),
329332 )
330333
334+ self .__nodeInsertAction = \
335+ QAction (self .tr ("Insert Widget" ), self ,
336+ objectName = "node-insert-action" ,
337+ triggered = self .__nodeInsert ,
338+ toolTip = self .tr ("Insert widget." ),
339+ )
340+
331341 self .__linkResetAction = \
332342 QAction (self .tr ("Reset Signals" ), self ,
333343 objectName = "link-reset-action" ,
@@ -346,6 +356,7 @@ def color_icon(color):
346356 self .__newArrowAnnotationAction ,
347357 self .__linkEnableAction ,
348358 self .__linkRemoveAction ,
359+ self .__nodeInsertAction ,
349360 self .__linkResetAction ,
350361 self .__duplicateSelectedAction ])
351362
@@ -867,6 +878,10 @@ def removeLink(self, link):
867878 command = commands .RemoveLinkCommand (self .__scheme , link )
868879 self .__undoStack .push (command )
869880
881+ def insertNode (self , link , new_node ):
882+ command = commands .InsertNodeCommand (self .__scheme , link , new_node )
883+ self .__undoStack .push (command )
884+
870885 def onNewLink (self , func ):
871886 """
872887 Runs function when new link is added to current scheme.
@@ -1594,6 +1609,52 @@ def __linkReset(self):
15941609 )
15951610 action .edit_links ()
15961611
1612+ def __nodeInsert (self ):
1613+ """
1614+ Node insert was requested from the context menu.
1615+ """
1616+ if not self .__contextMenuTarget :
1617+ return
1618+
1619+ original_link = self .__contextMenuTarget
1620+ source_node = original_link .source_node
1621+ sink_node = original_link .sink_node
1622+
1623+ def is_compatible (source , sink ):
1624+ return any (scheme .compatible_channels (output , input ) \
1625+ for output in source .outputs \
1626+ for input in sink .inputs )
1627+
1628+ def filterFunc (index ):
1629+ new_node_desc = index .data (QtWidgetRegistry .WIDGET_DESC_ROLE )
1630+ if isinstance (new_node_desc , WidgetDescription ):
1631+ return is_compatible (source_node .description , new_node_desc ) and \
1632+ is_compatible (new_node_desc , sink_node .description )
1633+ else :
1634+ return False
1635+
1636+ x = (source_node .position [0 ] + sink_node .position [0 ]) / 2
1637+ y = (source_node .position [1 ] + sink_node .position [1 ]) / 2
1638+
1639+ menu = self .quickMenu ()
1640+ menu .setFilterFunc (filterFunc )
1641+ menu .setSortingFunc (None )
1642+
1643+ view = self .view ()
1644+ try :
1645+ action = menu .exec_ (view .mapToGlobal (view .mapFromScene (QPoint (x , y ))))
1646+ finally :
1647+ menu .setFilterFunc (None )
1648+
1649+ if action :
1650+ item = action .property ("item" )
1651+ desc = item .data (QtWidgetRegistry .WIDGET_DESC_ROLE )
1652+ new_node = self .newNodeHelper (desc , position = (x , y ))
1653+ else :
1654+ return
1655+
1656+ self .insertNode (original_link , new_node )
1657+
15971658 def __duplicateSelected (self ):
15981659 """
15991660 Duplicate currently selected nodes.
0 commit comments