nodeparamview: implement copy/pasting values

This commit is contained in:
itsmattkc
2022-05-10 17:20:22 -07:00
parent e6bbe08ba5
commit 8b87e376a0
7 changed files with 241 additions and 70 deletions
+76 -2
View File
@@ -21,6 +21,7 @@
#include "nodeparamview.h"
#include <QApplication>
#include <QMessageBox>
#include <QScrollArea>
#include <QScrollBar>
#include <QSplitter>
@@ -594,9 +595,82 @@ bool NodeParamView::Paste()
}
}
// FIXME: Pasting nodes
ProjectSerializer::Result res = ProjectSerializer::Paste(QStringLiteral("nodes"));
if (res.GetLoadedNodes().isEmpty()) {
return false;
}
return false;
// Determine if any nodes of this type are already in the editor
QMap<Node*, Node*> existing_nodes;
for (Node *n : res.GetLoadedNodes()) {
if (Node *existing = GetNodeWithID(n->id())) {
if (!existing_nodes.contains(existing)) {
existing_nodes.insert(existing, n);
}
}
}
QVector<Node*> nodes_to_paste_as_new = res.GetLoadedNodes();
MultiUndoCommand *command = new MultiUndoCommand();
if (!existing_nodes.empty()) {
QMessageBox b(this);
b.setWindowTitle(tr("Paste Nodes"));
QStringList node_names;
for (auto it=existing_nodes.cbegin(); it!=existing_nodes.cend(); it++) {
node_names.append(it.key()->GetLabelAndName());
}
b.setText(tr("The following node types already exist in this context:\n\n"
"%1\n\n"
"Do you wish to paste values onto the existing nodes or paste new nodes?").arg(node_names.join('\n')));
auto as_vals = b.addButton(tr("Paste As Values"), QMessageBox::YesRole);
auto as_nodes = b.addButton(tr("Paste As Nodes"), QMessageBox::NoRole);
auto cancel_btn = b.addButton(QMessageBox::Cancel);
Q_UNUSED(as_nodes)
b.exec();
if (b.clickedButton() == cancel_btn) {
// Delete pasted nodes and clear array so no later code runs
qDeleteAll(nodes_to_paste_as_new);
nodes_to_paste_as_new.clear();
} else if (b.clickedButton() == as_vals) {
// Filter out existing nodes
for (auto it=existing_nodes.cbegin(); it!=existing_nodes.cend(); it++) {
Node::CopyInputs(it.value(), it.key(), false, command);
nodes_to_paste_as_new.removeOne(it.value());
}
}
}
if (!nodes_to_paste_as_new.isEmpty()) {
Node::PositionMap map;
for (auto it=res.GetLoadData().properties.cbegin(); it!=res.GetLoadData().properties.cend(); it++) {
if (nodes_to_paste_as_new.contains(it.key())) {
Node::Position pos;
const QMap<QString, QString> &node_props = it.value();
pos.position.setX(node_props.value(QStringLiteral("x")).toDouble());
pos.position.setY(node_props.value(QStringLiteral("y")).toDouble());
pos.expanded = node_props.value(QStringLiteral("expanded")).toDouble();
map.insert(it.key(), pos);
}
}
}
Core::instance()->undo_stack()->pushIfHasChildren(command);
return true;
}
void NodeParamView::UpdateItemTime(const rational &time)
@@ -27,9 +27,8 @@ namespace olive {
NodeParamSetKeyframingCommand::NodeParamSetKeyframingCommand(const NodeInput &input, bool setting) :
input_(input),
setting_(setting)
new_setting_(setting)
{
Q_ASSERT(setting != input_.IsKeyframing());
}
Project *NodeParamSetKeyframingCommand::GetRelevantProject() const
@@ -39,12 +38,13 @@ Project *NodeParamSetKeyframingCommand::GetRelevantProject() const
void NodeParamSetKeyframingCommand::redo()
{
input_.node()->SetInputIsKeyframing(input_, setting_);
old_setting_ = input_.IsKeyframing();
input_.node()->SetInputIsKeyframing(input_, new_setting_);
}
void NodeParamSetKeyframingCommand::undo()
{
input_.node()->SetInputIsKeyframing(input_, !setting_);
input_.node()->SetInputIsKeyframing(input_, old_setting_);
}
NodeParamSetKeyframeValueCommand::NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& value) :
+39 -1
View File
@@ -41,7 +41,8 @@ protected:
private:
NodeInput input_;
bool setting_;
bool new_setting_;
bool old_setting_;
};
@@ -145,6 +146,43 @@ private:
};
class NodeParamSetSplitStandardValueCommand : public UndoCommand
{
public:
NodeParamSetSplitStandardValueCommand(const NodeInput& input, const SplitValue& new_value, const SplitValue& old_value) :
ref_(input),
old_value_(old_value),
new_value_(new_value)
{}
NodeParamSetSplitStandardValueCommand(const NodeInput& input, const SplitValue& value) :
NodeParamSetSplitStandardValueCommand(input, value, input.node()->GetSplitStandardValue(input.input()))
{}
virtual Project* GetRelevantProject() const override
{
return ref_.node()->project();
}
protected:
virtual void redo() override
{
ref_.node()->SetSplitStandardValue(ref_.input(), new_value_, ref_.element());
}
virtual void undo() override
{
ref_.node()->SetSplitStandardValue(ref_.input(), old_value_, ref_.element());
}
private:
NodeInput ref_;
SplitValue old_value_;
SplitValue new_value_;
};
class NodeParamArrayAppendCommand : public UndoCommand
{
public:
-12
View File
@@ -112,18 +112,6 @@ Project *NodeAddCommand::GetRelevantProject() const
return dynamic_cast<Project*>(graph_);
}
NodeCopyInputsCommand::NodeCopyInputsCommand(const Node *src, Node *dest, bool include_connections) :
src_(src),
dest_(dest),
include_connections_(include_connections)
{
}
void NodeCopyInputsCommand::redo()
{
Node::CopyInputs(src_, dest_, include_connections_);
}
void NodeRemoveAndDisconnectCommand::prepare()
{
command_ = new MultiUndoCommand();
+4 -22
View File
@@ -193,28 +193,6 @@ private:
};
class NodeCopyInputsCommand : public UndoCommand {
public:
NodeCopyInputsCommand(const Node* src,
Node* dest,
bool include_connections);
virtual Project* GetRelevantProject() const override {return nullptr;}
protected:
virtual void redo() override;
virtual void undo() override {}
private:
const Node* src_;
Node* dest_;
bool include_connections_;
};
class NodeLinkCommand : public UndoCommand {
public:
NodeLinkCommand(Node* a, Node* b, bool link) :
@@ -324,6 +302,10 @@ class NodeRenameCommand : public UndoCommand
{
public:
NodeRenameCommand() = default;
NodeRenameCommand(Node* node, const QString& new_name)
{
AddNode(node, new_name);
}
void AddNode(Node* node, const QString& new_name);