Skip to content

Commit

Permalink
create guiApp.pasteNodes(optional group) python function (#674)
Browse files Browse the repository at this point in the history
* create GuiApp.pasteNodes() python function

This function paste the nodes in the clipboard.
It will be used to reconnect the pasted nodes to the previously selected node as Nuke does. (good time saver)

Known limitation: the nodes are pasted in a very random place probably related to cursor position.

Improvements to be done: ability to paste inside a group
  • Loading branch information
bonalex01dev committed Oct 6, 2021
1 parent d31abad commit cdbeae1
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,6 @@ Gui/Resources/etc/fonts/fonts.conf


Project-xcode.xcodeproj/xcshareddata/xcschemes/Natron.xcscheme

# QTCreator
*QtCreator.*
70 changes: 70 additions & 0 deletions Gui/NatronGui/guiapp_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,75 @@ static PyObject* Sbk_GuiAppFunc_copySelectedNodes(PyObject* self, PyObject* args
return 0;
}

static PyObject* Sbk_GuiAppFunc_pasteNodes(PyObject* self, PyObject* args, PyObject* kwds)
{
::GuiApp* cppSelf = 0;
SBK_UNUSED(cppSelf)
if (!Shiboken::Object::isValid(self))
return 0;
cppSelf = ((::GuiApp*)Shiboken::Conversions::cppPointer(SbkNatronGuiTypes[SBK_GUIAPP_IDX], (SbkObject*)self));
int overloadId = -1;
PythonToCppFunc pythonToCpp[] = { 0 };
SBK_UNUSED(pythonToCpp)
int numNamedArgs = (kwds ? PyDict_Size(kwds) : 0);
int numArgs = PyTuple_GET_SIZE(args);
PyObject* pyArgs[] = {0};

// invalid argument lengths
if (numArgs + numNamedArgs > 1) {
PyErr_SetString(PyExc_TypeError, "NatronGui.GuiApp.pasteNodes(): too many arguments");
return 0;
}

if (!PyArg_ParseTuple(args, "|O:pasteNodes", &(pyArgs[0])))
return 0;


// Overloaded function decisor
// 0: pasteNodes(Group*)
if (numArgs == 0) {
overloadId = 0; // pasteNodes(Group*)
} else if ((pythonToCpp[0] = Shiboken::Conversions::isPythonToCppPointerConvertible((SbkObjectType*)SbkNatronEngineTypes[SBK_GROUP_IDX], (pyArgs[0])))) {
overloadId = 0; // pasteNodes(Group*)
}

// Function signature not found.
if (overloadId == -1) goto Sbk_GuiAppFunc_pasteNodes_TypeError;

// Call function/method
{
if (kwds) {
PyObject* value = PyDict_GetItemString(kwds, "group");
if (value && pyArgs[0]) {
PyErr_SetString(PyExc_TypeError, "NatronGui.GuiApp.pasteNodes(): got multiple values for keyword argument 'group'.");
return 0;
} else if (value) {
pyArgs[0] = value;
if (!(pythonToCpp[0] = Shiboken::Conversions::isPythonToCppPointerConvertible((SbkObjectType*)SbkNatronEngineTypes[SBK_GROUP_IDX], (pyArgs[0]))))
goto Sbk_GuiAppFunc_pasteNodes_TypeError;
}
}
if (!Shiboken::Object::isValid(pyArgs[0]))
return 0;
::Group* cppArg0 = 0;
if (pythonToCpp[0]) pythonToCpp[0](pyArgs[0], &cppArg0);

if (!PyErr_Occurred()) {
// pasteNodes(Group*)
cppSelf->pasteNodes(cppArg0);
}
}

if (PyErr_Occurred()) {
return 0;
}
Py_RETURN_NONE;

Sbk_GuiAppFunc_pasteNodes_TypeError:
const char* overloads[] = {"NatronEngine.Group = None", 0};
Shiboken::setErrorAboutWrongArguments(args, "NatronGui.GuiApp.pasteNodes", overloads);
return 0;
}

static PyObject* Sbk_GuiAppFunc_selectNode(PyObject* self, PyObject* args)
{
Expand Down Expand Up @@ -1452,6 +1521,7 @@ static PyMethodDef Sbk_GuiApp_methods[] = {
{"saveSequenceDialog", (PyCFunction)Sbk_GuiAppFunc_saveSequenceDialog, METH_VARARGS|METH_KEYWORDS},
{"selectAllNodes", (PyCFunction)Sbk_GuiAppFunc_selectAllNodes, METH_VARARGS|METH_KEYWORDS},
{"copySelectedNodes", (PyCFunction)Sbk_GuiAppFunc_copySelectedNodes, METH_VARARGS|METH_KEYWORDS},
{"pasteNodes", (PyCFunction)Sbk_GuiAppFunc_pasteNodes, METH_VARARGS|METH_KEYWORDS},
{"selectNode", (PyCFunction)Sbk_GuiAppFunc_selectNode, METH_VARARGS},
{"setSelection", (PyCFunction)Sbk_GuiAppFunc_setSelection, METH_O},
{"unregisterPythonPanel", (PyCFunction)Sbk_GuiAppFunc_unregisterPythonPanel, METH_O},
Expand Down
30 changes: 30 additions & 0 deletions Gui/PyGuiApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,36 @@ GuiApp::copySelectedNodes(Group* group)
graph->copySelectedNodes();
}

void
GuiApp::pasteNodes(Group* group)
{
if ( appPTR->isBackground() ) {
return;
}
NodeGraph* graph = 0;
NodeCollectionPtr collection;
NodeGroup* isGroup = 0;
if (group) {
collection = group->getInternalCollection();
if (collection) {
isGroup = dynamic_cast<NodeGroup*>( collection.get() );
if (isGroup) {
graph = dynamic_cast<NodeGraph*>( isGroup->getNodeGraph() );
}
}
} else {
graph = getInternalGuiApp()->getGui()->getLastSelectedGraph();
}
if (!graph) {
graph = getInternalGuiApp()->getGui()->getNodeGraph();
}
assert(graph);
if (!graph) {
throw std::logic_error("");
}
graph->pasteNodeClipBoards();
}

void
GuiApp::deselectNode(Effect* effect)
{
Expand Down
1 change: 1 addition & 0 deletions Gui/PyGuiApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class GuiApp
void setSelection(const std::list<Effect*>& nodes);
void selectAllNodes(Group* group = 0);
void copySelectedNodes(Group* group = 0);
void pasteNodes(Group* group = 0);
void deselectNode(Effect* effect);
void clearSelection(Group* group = 0);

Expand Down

0 comments on commit cdbeae1

Please sign in to comment.