From 09dc79f9f6cb8ee6d04c4a59a52a31163e608291 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 23 May 2021 10:38:30 +1000 Subject: [PATCH] project: remove array element when deleting a folder's subitem Fixes #1639 --- app/node/node.h | 110 +++++++++--------- app/node/project/folder/folder.cpp | 18 +++ app/node/project/folder/folder.h | 40 +++++++ .../projectexplorer/projectexplorer.cpp | 4 + 4 files changed, 117 insertions(+), 55 deletions(-) diff --git a/app/node/node.h b/app/node/node.h index 71e6e78cd..d4ad010fc 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -768,6 +768,61 @@ public: static const QString kDefaultOutput; + class ArrayRemoveCommand : public UndoCommand + { + public: + ArrayRemoveCommand(Node* node, const QString& input, int index) : + node_(node), + input_(input), + index_(index) + { + } + + virtual Project* GetRelevantProject() const override; + + protected: + virtual void redo() override + { + // Save immediate data + if (node_->IsInputKeyframable(input_)) { + is_keyframing_ = node_->IsInputKeyframing(input_, index_); + } + standard_value_ = node_->GetSplitStandardValue(input_, index_); + keyframes_ = node_->GetKeyframeTracks(input_, index_); + node_->GetImmediate(input_, index_)->delete_all_keyframes(&memory_manager_); + + node_->InputArrayRemove(input_, index_, false); + } + + virtual void undo() override + { + node_->InputArrayInsert(input_, index_, false); + + // Restore keyframes + foreach (const NodeKeyframeTrack& track, keyframes_) { + foreach (NodeKeyframe* key, track) { + key->setParent(node_); + } + } + node_->SetSplitStandardValue(input_, standard_value_, index_); + + if (node_->IsInputKeyframable(input_)) { + node_->SetInputIsKeyframing(input_, is_keyframing_, index_); + } + } + + private: + Node* node_; + QString input_; + int index_; + + SplitValue standard_value_; + bool is_keyframing_; + QVector keyframes_; + QObject memory_manager_; + + }; + protected: enum InputFlag { /// By default, inputs are keyframable, connectable, and NOT arrays @@ -976,61 +1031,6 @@ private: }; - class ArrayRemoveCommand : public UndoCommand - { - public: - ArrayRemoveCommand(Node* node, const QString& input, int index) : - node_(node), - input_(input), - index_(index) - { - } - - virtual Project* GetRelevantProject() const override; - - protected: - virtual void redo() override - { - // Save immediate data - if (node_->IsInputKeyframable(input_)) { - is_keyframing_ = node_->IsInputKeyframing(input_, index_); - } - standard_value_ = node_->GetSplitStandardValue(input_, index_); - keyframes_ = node_->GetKeyframeTracks(input_, index_); - node_->GetImmediate(input_, index_)->delete_all_keyframes(&memory_manager_); - - node_->InputArrayRemove(input_, index_, false); - } - - virtual void undo() override - { - node_->InputArrayInsert(input_, index_, false); - - // Restore keyframes - foreach (const NodeKeyframeTrack& track, keyframes_) { - foreach (NodeKeyframe* key, track) { - key->setParent(node_); - } - } - node_->SetSplitStandardValue(input_, standard_value_, index_); - - if (node_->IsInputKeyframable(input_)) { - node_->SetInputIsKeyframing(input_, is_keyframing_, index_); - } - } - - private: - Node* node_; - QString input_; - int index_; - - SplitValue standard_value_; - bool is_keyframing_; - QVector keyframes_; - QObject memory_manager_; - - }; - class ArrayResizeCommand : public UndoCommand { public: diff --git a/app/node/project/folder/folder.cpp b/app/node/project/folder/folder.cpp index dc07f574e..9508425f2 100644 --- a/app/node/project/folder/folder.cpp +++ b/app/node/project/folder/folder.cpp @@ -24,6 +24,7 @@ #include "node/project/footage/footage.h" #include "node/project/sequence/sequence.h" #include "ui/icons/icons.h" +#include "widget/nodeview/nodeviewundo.h" namespace olive { @@ -155,4 +156,21 @@ void FolderAddChild::undo() folder_->InputArrayRemoveLast(Folder::kChildInput); } +void Folder::RemoveElementCommand::redo() +{ + if (!subcommand_) { + remove_index_ = folder_->index_of_child_in_array(child_); + if (remove_index_ != -1) { + NodeInput connected_input(folder_, Folder::kChildInput, remove_index_); + subcommand_ = new MultiUndoCommand(); + subcommand_->add_child(new NodeEdgeRemoveCommand(folder_->GetConnectedOutput(connected_input), connected_input)); + subcommand_->add_child(new Node::ArrayRemoveCommand(folder_, Folder::kChildInput, remove_index_)); + } + } + + if (subcommand_) { + subcommand_->redo(); + } +} + } diff --git a/app/node/project/folder/folder.h b/app/node/project/folder/folder.h index 3e96cb293..6d0521433 100644 --- a/app/node/project/folder/folder.h +++ b/app/node/project/folder/folder.h @@ -115,6 +115,46 @@ public: static const QString kChildInput; + class RemoveElementCommand : public UndoCommand + { + public: + RemoveElementCommand(Folder *folder, Node *child) : + folder_(folder), + child_(child), + subcommand_(nullptr) + { + } + + virtual ~RemoveElementCommand() override + { + delete subcommand_; + } + + virtual Project *GetRelevantProject() const override + { + return folder_->project(); + } + + virtual void redo() override; + + virtual void undo() override + { + if (subcommand_) { + subcommand_->undo(); + } + } + + private: + Folder *folder_; + + Node *child_; + + int remove_index_; + + MultiUndoCommand *subcommand_; + + }; + signals: void BeginInsertItem(Node* n, int index); diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index c05a69d11..49720bb0a 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -223,6 +223,10 @@ bool ProjectExplorer::DeleteItemsInternal(const QVector& selected, bool& command->add_child(new CloseSequenceCommand(sequence)); } + if (node->folder()) { + command->add_child(new Folder::RemoveElementCommand(node->folder(), node)); + } + command->add_child(new NodeRemoveWithExclusiveDependenciesAndDisconnect(node)); } }