From b57b091ca4ad9e0cefb430d06a9cd71b25dc8b01 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 15 Mar 2020 13:15:36 +1100 Subject: [PATCH] timeline: auto-unlink blocks when they're deleted --- app/node/block/block.cpp | 20 ++++++-- app/node/block/block.h | 3 +- app/widget/timelinewidget/timelinewidget.cpp | 2 + app/widget/timelinewidget/undo/undo.cpp | 49 ++++++++++++++++++++ app/widget/timelinewidget/undo/undo.h | 30 ++++++++++++ 5 files changed, 100 insertions(+), 4 deletions(-) diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index 312f10103..6228dcec2 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -204,11 +204,12 @@ void Block::LengthInputChanged() void Block::Link(Block *a, Block *b) { - if (a == b || a == nullptr || b == nullptr) { + if (a == b || !a || !b) { return; } - // Assume both clips are already linked since Link() and Unlink() should be the only entry points to this array + // Prevent duplicate link entries (assume that we only need to check one clip since this should be the only function + // that adds to the linked array) if (a->linked_clips_.contains(b)) { return; } @@ -217,7 +218,7 @@ void Block::Link(Block *a, Block *b) b->linked_clips_.append(a); } -void Block::Link(QList blocks) +void Block::Link(const QList& blocks) { foreach (Block* a, blocks) { foreach (Block* b, blocks) { @@ -228,10 +229,23 @@ void Block::Link(QList blocks) void Block::Unlink(Block *a, Block *b) { + if (a == b || !a || !b) { + return; + } + a->linked_clips_.removeOne(b); b->linked_clips_.removeOne(a); } +void Block::Unlink(const QList &blocks) +{ + foreach (Block* a, blocks) { + foreach (Block* b, blocks) { + Unlink(a, b); + } + } +} + bool Block::AreLinked(Block *a, Block *b) { return a->linked_clips_.contains(b); diff --git a/app/node/block/block.h b/app/node/block/block.h index e0e43f1fe..3cf16d46e 100644 --- a/app/node/block/block.h +++ b/app/node/block/block.h @@ -77,8 +77,9 @@ public: void set_block_name(const QString& name); static void Link(Block* a, Block* b); - static void Link(QList blocks); + static void Link(const QList& blocks); static void Unlink(Block* a, Block* b); + static void Unlink(const QList& blocks); static bool AreLinked(Block* a, Block* b); const QVector& linked_clips(); bool HasLinks(); diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 2385b9289..28359e0fc 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -380,6 +380,8 @@ void TimelineWidget::DeleteSelectedInternal(const QList &blocks, } if (remove_from_graph) { + new BlockUnlinkAllCommand(b, command); + new NodeRemoveWithExclusiveDeps(static_cast(b->parent()), b, command); } } diff --git a/app/widget/timelinewidget/undo/undo.cpp b/app/widget/timelinewidget/undo/undo.cpp index 2a7dfae1b..4eb3e66af 100644 --- a/app/widget/timelinewidget/undo/undo.cpp +++ b/app/widget/timelinewidget/undo/undo.cpp @@ -715,3 +715,52 @@ void WorkareaSetRangeCommand::undo_internal() { points_->workarea()->set_range(old_range_); } + +BlockLinkCommand::BlockLinkCommand(const QList &blocks, bool link, QUndoCommand *parent) : + UndoCommand(parent), + blocks_(blocks), + link_(link) +{ +} + +void BlockLinkCommand::redo_internal() +{ + if (link_) { + Block::Link(blocks_); + } else { + Block::Unlink(blocks_); + } +} + +void BlockLinkCommand::undo_internal() +{ + if (link_) { + Block::Unlink(blocks_); + } else { + Block::Link(blocks_); + } +} + +BlockUnlinkAllCommand::BlockUnlinkAllCommand(Block *block, QUndoCommand *parent) : + UndoCommand(parent), + block_(block) +{ +} + +void BlockUnlinkAllCommand::redo_internal() +{ + unlinked_ = block_->linked_clips(); + + foreach (Block* link, unlinked_) { + Block::Unlink(block_, link); + } +} + +void BlockUnlinkAllCommand::undo_internal() +{ + foreach (Block* link, unlinked_) { + Block::Link(block_, link); + } + + unlinked_.clear(); +} diff --git a/app/widget/timelinewidget/undo/undo.h b/app/widget/timelinewidget/undo/undo.h index d8afe6d60..ce2d82285 100644 --- a/app/widget/timelinewidget/undo/undo.h +++ b/app/widget/timelinewidget/undo/undo.h @@ -331,4 +331,34 @@ private: }; +class BlockLinkCommand : public UndoCommand { +public: + BlockLinkCommand(const QList& blocks, bool link, QUndoCommand* parent = nullptr); + +protected: + virtual void redo_internal() override; + virtual void undo_internal() override; + +private: + QList blocks_; + + bool link_; + +}; + +class BlockUnlinkAllCommand : public UndoCommand { +public: + BlockUnlinkAllCommand(Block* block, QUndoCommand* parent = nullptr); + +protected: + virtual void redo_internal() override; + virtual void undo_internal() override; + +private: + Block* block_; + + QVector unlinked_; + +}; + #endif // TIMELINEUNDOABLE_H