delete exclusive dependencies when deleting items from project explorer

This commit is contained in:
itsmattkc
2021-03-16 12:59:58 +11:00
parent 643999e308
commit e44918c70a
4 changed files with 120 additions and 74 deletions
+86 -74
View File
@@ -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<Folder*>(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<Node*>& selected, bool& check_if_item_is_in_use, MultiUndoCommand* command)
{
for (int i=0; i<selected.size(); i++) {
// Delete sequences first
Node* node = selected.at(i);
bool can_delete_item = true;
if (check_if_item_is_in_use) {
foreach (const Node::OutputConnection& oc, node->output_connections()) {
Folder* folder_test = dynamic_cast<Folder*>(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<Sequence*>(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<QAbstractItemView*>(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<Footage*>(item);
Sequence* sequence_cast_test = dynamic_cast<Sequence*>(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<FootageViewerPanel>().first();
if (footage_panel->GetSelectedFootage().contains(footage_cast_test)) {
footage_panel->SetFootage(nullptr);
}
}
}
if (cleared_to_delete) {
command->add_child(new NodeRemoveAndDisconnectCommand(reinterpret_cast<Node*>(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);
}
}