Skip to content

Commit bea91e9

Browse files
authored
Merge pull request #383 from jchanvfx/port_connection_signal_fix_#373
emit signals from undo fix #373
2 parents 4a645b4 + 8e2a625 commit bea91e9

File tree

4 files changed

+132
-71
lines changed

4 files changed

+132
-71
lines changed

NodeGraphQt/base/commands.py

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -165,54 +165,73 @@ class NodeAddedCmd(QtWidgets.QUndoCommand):
165165
graph (NodeGraphQt.NodeGraph): node graph.
166166
node (NodeGraphQt.NodeObject): node.
167167
pos (tuple(float, float)): initial node position (optional).
168+
emit_signal (bool): emit node creation signals. (default: True)
168169
"""
169170

170-
def __init__(self, graph, node, pos=None):
171+
def __init__(self, graph, node, pos=None, emit_signal=True):
171172
QtWidgets.QUndoCommand.__init__(self)
172173
self.setText('added node')
173-
self.viewer = graph.viewer()
174-
self.model = graph.model
174+
self.graph = graph
175175
self.node = node
176176
self.pos = pos
177+
self.emit_signal = emit_signal
177178

178179
def undo(self):
180+
node_id = self.node.id
179181
self.pos = self.pos or self.node.pos()
180-
self.model.nodes.pop(self.node.id)
182+
self.graph.model.nodes.pop(self.node.id)
181183
self.node.view.delete()
182184

185+
if self.emit_signal:
186+
self.graph.nodes_deleted.emit([node_id])
187+
183188
def redo(self):
184-
self.model.nodes[self.node.id] = self.node
185-
self.viewer.add_node(self.node.view, self.pos)
189+
self.graph.model.nodes[self.node.id] = self.node
190+
self.graph.viewer().add_node(self.node.view, self.pos)
186191

187192
# node width & height is calculated when it's added to the scene,
188193
# so we have to update the node model here.
189194
self.node.model.width = self.node.view.width
190195
self.node.model.height = self.node.view.height
191196

197+
if self.emit_signal:
198+
self.graph.node_created.emit(self.node)
199+
192200

193-
class NodeRemovedCmd(QtWidgets.QUndoCommand):
201+
class NodesRemovedCmd(QtWidgets.QUndoCommand):
194202
"""
195203
Node deleted command.
196204
197205
Args:
198206
graph (NodeGraphQt.NodeGraph): node graph.
199-
node (NodeGraphQt.BaseNode or NodeGraphQt.NodeObject): node.
207+
nodes (list[NodeGraphQt.BaseNode or NodeGraphQt.NodeObject]): nodes.
208+
emit_signal (bool): emit node deletion signals. (default: True)
200209
"""
201210

202-
def __init__(self, graph, node):
211+
def __init__(self, graph, nodes, emit_signal=True):
203212
QtWidgets.QUndoCommand.__init__(self)
204-
self.setText('deleted node')
205-
self.scene = graph.scene()
206-
self.model = graph.model
207-
self.node = node
213+
self.setText('deleted node(s)')
214+
self.graph = graph
215+
self.nodes = nodes
216+
self.emit_signal = emit_signal
208217

209218
def undo(self):
210-
self.model.nodes[self.node.id] = self.node
211-
self.scene.addItem(self.node.view)
219+
for node in self.nodes:
220+
self.graph.model.nodes[node.id] = node
221+
self.graph.scene().addItem(node.view)
222+
223+
if self.emit_signal:
224+
self.graph.node_created.emit(node)
212225

213226
def redo(self):
214-
self.model.nodes.pop(self.node.id)
215-
self.node.view.delete()
227+
node_ids = []
228+
for node in self.nodes:
229+
node_ids.append(node.id)
230+
self.graph.model.nodes.pop(node.id)
231+
node.view.delete()
232+
233+
if self.emit_signal:
234+
self.graph.nodes_deleted.emit(node_ids)
216235

217236

218237
class NodeInputConnectedCmd(QtWidgets.QUndoCommand):
@@ -276,12 +295,14 @@ class PortConnectedCmd(QtWidgets.QUndoCommand):
276295
Args:
277296
src_port (NodeGraphQt.Port): source port.
278297
trg_port (NodeGraphQt.Port): target port.
298+
emit_signal (bool): emit port connection signals.
279299
"""
280300

