diff --git a/app/node/connectable.cpp b/app/node/connectable.cpp index 24d4ba530..7fed464b1 100644 --- a/app/node/connectable.cpp +++ b/app/node/connectable.cpp @@ -31,7 +31,7 @@ void NodeConnectable::ConnectEdge(Node *output, NodeInput *input, int element) // Connection exists if (std::find(output->output_connections_.begin(), output->output_connections_.end(), conn_to_in) != output->output_connections_.end()) { - qDebug() << "Ignored connect that already exists"; + qDebug() << "Ignored connect that already exists:" << output << input->parent() << input->id() << element; return; } @@ -53,7 +53,7 @@ void NodeConnectable::DisconnectEdge(Node *output, NodeInput *input, int element // Connection exists if (std::find(output->output_connections_.begin(), output->output_connections_.end(), conn_to_in) == output->output_connections_.end()) { - qDebug() << "Ignored disconnect that doesn't exist"; + qDebug() << "Ignored disconnect that doesn't exist:" << output << input->parent() << input->id() << element; return; } diff --git a/app/node/node.cpp b/app/node/node.cpp index 33c45de84..f36e6e40e 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -193,35 +193,6 @@ QBrush Node::brush(qreal top, qreal bottom) const } } -void Node::RemoveNodesAndExclusiveDependencies(Node *node, QUndoCommand *command) -{ - // Remove main node - RemoveNodeAndDisconnect(node, command); - - // Remove exclusive dependencies - QVector deps = node->GetExclusiveDependencies(); - foreach (Node* d, deps) { - RemoveNodeAndDisconnect(d, command); - } -} - -void Node::RemoveNodeAndDisconnect(Node *node, QUndoCommand *command) -{ - // Disconnect everything - foreach (const InputConnection& conn, node->output_connections()) { - new NodeEdgeRemoveCommand(node, conn.input, conn.element, command); - } - - foreach (NodeInput* input, node->inputs_) { - for (auto it=input->edges().cbegin(); it!=input->edges().cend(); it++) { - new NodeEdgeRemoveCommand(it->second, input, it->first, command); - } - } - - // Remove node - new NodeRemoveCommand(node, command); -} - NodeValueTable Node::Value(NodeValueDatabase &value) const { return value.Merge(); diff --git a/app/node/node.h b/app/node/node.h index 792b34313..779599c49 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -193,10 +193,6 @@ public: return inputs_; } - static void RemoveNodesAndExclusiveDependencies(Node* node, QUndoCommand* command); - - static void RemoveNodeAndDisconnect(Node* node, QUndoCommand* command); - /** * @brief Return the index of a parameter * @return Parameter index or -1 if this parameter is not part of this Node diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp index 785884cae..87bbb66a0 100644 --- a/app/widget/nodeview/nodeview.cpp +++ b/app/widget/nodeview/nodeview.cpp @@ -139,7 +139,7 @@ void NodeView::DeleteSelected() if (!selected_nodes.isEmpty()) { foreach (Node* node, selected_nodes) { - Node::RemoveNodeAndDisconnect(node, command); + new NodeRemoveAndDisconnectCommand(node, command); } } } diff --git a/app/widget/nodeview/nodeviewundo.cpp b/app/widget/nodeview/nodeviewundo.cpp index c4129dfdb..370657cd2 100644 --- a/app/widget/nodeview/nodeviewundo.cpp +++ b/app/widget/nodeview/nodeviewundo.cpp @@ -21,6 +21,7 @@ #include "nodeviewundo.h" #include "project/item/sequence/sequence.h" +#include "widget/timelinewidget/timelineundo.h" namespace olive { @@ -94,28 +95,6 @@ Project *NodeAddCommand::GetRelevantProject() const return graph_->project(); } -NodeRemoveCommand::NodeRemoveCommand(Node *node, QUndoCommand *parent) : - UndoCommand(parent), - graph_(node->parent()), - node_(node) -{ -} - -void NodeRemoveCommand::redo_internal() -{ - node_->setParent(&memory_manager_); -} - -void NodeRemoveCommand::undo_internal() -{ - node_->setParent(graph_); -} - -Project *NodeRemoveCommand::GetRelevantProject() const -{ - return static_cast(graph_)->project(); -} - NodeCopyInputsCommand::NodeCopyInputsCommand(Node *src, Node *dest, bool include_connections, QUndoCommand *parent) : QUndoCommand(parent), src_(src), @@ -129,4 +108,26 @@ void NodeCopyInputsCommand::redo() Node::CopyInputs(src_, dest_, include_connections_); } +void NodeRemoveAndDisconnectCommand::prep() +{ + command_ = new QUndoCommand(); + + // If this is a block, remove all links + Block* block = dynamic_cast(node_); + if (block) { + new BlockUnlinkAllCommand(block, command_); + } + + // Disconnect everything + foreach (const Node::InputConnection& conn, node_->edges()) { + new NodeEdgeRemoveCommand(node_, conn.input, conn.element, command_); + } + + foreach (NodeInput* input, node_->inputs()) { + for (auto it=input->edges().cbegin(); it!=input->edges().cend(); it++) { + new NodeEdgeRemoveCommand(it->second, input, it->first, command_); + } + } +} + } diff --git a/app/widget/nodeview/nodeviewundo.h b/app/widget/nodeview/nodeviewundo.h index aa5ee9b87..c440827c3 100644 --- a/app/widget/nodeview/nodeviewundo.h +++ b/app/widget/nodeview/nodeviewundo.h @@ -90,22 +90,124 @@ private: Node* node_; }; -class NodeRemoveCommand : public UndoCommand { +class NodeRemoveAndDisconnectCommand : public UndoCommand { public: - NodeRemoveCommand(Node* node, - QUndoCommand* parent = nullptr); + NodeRemoveAndDisconnectCommand(Node* node, QUndoCommand* parent = nullptr) : + UndoCommand(parent), + node_(node), + graph_(nullptr), + command_(nullptr), + prepped_(false) + { + } - virtual Project* GetRelevantProject() const override; + virtual ~NodeRemoveAndDisconnectCommand() override + { + delete command_; + } + + virtual Project* GetRelevantProject() const override + { + if (graph_) { + return graph_->project(); + } else { + return node_->parent()->project(); + } + } protected: - virtual void redo_internal() override; - virtual void undo_internal() override; + virtual void redo_internal() override + { + if (!prepped_) { + prep(); + prepped_ = true; + } + + command_->redo(); + + graph_ = node_->parent(); + node_->setParent(&memory_manager_); + } + + virtual void undo_internal() override + { + node_->setParent(graph_); + graph_ = nullptr; + + command_->undo(); + } private: + void prep(); + QObject memory_manager_; - NodeGraph* graph_; Node* node_; + NodeGraph* graph_; + + QUndoCommand* command_; + + bool prepped_; + +}; + +class NodeRemoveWithExclusiveDependenciesAndDisconnect : public UndoCommand { +public: + NodeRemoveWithExclusiveDependenciesAndDisconnect(Node* node, QUndoCommand* parent = nullptr) : + UndoCommand(parent), + node_(node), + command_(nullptr), + prepped_(false) + { + } + + virtual ~NodeRemoveWithExclusiveDependenciesAndDisconnect() override + { + delete command_; + } + + virtual Project* GetRelevantProject() const override + { + if (command_) { + return static_cast(command_->child(0))->GetRelevantProject(); + } else { + return node_->parent()->project(); + } + } + +protected: + virtual void redo_internal() override + { + if (!prepped_) { + prep(); + prepped_ = true; + } + + command_->redo(); + } + + virtual void undo_internal() override + { + command_->undo(); + } + +private: + void prep() + { + command_ = new QUndoCommand(); + + new NodeRemoveAndDisconnectCommand(node_, command_); + + // Remove exclusive dependencies + QVector deps = node_->GetExclusiveDependencies(); + foreach (Node* d, deps) { + new NodeRemoveAndDisconnectCommand(d, command_); + } + } + + Node* node_; + QUndoCommand* command_; + bool prepped_; }; diff --git a/app/widget/timelinewidget/timelineundo.h b/app/widget/timelinewidget/timelineundo.h index 16364bdca..9da4d496b 100644 --- a/app/widget/timelinewidget/timelineundo.h +++ b/app/widget/timelinewidget/timelineundo.h @@ -48,9 +48,7 @@ inline bool NodeCanBeRemoved(Node* n) inline QUndoCommand* CreateRemoveCommand(Node* n) { - QUndoCommand* command = new QUndoCommand(); - Node::RemoveNodesAndExclusiveDependencies(n, command); - return command; + return new NodeRemoveWithExclusiveDependenciesAndDisconnect(n); } inline QUndoCommand* CreateAndRunRemoveCommand(Node* n) diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 785617728..863b7eb89 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -435,7 +435,7 @@ void TimelineWidget::ReplaceBlocksWithGaps(const QVector &blocks, new TrackReplaceBlockWithGapCommand(original_track, b, command); if (remove_from_graph) { - Node::RemoveNodesAndExclusiveDependencies(b, command); + new NodeRemoveWithExclusiveDependenciesAndDisconnect(b, command); } } } @@ -471,7 +471,7 @@ void TimelineWidget::DeleteSelected(bool ripple) foreach (TransitionBlock* transition, transitions_to_delete) { new TransitionRemoveCommand(transition, command); - Node::RemoveNodesAndExclusiveDependencies(transition, command); + new NodeRemoveWithExclusiveDependenciesAndDisconnect(transition, command); } // Replace clips with gaps (effectively deleting them)