From 5bb9cb0ccad27544898bbe7d5e0af36ccbf5f71f Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Sun, 27 Sep 2020 17:42:09 +0100 Subject: [PATCH] Make Offlining footage an UndoCommand Created a new UndoCommand in ProjectViewModel that set the footage input to a nullptr and resets it to the correct stream on undo. --- app/project/projectviewmodel.cpp | 38 +++++++++++++++++++ app/project/projectviewmodel.h | 21 ++++++++++ .../projectexplorer/projectexplorer.cpp | 27 +++++++------ app/widget/projectexplorer/projectexplorer.h | 2 +- 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/app/project/projectviewmodel.cpp b/app/project/projectviewmodel.cpp index 7dfaf453a..8c176f24f 100644 --- a/app/project/projectviewmodel.cpp +++ b/app/project/projectviewmodel.cpp @@ -25,6 +25,7 @@ #include #include "core.h" +#include "node/input/media/media.h" OLIVE_NAMESPACE_ENTER @@ -603,4 +604,41 @@ void ProjectViewModel::RemoveItemCommand::undo_internal() model_->AddChild(parent_, item_); } +ProjectViewModel::OfflineFootageCommand::OfflineFootageCommand(ProjectViewModel* model, ItemPtr item, + QMap nodes, QUndoCommand* parent) : + UndoCommand(parent), + model_(model), + item_(item), + nodes_(nodes) +{ +} + +Project *ProjectViewModel::OfflineFootageCommand::GetRelevantProject() const +{ + return model_->project(); +} + +void ProjectViewModel::OfflineFootageCommand::redo_internal() +{ + QMap::const_iterator it = nodes_.constBegin(); + while (it != nodes_.constEnd()) { + static_cast(it.key())->SetFootage(nullptr); + ++it; + } + + parent_ = item_->parent(); + model_->RemoveChild(parent_, item_.get()); +} + +void ProjectViewModel::OfflineFootageCommand::undo_internal() +{ + model_->AddChild(parent_, item_); + + QMap::const_iterator it = nodes_.constBegin(); + while (it != nodes_.constEnd()) { + static_cast(it.key())->SetFootage(it.value()); + ++it; + } +} + OLIVE_NAMESPACE_EXIT diff --git a/app/project/projectviewmodel.h b/app/project/projectviewmodel.h index 964378316..d79542aa0 100644 --- a/app/project/projectviewmodel.h +++ b/app/project/projectviewmodel.h @@ -194,6 +194,27 @@ public: }; + class OfflineFootageCommand : public UndoCommand { + public: + OfflineFootageCommand(ProjectViewModel* model, ItemPtr item, QMap nodes, QUndoCommand* parent = nullptr); + + virtual Project* GetRelevantProject() const override; + + protected: + virtual void redo_internal() override; + + virtual void undo_internal() override; + + private: + ProjectViewModel* model_; + + ItemPtr item_; + + Item* parent_; + + QMap nodes_; + }; + private: /** * @brief Retrieve the index of `item` in its parent diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 0694185e3..3c5ce6f07 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -537,11 +537,11 @@ void ProjectExplorer::DeselectAll() CurrentView()->selectionModel()->clearSelection(); } -QList ProjectExplorer::GetFootageNodes(Item* item) +QMap ProjectExplorer::GetFootageNodes(Item* item) { // Output list list - QList nodes; - + QMap nodes; + // Get all sequences. QList sequences = model_.project()->get_items_of_type(Item::kSequence); // Get item pointer. @@ -562,7 +562,7 @@ QList ProjectExplorer::GetFootageNodes(Item* item) if (node->IsMedia()){ // Check the streams are the same if (static_cast(node)->footage() == stream) { - nodes.append(node); + nodes.insert(node, stream); } } } @@ -615,29 +615,32 @@ void ProjectExplorer::DeleteSelected() if (Core::instance()->main_window()->IsSequenceOpen(s)) { Core::instance()->main_window()->CloseSequence(s); } + + new ProjectViewModel::RemoveItemCommand(&model_, item_ptr, command); } // If this is a footage item, clean up if necessary if (item_ptr->type() == Item::kFootage) { // Check if nodes exists - QList nodes = GetFootageNodes(item); + QMap nodes = GetFootageNodes(item); if (!nodes.isEmpty()){ + // Warn user and ask them what to do FootageDeleteResponse response = DeleteWarningMessage(); if (response == kOffline) { - // Loop through Footage nodes - foreach (Node* node, nodes) { - // Set footage to be null - static_cast(node)->SetFootage(nullptr); - } + new ProjectViewModel::OfflineFootageCommand(&model_, item_ptr, nodes, command); + } + if (response == kDelete) { + // Get all sequences. + QList sequences = model_.project()->get_items_of_type(Item::kSequence); + } if (response == kCancel) { + delete command; return; } } } - - new ProjectViewModel::RemoveItemCommand(&model_, item_ptr, command); } Core::instance()->undo_stack()->pushIfHasChildren(command); diff --git a/app/widget/projectexplorer/projectexplorer.h b/app/widget/projectexplorer/projectexplorer.h index 12c999d5e..b755401ac 100644 --- a/app/widget/projectexplorer/projectexplorer.h +++ b/app/widget/projectexplorer/projectexplorer.h @@ -119,7 +119,7 @@ private: * @brief Check if an item is in use anywhere and return any relevant input nodes * Returns a QList as Footage has two streams that need to be handled */ - QList GetFootageNodes(Item* item); + QMap GetFootageNodes(Item* item); /** * @brief Simple convenience function for adding a view to this stacked widget