mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-04-30 18:57:53 +02:00
Add node to graph with Ctrl+V if valid node content is in the clipboard
Attempt to paste the clipboard's content in the graph when Ctrl+V is pressed. If the clipboard contains a valid node description, add the corresponding node to the graph. Otherwise, do nothing.
This commit is contained in:
parent
751bad96c6
commit
ddda62a652
5 changed files with 80 additions and 0 deletions
|
@ -396,6 +396,15 @@ class Graph(BaseObject):
|
||||||
|
|
||||||
return duplicates
|
return duplicates
|
||||||
|
|
||||||
|
def pasteNode(self, nodeType, **kwargs):
|
||||||
|
name = self._createUniqueNodeName(nodeType)
|
||||||
|
node = None
|
||||||
|
with GraphModification(self):
|
||||||
|
node = Node(nodeType, **kwargs)
|
||||||
|
self._addNode(node, name)
|
||||||
|
self._applyExpr()
|
||||||
|
return node
|
||||||
|
|
||||||
def outEdges(self, attribute):
|
def outEdges(self, attribute):
|
||||||
""" Return the list of edges starting from the given attribute """
|
""" Return the list of edges starting from the given attribute """
|
||||||
# type: (Attribute,) -> [Edge]
|
# type: (Attribute,) -> [Edge]
|
||||||
|
|
|
@ -195,6 +195,26 @@ class DuplicateNodesCommand(GraphCommand):
|
||||||
self.graph.removeNode(duplicate)
|
self.graph.removeNode(duplicate)
|
||||||
|
|
||||||
|
|
||||||
|
class PasteNodeCommand(GraphCommand):
|
||||||
|
"""
|
||||||
|
Handle node pasting in a Graph.
|
||||||
|
"""
|
||||||
|
def __init__(self, graph, nodeType, parent=None, **kwargs):
|
||||||
|
super(PasteNodeCommand, self).__init__(graph, parent)
|
||||||
|
self.nodeType = nodeType
|
||||||
|
self.nodeName = None
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
def redoImpl(self):
|
||||||
|
node = self.graph.pasteNode(self.nodeType, **self.kwargs)
|
||||||
|
self.nodeName = node.name
|
||||||
|
self.setText("Paste Node {}".format(self.nodeName))
|
||||||
|
return node
|
||||||
|
|
||||||
|
def undoImpl(self):
|
||||||
|
self.graph.removeNode(self.nodeName)
|
||||||
|
|
||||||
|
|
||||||
class SetAttributeCommand(GraphCommand):
|
class SetAttributeCommand(GraphCommand):
|
||||||
def __init__(self, graph, attribute, value, parent=None):
|
def __init__(self, graph, attribute, value, parent=None):
|
||||||
super(SetAttributeCommand, self).__init__(graph, parent)
|
super(SetAttributeCommand, self).__init__(graph, parent)
|
||||||
|
|
|
@ -15,6 +15,10 @@ class ClipboardHelper(QObject):
|
||||||
def setText(self, value):
|
def setText(self, value):
|
||||||
self._clipboard.setText(value)
|
self._clipboard.setText(value)
|
||||||
|
|
||||||
|
@Slot(result=str)
|
||||||
|
def getText(self):
|
||||||
|
return self._clipboard.text()
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._clipboard.clear()
|
self._clipboard.clear()
|
||||||
|
|
|
@ -766,6 +766,44 @@ class UIGraph(QObject):
|
||||||
return json.dumps(node, indent=4)
|
return json.dumps(node, indent=4)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@Slot(str)
|
||||||
|
def pasteNode(self, clipboardContent):
|
||||||
|
"""
|
||||||
|
Parse the content of the clipboard to see whether it contains
|
||||||
|
a valid node description. If that is the case, the node described
|
||||||
|
in the clipboard is built with the available information.
|
||||||
|
Otherwise, nothing is done.
|
||||||
|
|
||||||
|
This function does not need to be preceded by a call to "copyNodeContent".
|
||||||
|
Any clipboard content that contains at least a node type with a valid JSON
|
||||||
|
formatting (dictionary form with double quotes around the keys and values)
|
||||||
|
can be used to generate a node.
|
||||||
|
|
||||||
|
For example, it is enough to have:
|
||||||
|
{"nodeType":"CameraInit"}
|
||||||
|
in the clipboard to create a default CameraInit node.
|
||||||
|
"""
|
||||||
|
if not clipboardContent:
|
||||||
|
return
|
||||||
|
d = {}
|
||||||
|
try:
|
||||||
|
d = json.loads(clipboardContent)
|
||||||
|
except ValueError as e:
|
||||||
|
raise ValueError(e)
|
||||||
|
|
||||||
|
if not isinstance(d, dict):
|
||||||
|
raise ValueError("The clipboard does not contain a valid node. Cannot paste it.")
|
||||||
|
|
||||||
|
nodeType = d.get("nodeType", None)
|
||||||
|
if not nodeType:
|
||||||
|
raise ValueError("The clipboard does not contain a valid node. Cannot paste it.")
|
||||||
|
|
||||||
|
attributes = {}
|
||||||
|
attributes.update(d.get("inputs", {}))
|
||||||
|
attributes.update(d.get("outputs", {}))
|
||||||
|
|
||||||
|
self.push(commands.PasteNodeCommand(self._graph, nodeType, **attributes))
|
||||||
|
|
||||||
undoStack = Property(QObject, lambda self: self._undoStack, constant=True)
|
undoStack = Property(QObject, lambda self: self._undoStack, constant=True)
|
||||||
graphChanged = Signal()
|
graphChanged = Signal()
|
||||||
graph = Property(Graph, lambda self: self._graph, notify=graphChanged)
|
graph = Property(Graph, lambda self: self._graph, notify=graphChanged)
|
||||||
|
|
|
@ -85,6 +85,12 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Paste content of clipboard to graph editor and create new node if valid
|
||||||
|
function pasteNode()
|
||||||
|
{
|
||||||
|
var copiedContent = Clipboard.getText()
|
||||||
|
uigraph.pasteNode(copiedContent)
|
||||||
|
}
|
||||||
|
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
if (event.key === Qt.Key_F)
|
if (event.key === Qt.Key_F)
|
||||||
|
@ -100,6 +106,9 @@ Item {
|
||||||
if (event.key === Qt.Key_C)
|
if (event.key === Qt.Key_C)
|
||||||
if (event.modifiers == Qt.ControlModifier)
|
if (event.modifiers == Qt.ControlModifier)
|
||||||
copyNode()
|
copyNode()
|
||||||
|
if (event.key === Qt.Key_V)
|
||||||
|
if (event.modifiers == Qt.ControlModifier)
|
||||||
|
pasteNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
Loading…
Add table
Reference in a new issue