281-
def __init__(self, src_port, trg_port):
301+
def __init__(self, src_port, trg_port, emit_signal):
282302
QtWidgets.QUndoCommand.__init__(self)
283303
self.source = src_port
284304
self.target = trg_port
305+
self.emit_signal = emit_signal
285306

286307
def undo(self):
287308
src_model = self.source.model
@@ -303,6 +324,13 @@ def undo(self):
303324

304325
self.source.view.disconnect_from(self.target.view)
305326

327+
# emit "port_disconnected" signal from the parent graph.
328+
if self.emit_signal:
329+
ports = {p.type_(): p for p in [self.source, self.target]}
330+
graph = self.source.node().graph
331+
graph.port_disconnected.emit(ports[PortTypeEnum.IN.value],
332+
ports[PortTypeEnum.OUT.value])
333+
306334
def redo(self):
307335
src_model = self.source.model
308336
trg_model = self.target.model
@@ -314,6 +342,13 @@ def redo(self):
314342

315343
self.source.view.connect_to(self.target.view)
316344

345+
# emit "port_connected" signal from the parent graph.
346+
if self.emit_signal:
347+
ports = {p.type_(): p for p in [self.source, self.target]}
348+
graph = self.source.node().graph
349+
graph.port_connected.emit(ports[PortTypeEnum.IN.value],
350+
ports[PortTypeEnum.OUT.value])
351+
317352

318353
class PortDisconnectedCmd(QtWidgets.QUndoCommand):
319354
"""
@@ -322,12 +357,14 @@ class PortDisconnectedCmd(QtWidgets.QUndoCommand):
322357
Args:
323358
src_port (NodeGraphQt.Port): source port.
324359
trg_port (NodeGraphQt.Port): target port.
360+
emit_signal (bool): emit port connection signals.
325361
"""
326362

327-
def __init__(self, src_port, trg_port):
363+
def __init__(self, src_port, trg_port, emit_signal):
328364
QtWidgets.QUndoCommand.__init__(self)
329365
self.source = src_port
330366
self.target = trg_port
367+
self.emit_signal = emit_signal
331368

332369
def undo(self):
333370
src_model = self.source.model
@@ -340,6 +377,13 @@ def undo(self):
340377

341378
self.source.view.connect_to(self.target.view)
342379

380+
# emit "port_connected" signal from the parent graph.
381+
if self.emit_signal:
382+
ports = {p.type_(): p for p in [self.source, self.target]}
383+
graph = self.source.node().graph
384+
graph.port_connected.emit(ports[PortTypeEnum.IN.value],
385+
ports[PortTypeEnum.OUT.value])
386+
343387
def redo(self):
344388
src_model = self.source.model
345389
trg_model = self.target.model
@@ -360,6 +404,13 @@ def redo(self):
360404

361405
self.source.view.disconnect_from(self.target.view)
362406

407+
# emit "port_disconnected" signal from the parent graph.
408+
if self.emit_signal:
409+
ports = {p.type_(): p for p in [self.source, self.target]}
410+
graph = self.source.node().graph
411+
graph.port_disconnected.emit(ports[PortTypeEnum.IN.value],
412+
ports[PortTypeEnum.OUT.value])
413+
363414

