From e44918c70a235185944e659ce3fb9dc7cc4eac96 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 16 Mar 2021 12:59:58 +1100 Subject: [PATCH] delete exclusive dependencies when deleting items from project explorer --- .../projectexplorer/projectexplorer.cpp | 160 ++++++++++-------- app/widget/projectexplorer/projectexplorer.h | 6 + app/window/mainwindow/mainwindowundo.cpp | 10 ++ app/window/mainwindow/mainwindowundo.h | 18 ++ 4 files changed, 120 insertions(+), 74 deletions(-) diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 19d0f03a3..ce09ca4db 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -37,8 +37,9 @@ #include "widget/menu/menu.h" #include "widget/menu/menushared.h" #include "window/mainwindow/mainwindow.h" -#include "widget/timelinewidget/timelinewidget.h" +#include "window/mainwindow/mainwindowundo.h" #include "widget/nodeview/nodeviewundo.h" +#include "widget/timelinewidget/timelinewidget.h" namespace olive { @@ -159,6 +160,85 @@ void ProjectExplorer::BrowseToFolder(const QModelIndex &index) nav_bar_->set_dir_up_enabled(index.isValid()); } +int ProjectExplorer::ConfirmItemDeletion(Node* item) +{ + QMessageBox msgbox(this); + msgbox.setWindowTitle(tr("Confirm Item Deletion")); + msgbox.setIcon(QMessageBox::Warning); + + QStringList connected_nodes_names; + foreach (const Node::OutputConnection& connected, item->output_connections()) { + if (!dynamic_cast(connected.second.node())) { + connected_nodes_names.append(GetHumanReadableNodeName(connected.second.node())); + } + } + + msgbox.setText(tr("The item \"%1\" is currently connected to the following nodes:\n\n" + "%2\n\n" + "Are you sure you wish to delete this footage?") + .arg(GetHumanReadableNodeName(item), connected_nodes_names.join('\n'))); + + // Set up buttons + msgbox.addButton(QMessageBox::Yes); + msgbox.addButton(QMessageBox::YesToAll); + msgbox.addButton(QMessageBox::No); + msgbox.addButton(QMessageBox::Cancel); + + // Run messagebox + return msgbox.exec(); +} + +bool ProjectExplorer::DeleteItemsInternal(const QVector& selected, bool& check_if_item_is_in_use, MultiUndoCommand* command) +{ + for (int i=0; ioutput_connections()) { + Folder* folder_test = dynamic_cast(oc.second.node()); + if (!folder_test) { + // This sequence outputs to SOMETHING, confirm the user if they want to delete this + int r = ConfirmItemDeletion(node); + + switch (r) { + case QMessageBox::No: + can_delete_item = false; + break; + case QMessageBox::Cancel: + return false; + case QMessageBox::YesToAll: + check_if_item_is_in_use = false; + break; + } + } + } + } + + if (can_delete_item) { + Sequence* sequence = dynamic_cast(node); + if (sequence && Core::instance()->main_window()->IsSequenceOpen(sequence)) { + command->add_child(new CloseSequenceCommand(sequence)); + } + + command->add_child(new NodeRemoveWithExclusiveDependenciesAndDisconnect(node)); + } + } + + return true; +} + +QString ProjectExplorer::GetHumanReadableNodeName(Node *node) +{ + if (node->GetLabel().isEmpty()) { + return node->Name(); + } else { + return tr("%1 (%2)").arg(node->GetLabel(), node->Name()); + } +} + QAbstractItemView *ProjectExplorer::CurrentView() const { return static_cast(stacked_widget_->currentWidget()); @@ -533,81 +613,13 @@ void ProjectExplorer::DeleteSelected() MultiUndoCommand* command = new MultiUndoCommand(); - bool dont_confirm_footage_in_use = false; + bool check_if_item_is_in_use = true; - foreach (Node* item, selected) { - // Verify whether this item is in use anywhere - Footage* footage_cast_test = dynamic_cast(item); - Sequence* sequence_cast_test = dynamic_cast(item); - - bool cleared_to_delete = true; - - if (sequence_cast_test) { - if (Core::instance()->main_window()->IsSequenceOpen(sequence_cast_test)) { - Core::instance()->main_window()->CloseSequence(sequence_cast_test); - } - } else if (footage_cast_test) { - if (!footage_cast_test->output_connections().empty() && !dont_confirm_footage_in_use) { - // Footage outputs to other nodes, warn the user - QMessageBox msgbox(this); - msgbox.setWindowTitle(tr("Confirm Footage Deletion")); - msgbox.setIcon(QMessageBox::Warning); - - QStringList connected_nodes; - foreach (const Node::OutputConnection& c, footage_cast_test->output_connections()) { - Node* connected = c.second.node(); - - if (connected->GetLabel().isEmpty()) { - connected_nodes.append(connected->Name()); - } else { - connected_nodes.append(QStringLiteral("%1 (%2)").arg(connected->GetLabel(), connected->Name())); - } - } - - msgbox.setText(tr("The footage \"%1\" is currently connected to the following nodes:\n\n" - "%2\n\n" - "Are you sure you wish to delete this footage?") - .arg(footage_cast_test->filename(), connected_nodes.join('\n'))); - - - // Set up buttons - msgbox.addButton(QMessageBox::Yes); - msgbox.addButton(QMessageBox::YesToAll); - msgbox.addButton(QMessageBox::No); - msgbox.addButton(QMessageBox::Cancel); - - // Run messagebox - int r = msgbox.exec(); - - switch (r) { - case QMessageBox::Cancel: - // Stop this entire function - delete command; - return; - case QMessageBox::No: - cleared_to_delete = false; - break; - case QMessageBox::YesToAll: - dont_confirm_footage_in_use = true; - break; - } - } - - if (cleared_to_delete) { - // Close footage if currently open in footage panel - FootageViewerPanel* footage_panel = PanelManager::instance()->GetPanelsOfType().first(); - if (footage_panel->GetSelectedFootage().contains(footage_cast_test)) { - footage_panel->SetFootage(nullptr); - } - } - } - - if (cleared_to_delete) { - command->add_child(new NodeRemoveAndDisconnectCommand(reinterpret_cast(item))); - } + if (DeleteItemsInternal(selected, check_if_item_is_in_use, command)) { + Core::instance()->undo_stack()->pushIfHasChildren(command); + } else { + delete command; } - - Core::instance()->undo_stack()->pushIfHasChildren(command); } } diff --git a/app/widget/projectexplorer/projectexplorer.h b/app/widget/projectexplorer/projectexplorer.h index d929dff15..274afd887 100644 --- a/app/widget/projectexplorer/projectexplorer.h +++ b/app/widget/projectexplorer/projectexplorer.h @@ -131,6 +131,12 @@ private: */ void BrowseToFolder(const QModelIndex& index); + int ConfirmItemDeletion(Node *item); + + bool DeleteItemsInternal(const QVector &selected, bool &check_if_item_is_in_use, MultiUndoCommand *command); + + static QString GetHumanReadableNodeName(Node* node); + /** * @brief Get the currently active QAbstractItemView */ diff --git a/app/window/mainwindow/mainwindowundo.cpp b/app/window/mainwindow/mainwindowundo.cpp index 54d4d592c..a0d9ac840 100644 --- a/app/window/mainwindow/mainwindowundo.cpp +++ b/app/window/mainwindow/mainwindowundo.cpp @@ -35,4 +35,14 @@ void OpenSequenceCommand::undo() Core::instance()->main_window()->CloseSequence(sequence_); } +void CloseSequenceCommand::redo() +{ + Core::instance()->main_window()->CloseSequence(sequence_); +} + +void CloseSequenceCommand::undo() +{ + Core::instance()->main_window()->OpenSequence(sequence_); +} + } diff --git a/app/window/mainwindow/mainwindowundo.h b/app/window/mainwindow/mainwindowundo.h index 27ea85736..f64f7f92e 100644 --- a/app/window/mainwindow/mainwindowundo.h +++ b/app/window/mainwindow/mainwindowundo.h @@ -43,6 +43,24 @@ private: }; +class CloseSequenceCommand : public UndoCommand +{ +public: + CloseSequenceCommand(Sequence* sequence) : + sequence_(sequence) + {} + + virtual void redo() override; + + virtual void undo() override; + + virtual Project* GetRelevantProject() const override {return nullptr;} + +private: + Sequence* sequence_; + +}; + } #endif // MAINWINDOWUNDO_H