364415
class PortLockedCmd(QtWidgets.QUndoCommand):
365416
"""

NodeGraphQt/base/graph.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from Qt import QtCore, QtWidgets
99

1010
from NodeGraphQt.base.commands import (NodeAddedCmd,
11-
NodeRemovedCmd,
11+
NodesRemovedCmd,
1212
NodeMovedCmd,
1313
PortConnectedCmd)
1414
from NodeGraphQt.base.factory import NodeFactory
@@ -1255,7 +1255,9 @@ def format_color(clr):
12551255

12561256
node.update()
12571257

1258-
undo_cmd = NodeAddedCmd(self, node, node.model.pos)
1258+
undo_cmd = NodeAddedCmd(
1259+
self, node, pos=node.model.pos, emit_signal=True
1260+
)
12591261
if push_undo:
12601262
undo_label = 'create node: "{}"'.format(node.NODE_NAME)
12611263
self._undo_stack.beginMacro(undo_label)
@@ -1266,10 +1268,10 @@ def format_color(clr):
12661268
else:
12671269
for n in self.selected_nodes():
12681270
n.set_property('selected', False, push_undo=False)
1269-
NodeAddedCmd(self, node, node.model.pos).redo()
1271+
undo_cmd.redo()
12701272

1271-
self.node_created.emit(node)
12721273
return node
1274+
12731275
raise NodeCreationError('Can\'t find node: "{}"'.format(node_type))
12741276

12751277
def add_node(self, node, pos=None, selected=True, push_undo=True):
@@ -1341,14 +1343,15 @@ def add_node(self, node, pos=None, selected=True, push_undo=True):
13411343
# update method must be called before it's been added to the viewer.
13421344
node.update()
13431345

1346+
undo_cmd = NodeAddedCmd(self, node, pos=pos, emit_signal=False)
13441347
if push_undo:
13451348
self._undo_stack.beginMacro('add node: "{}"'.format(node.name()))
1346-
self._undo_stack.push(NodeAddedCmd(self, node, pos))
1349+
self._undo_stack.push(undo_cmd)
13471350
if selected:
13481351
node.set_selected(True)
13491352
self._undo_stack.endMacro()
13501353
else:
1351-
NodeAddedCmd(self, node, pos).redo()
1354+
undo_cmd.redo()
13521355

13531356
def delete_node(self, node, push_undo=True):
13541357
"""
@@ -1382,13 +1385,12 @@ def delete_node(self, node, push_undo=True):
13821385
if isinstance(node, GroupNode) and node.is_expanded:
13831386
node.collapse()
13841387

1388+
undo_cmd = NodesRemovedCmd(self, [node], emit_signal=True)
13851389
if push_undo:
1386-
self._undo_stack.push(NodeRemovedCmd(self, node))
1390+
self._undo_stack.push(undo_cmd)
13871391
self._undo_stack.endMacro()
13881392
else:
1389-
NodeRemovedCmd(self, node).redo()
1390-
1391-
self.nodes_deleted.emit([node_id])
1393+
undo_cmd.redo()
13921394

13931395
def remove_node(self, node, push_undo=True):
13941396
"""
@@ -1425,11 +1427,12 @@ def remove_node(self, node, push_undo=True):
14251427
push_undo=push_undo)
14261428
p.clear_connections(push_undo=push_undo)
14271429

1430+
undo_cmd = NodesRemovedCmd(self, [node], emit_signal=False)
14281431
if push_undo:
1429-
self._undo_stack.push(NodeRemovedCmd(self, node))
1432+
self._undo_stack.push(undo_cmd)
14301433
self._undo_stack.endMacro()
14311434
else:
1432-
NodeRemovedCmd(self, node).redo()
1435+
undo_cmd.redo()
14331436

14341437
def delete_nodes(self, nodes, push_undo=True):
14351438
"""
@@ -1468,12 +1471,14 @@ def delete_nodes(self, nodes, push_undo=True):
14681471
connected_ports=False,
14691472
push_undo=push_undo)
14701473
p.clear_connections(push_undo=push_undo)
1471-
if push_undo:
1472-
self._undo_stack.push(NodeRemovedCmd(self, node))
1473-
else:
1474-
NodeRemovedCmd(self, node).redo()
1474+
1475+
undo_cmd = NodesRemovedCmd(self, nodes, emit_signal=True)
14751476
if push_undo:
1477+
self._undo_stack.push(undo_cmd)
14761478
self._undo_stack.endMacro()
1479+
else:
1480+
undo_cmd.redo()
1481+
14771482
self.nodes_deleted.emit(node_ids)
14781483

14791484
def extract_nodes(self, nodes, push_undo=True, prompt_warning=True):

0 commit comments

Comments
 (0)