diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index 75712c0a8..989c8b037 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -31,9 +31,6 @@ Block::Block() : buffer_output_ = new NodeOutput("buffer_out"); AddParameter(buffer_output_); - - connect(this, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(EdgeAddedSlot(NodeEdgePtr)), Qt::DirectConnection); - connect(this, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(EdgeRemovedSlot(NodeEdgePtr)), Qt::DirectConnection); } QString Block::Category() @@ -51,6 +48,16 @@ const rational &Block::out() return out_point_; } +void Block::set_in(const rational &in) +{ + in_point_ = in; +} + +void Block::set_out(const rational &out) +{ + out_point_ = out; +} + const rational& Block::length() { return length_; @@ -60,13 +67,17 @@ void Block::set_length(const rational &length) { Q_ASSERT(length > 0); + if (length == length_) { + return; + } + LockUserInput(); length_ = length; UnlockUserInput(); - Refresh(); + emit LengthChanged(length_); } void Block::set_length_and_media_in(const rational &length) @@ -88,6 +99,16 @@ Block *Block::next() return next_; } +void Block::set_previous(Block *previous) +{ + previous_ = previous; +} + +void Block::set_next(Block *next) +{ + next_ = next; +} + QVariant Block::Value(NodeOutput *output) { if (output == block_output_) { @@ -98,25 +119,6 @@ QVariant Block::Value(NodeOutput *output) return 0; } -void Block::Refresh() -{ - // Set in point to the out point of the previous Node - if (previous() != nullptr) { - in_point_ = previous()->out(); - } else { - in_point_ = 0; - } - - // Update out point by adding this clip's length to the just calculated in point - out_point_ = in_point_ + length(); - - emit Refreshed(); - - if (next() != nullptr) { - next()->Refresh(); - } -} - NodeOutput *Block::buffer_output() { return buffer_output_; diff --git a/app/node/block/block.h b/app/node/block/block.h index 7708cba01..5451ee947 100644 --- a/app/node/block/block.h +++ b/app/node/block/block.h @@ -42,7 +42,7 @@ public: enum Type { kClip, kGap, - kEnd + kTrack }; virtual Type type() = 0; @@ -51,6 +51,8 @@ public: const rational& in(); const rational& out(); + void set_in(const rational& in); + void set_out(const rational& out); const rational &length(); void set_length(const rational &length); @@ -58,6 +60,8 @@ public: Block* previous(); Block* next(); + void set_previous(Block* previous); + void set_next(Block* next); NodeOutput* buffer_output(); NodeOutput* block_output(); @@ -80,20 +84,6 @@ public: virtual QVariant Value(NodeOutput* output) override; public slots: - /** - * @brief Refreshes internal cache of in/out points up to date - * - * A block can only know truly know its in point by adding all the lengths of the clips before it. Since this can - * become timeconsuming, blocks cache their in and out points for easy access, however this does mean their caches - * need to stay up to date to provide accurate results. Whenever this or any surrounding Block is changed, it's - * recommended to call Refresh(). - * - * This function specifically sets the in point to the out point of the previous clip and sets its out point to the - * in point + this block's length. Therefore, before calling Refresh() on a Block, it's necessary that all the - * Blocks before it are accurate and up to date. You may need to traverse through the Block list (using previous()) - * and run Refresh() on all Blocks sequentially. - */ - virtual void Refresh(); signals: /** @@ -103,6 +93,8 @@ signals: */ void Refreshed(); + void LengthChanged(const rational& length); + protected: rational SequenceToMediaTime(const rational& sequence_time); @@ -110,18 +102,18 @@ protected: static void CopyParameters(Block* source, Block* dest); + Block* previous_; + Block* next_; + private: NodeOutput* block_output_; NodeOutput* buffer_output_; - rational in_point_; - rational out_point_; - rational length_; rational media_in_; - Block* previous_; - Block* next_; + rational in_point_; + rational out_point_; QString block_name_; diff --git a/app/node/output/timeline/tracklist.cpp b/app/node/output/timeline/tracklist.cpp index 51e0d06fa..497e80e15 100644 --- a/app/node/output/timeline/tracklist.cpp +++ b/app/node/output/timeline/tracklist.cpp @@ -47,7 +47,7 @@ void TrackList::AttachTrack(TrackOutput *track) connect(current_track, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(TrackEdgeRemoved(NodeEdgePtr))); connect(current_track, SIGNAL(BlockAdded(Block*)), this, SLOT(TrackAddedBlock(Block*))); connect(current_track, SIGNAL(BlockRemoved(Block*)), this, SLOT(TrackRemovedBlock(Block*))); - connect(current_track, SIGNAL(Refreshed()), this, SLOT(UpdateTotalLength())); + connect(current_track, SIGNAL(TrackLengthChanged()), this, SLOT(UpdateTotalLength())); current_track->SetIndex(track_cache_.size()); current_track->set_track_type(type_); @@ -219,7 +219,7 @@ void TrackList::UpdateTotalLength() total_length_ = 0; foreach (TrackOutput* track, track_cache_) { - total_length_ = qMax(total_length_, track->in()); + total_length_ = qMax(total_length_, track->track_length()); } emit LengthChanged(total_length_); diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index bf8854a37..4282e5f81 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -32,6 +32,9 @@ TrackOutput::TrackOutput() : { block_input_ = new NodeInputArray("block_in"); AddParameter(block_input_); + connect(block_input_, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(BlockConnected(NodeEdgePtr))); + connect(block_input_, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(BlockDisconnected(NodeEdgePtr))); + connect(block_input_, SIGNAL(SizeChanged(int)), this, SLOT(BlockListSizeChanged(int))); track_input_ = new NodeInput("track_in"); track_input_->set_data_type(NodeParam::kTrack); @@ -54,7 +57,7 @@ const TrackType& TrackOutput::track_type() Block::Type TrackOutput::type() { - return kEnd; + return kTrack; } Block *TrackOutput::copy() @@ -83,33 +86,6 @@ QString TrackOutput::Description() "a Sequence."); } -void TrackOutput::Refresh() -{ - QVector detect_attached_blocks; - - Block* prev = previous(); - while (prev != nullptr) { - detect_attached_blocks.prepend(prev); - - if (!block_cache_.contains(prev)) { - emit BlockAdded(prev); - } - - prev = prev->previous(); - } - - foreach (Block* b, block_cache_) { - if (!detect_attached_blocks.contains(b)) { - // If the current block was removed, stop referencing it - emit BlockRemoved(b); - } - } - - block_cache_ = detect_attached_blocks; - - Block::Refresh(); -} - const int &TrackOutput::Index() { return index_; @@ -192,87 +168,42 @@ QVariant TrackOutput::Value(NodeOutput *output) if (output == track_output_) { // Set track output correctly return PtrToValue(this); - /*} else if (output == buffer_output()) { - ValidateCurrentBlock(in); - - if (current_block_ != this) { - // At this point, we must have found the correct block so we use its texture output to produce the image - return current_block_->buffer_output()->get_value(in, out); - } - - // No texture is valid - return 0;*/ } // Run default node processing return Block::Value(output); } -void TrackOutput::InsertBlockBetweenBlocks(Block *block, Block *before, Block *after) -{ - AddBlockToGraph(block); - - Block::DisconnectBlocks(before, after); - Block::ConnectBlocks(before, block); - Block::ConnectBlocks(block, after); -} - void TrackOutput::InsertBlockBefore(Block* block, Block* after) { - Block* before = after->previous(); - - // If a block precedes this one, just insert between them - if (before != nullptr) { - InsertBlockBetweenBlocks(block, before, after); - } else { - AddBlockToGraph(block); - - // Otherwise, just connect the block since there's no before clip to insert between - Block::ConnectBlocks(block, after); - } + InsertBlockAtIndex(block, block_cache_.indexOf(after)); } void TrackOutput::InsertBlockAfter(Block *block, Block *before) { - InsertBlockBetweenBlocks(block, before, before->next()); + int before_index = block_cache_.indexOf(before); + + Q_ASSERT(before_index >= 0); + + if (before_index == block_cache_.size() - 1) { + AppendBlock(block); + } else { + InsertBlockAtIndex(block, before_index + 1); + } } void TrackOutput::PrependBlock(Block *block) { - AddBlockToGraph(block); - - if (block_cache_.isEmpty()) { - ConnectBlockInternal(block); - } else { - Block::ConnectBlocks(block, block_cache_.first()); - } + InsertBlockAtIndex(block, 0); } void TrackOutput::InsertBlockAtIndex(Block *block, int index) { AddBlockToGraph(block); - if (block_cache_.isEmpty()) { - - // If there are no blocks connected, the index doesn't matter. Just connect it. - ConnectBlockInternal(block); - - } else if (index == 0) { - - // If the index is 0, it goes at the very beginning - PrependBlock(block); - - } else if (index >= block_cache_.size()) { - - // Append Block at the end - AppendBlock(block); - - } else { - - // Insert Block just before the Block currently at that index so that it becomes the new Block at that index - InsertBlockBetweenBlocks(block, block_cache_.at(index - 1), block_cache_.at(index)); - - } + block_input_->InsertAt(index); + NodeParam::ConnectEdge(block->block_output(), + block_input_->ParamAt(index)); } void TrackOutput::AppendBlock(Block *block) @@ -281,23 +212,15 @@ void TrackOutput::AppendBlock(Block *block) BlockInvalidateCache(); - if (block_cache_.isEmpty()) { - ConnectBlockInternal(block); - } else { - InsertBlockBetweenBlocks(block, block_cache_.last(), this); - } + int last_index = block_input_->GetSize(); + block_input_->Append(); + NodeParam::ConnectEdge(block->block_output(), + block_input_->ParamAt(last_index)); UnblockInvalidateCache(); // Invalidate area that block was added to - InvalidateCache(block->in(), in()); -} - -void TrackOutput::ConnectBlockInternal(Block *block) -{ - AddBlockToGraph(block); - - Block::ConnectBlocks(block, this); + InvalidateCache(block->in(), track_length()); } void TrackOutput::AddBlockToGraph(Block *block) @@ -322,18 +245,7 @@ void TrackOutput::RemoveBlock(Block *block) GapBlock* gap = new GapBlock(); gap->set_length(block->length()); - Block* previous = block->previous(); - Block* next = block->next(); - - // Remove block - RippleRemoveBlock(block); - - if (previous == nullptr) { - // Block must be at the beginning - PrependBlock(gap); - } else { - InsertBlockBetweenBlocks(gap, previous, next); - } + ReplaceBlock(block, gap); } void TrackOutput::RippleRemoveBlock(Block *block) @@ -342,24 +254,13 @@ void TrackOutput::RippleRemoveBlock(Block *block) rational remove_in = block->in(); - Block* previous = block->previous(); - Block* next = block->next(); + int index_of_block_to_remove = block_cache_.indexOf(block); - if (previous != nullptr) { - Block::DisconnectBlocks(previous, block); - } - - if (next != nullptr) { - Block::DisconnectBlocks(block, next); - } - - if (previous != nullptr && next != nullptr) { - Block::ConnectBlocks(previous, next); - } + block_input_->RemoveAt(index_of_block_to_remove); UnblockInvalidateCache(); - InvalidateCache(remove_in, in()); + InvalidateCache(remove_in, track_length()); // FIXME: Should there be removing the Blocks from the graph? } @@ -368,23 +269,17 @@ void TrackOutput::ReplaceBlock(Block *old, Block *replace) { Q_ASSERT(old->length() == replace->length()); - Block* previous = old->previous(); - Block* next = old->next(); - BlockInvalidateCache(); AddBlockToGraph(replace); - // Disconnect old block from its surroundings - if (previous != nullptr) { - Block::DisconnectBlocks(previous, old); - Block::ConnectBlocks(previous, replace); - } + int index_of_old_block = block_cache_.indexOf(old); - if (next != nullptr) { - Block::DisconnectBlocks(old, next); - Block::ConnectBlocks(replace, next); - } + NodeParam::DisconnectEdge(old->block_output(), + block_input_->ParamAt(index_of_old_block)); + + NodeParam::ConnectEdge(replace->block_output(), + block_input_->ParamAt(index_of_old_block)); UnblockInvalidateCache(); @@ -393,14 +288,173 @@ void TrackOutput::ReplaceBlock(Block *old, Block *replace) TrackOutput *TrackOutput::TrackFromBlock(Block *block) { - Block* n = block; + NodeOutput* output = block->block_output(); - // Find last valid block in Sequence and assume its a track - while (n->next() != nullptr) { - n = n->next(); + foreach (NodeEdgePtr edge, output->edges()) { + TrackOutput* track_test = dynamic_cast(edge->input()->parentNode()); + + if (track_test) { + return track_test; + } } - // Downside of this approach is the usage of dynamic_cast, alternative would be looping through all known tracks and - // seeing if the contain the Block, but this seems slower - return dynamic_cast(n); + return nullptr; +} + +const rational &TrackOutput::track_length() +{ + return track_length_; +} + +bool TrackOutput::IsTrack() +{ + return true; +} + +void TrackOutput::UpdateInOutFrom(int index) +{ + Q_ASSERT(index >= 0); + Q_ASSERT(index < block_cache_.size()); + + rational new_track_length; + + for (int i=index;i=0;j--) { + Block* previous = block_cache_.at(j); + if (previous) { + prev_out = previous->out(); + break; + } + } + + rational new_out = prev_out + b->length(); + + b->set_in(prev_out); + b->set_out(new_out); + + new_track_length = new_out; + + emit b->Refreshed(); + } + } + + // Update track length + if (new_track_length != track_length_) { + track_length_ = new_track_length; + emit TrackLengthChanged(); + } +} + +void TrackOutput::UpdatePreviousAndNextOfIndex(int index) +{ + Block* ref = block_cache_.at(index); + + Block* previous = nullptr; + Block* next = nullptr; + + // Find previous + for (int i=index-1;i>=0;i--) { + previous = block_cache_.at(i); + + if (previous) { + break; + } + } + + // Find next + for (int i=index+1;iset_previous(previous); + ref->set_next(next); + + if (previous) + previous->set_next(ref); + + if (next) + next->set_previous(ref); + } else { + // Link previous and next together + if (previous) + previous->set_next(next); + + if (next) + next->set_previous(previous); + } +} + +void TrackOutput::BlockConnected(NodeEdgePtr edge) +{ + int block_index = block_input_->IndexOfSubParameter(edge->input()); + + Q_ASSERT(block_index >= 0); + + Block* connected_block = dynamic_cast(edge->output()->parentNode()); + block_cache_.replace(block_index, connected_block); + UpdatePreviousAndNextOfIndex(block_index); + UpdateInOutFrom(block_index); + + if (connected_block) { + connect(connected_block, SIGNAL(LengthChanged(const rational&)), this, SLOT(BlockLengthChanged())); + + emit BlockAdded(connected_block); + } +} + +void TrackOutput::BlockDisconnected(NodeEdgePtr edge) +{ + int block_index = block_input_->IndexOfSubParameter(edge->input()); + + Q_ASSERT(block_index >= 0); + + block_cache_.replace(block_index, nullptr); + UpdatePreviousAndNextOfIndex(block_index); + UpdateInOutFrom(block_index); + + Block* connected_block = dynamic_cast(edge->output()->parentNode()); + if (connected_block) { + disconnect(connected_block, SIGNAL(LengthChanged(const rational&)), this, SLOT(BlockLengthChanged())); + + // Update previous and next references + emit BlockRemoved(connected_block); + } +} + +void TrackOutput::BlockListSizeChanged(int size) +{ + int old_size = block_cache_.size(); + + block_cache_.resize(size); + + if (size > old_size) { + // Fill new slots with nullptr + for (int i=old_size;i(sender()); + + int index = block_cache_.indexOf(b); + + Q_ASSERT(index >= 0); + + UpdateInOutFrom(index); } diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index 409e90d9a..b16698007 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -45,8 +45,6 @@ public: virtual QString Category() override; virtual QString Description() override; - virtual void Refresh() override; - const int& Index(); void SetIndex(const int& index); @@ -79,13 +77,6 @@ public: */ void InsertBlockAtIndex(Block* block, int index); - /** - * @brief Inserts a Block between two other Blocks - * - * Disconnects `before` and `after`, and connects them to `block` with `block` in between. - */ - void InsertBlockBetweenBlocks(Block* block, Block* before, Block* after); - /** * @brief Inserts Block after another Block * @@ -131,6 +122,12 @@ public: */ void AddBlockToGraph(Block* block); + static TrackOutput* TrackFromBlock(Block* block); + + const rational& track_length(); + + virtual bool IsTrack() override; + signals: /** * @brief Signal emitted when a Block is added to this Track @@ -142,21 +139,18 @@ signals: */ void BlockRemoved(Block* block); + /** + * @brief Signal emitted when the length of the track has changed + */ + void TrackLengthChanged(); + protected: virtual QVariant Value(NodeOutput* output) override; private: - /** - * @brief Sets this Block as the only block in the Timeline (creating essentially a one clip sequence) - */ - void ConnectBlockInternal(Block* block); + void UpdateInOutFrom(int index); - /** - * @brief Disconnects t - */ - void RemoveBlockInternal(); - - static TrackOutput* TrackFromBlock(Block* block); + void UpdatePreviousAndNextOfIndex(int index); QVector block_cache_; @@ -168,11 +162,20 @@ private: TrackType track_type_; + rational track_length_; + int block_invalidate_cache_stack_; int index_; private slots: + void BlockConnected(NodeEdgePtr edge); + + void BlockDisconnected(NodeEdgePtr edge); + + void BlockListSizeChanged(int size); + + void BlockLengthChanged(); }; diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index d909f2c52..1f8384889 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -276,7 +276,7 @@ void TimelineWidget::GoToNextCut() int64_t closest_cut = INT64_MAX; foreach (TrackOutput* track, timeline_node_->Tracks()) { - int64_t this_track_closest_cut = olive::time_to_timestamp(track->in(), timebase()); + int64_t this_track_closest_cut = olive::time_to_timestamp(track->track_length(), timebase()); if (this_track_closest_cut <= playhead_) { this_track_closest_cut = INT64_MAX; @@ -592,7 +592,7 @@ void TimelineWidget::AddBlock(Block *block, TrackReference track) connect(block, SIGNAL(Refreshed()), this, SLOT(BlockChanged())); break; } - case Block::kEnd: + case Block::kTrack: // Do nothing break; } diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index f3841ddb9..1493861b9 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -513,7 +513,7 @@ rational TimelineWidget::PointerTool::ValidateOutTrimming(rational movement, if (prevent_overwriting) { // Determine if there's a block in the way Block* next = block->next(); - while (next != nullptr && next->type() != Block::kEnd) { + while (next != nullptr) { if (next->type() == Block::kClip) { latest_out = qMin(latest_out, next->in()); break; diff --git a/app/widget/timelinewidget/tool/ripple.cpp b/app/widget/timelinewidget/tool/ripple.cpp index f65a4a01e..3d9f5f2cc 100644 --- a/app/widget/timelinewidget/tool/ripple.cpp +++ b/app/widget/timelinewidget/tool/ripple.cpp @@ -129,9 +129,7 @@ void TimelineWidget::RippleTool::InitiateGhosts(TimelineViewBlockItem *clicked_i Block* block_before_ripple = track->NearestBlockBefore(earliest_ripple); // If block is null, there will be no blocks after to ripple - if (block_before_ripple != nullptr - && block_before_ripple->type() != Block::kEnd - && block_before_ripple->next()->type() != Block::kEnd) { + if (block_before_ripple != nullptr) { TimelineViewGhostItem* ghost; TrackReference track_ref(track->track_type(), track->Index()); diff --git a/app/widget/timelinewidget/tool/rolling.cpp b/app/widget/timelinewidget/tool/rolling.cpp index 2dabbafca..4e51f9454 100644 --- a/app/widget/timelinewidget/tool/rolling.cpp +++ b/app/widget/timelinewidget/tool/rolling.cpp @@ -90,7 +90,7 @@ void TimelineWidget::RollingTool::InitiateGhosts(TimelineViewBlockItem *clicked_ if (ghost->mode() == olive::timeline::kTrimIn && ghost_block->previous() != nullptr) { // Add an extra Ghost for the previous block AddGhostFromBlock(ghost_block->previous(), ghost->Track(), olive::timeline::kTrimOut); - } else if (ghost->mode() == olive::timeline::kTrimOut && ghost_block->next() != nullptr && ghost_block->next()->type() != Block::kEnd) { + } else if (ghost->mode() == olive::timeline::kTrimOut && ghost_block->next() != nullptr) { AddGhostFromBlock(ghost_block->next(), ghost->Track(), olive::timeline::kTrimIn); } } diff --git a/app/widget/timelinewidget/tool/slide.cpp b/app/widget/timelinewidget/tool/slide.cpp index 00cd8f546..55c7db3e6 100644 --- a/app/widget/timelinewidget/tool/slide.cpp +++ b/app/widget/timelinewidget/tool/slide.cpp @@ -81,7 +81,7 @@ void TimelineWidget::SlideTool::InitiateGhosts(TimelineViewBlockItem *clicked_it AddGhostFromBlock(ghost_block->previous(), ghost->Track(), olive::timeline::kTrimOut); } - if (ghost_block->next() != nullptr && ghost_block->next()->type() != Block::kEnd) { + if (ghost_block->next() != nullptr) { AddGhostFromBlock(ghost_block->next(), ghost->Track(), olive::timeline::kTrimIn); } } diff --git a/app/widget/timelinewidget/undo/undo.cpp b/app/widget/timelinewidget/undo/undo.cpp index bf49bd533..79a1c16d4 100644 --- a/app/widget/timelinewidget/undo/undo.cpp +++ b/app/widget/timelinewidget/undo/undo.cpp @@ -38,18 +38,6 @@ Node* TakeNodeFromParentGraph(Node* n, QObject* new_parent = nullptr) return n; } -TrackOutput* TrackFromBlock(Block* b) -{ - Block* next = b; - - do { - next = next->next(); - } while (next != nullptr && next->type() != Block::kEnd); - - // A little hacky, but this should either be a TrackOutput* or nullptr - return static_cast(next); -} - BlockResizeCommand::BlockResizeCommand(Block *block, rational new_length, QUndoCommand* parent) : QUndoCommand(parent), block_(block), @@ -108,8 +96,7 @@ TrackRippleRemoveBlockCommand::TrackRippleRemoveBlockCommand(TrackOutput *track, QUndoCommand(parent), track_(track), block_(block), - before_(block->previous()), - after_(block->next()) + before_(block->previous()) { } @@ -120,7 +107,7 @@ void TrackRippleRemoveBlockCommand::redo() void TrackRippleRemoveBlockCommand::undo() { - track_->InsertBlockBetweenBlocks(block_, before_, after_); + track_->InsertBlockAfter(block_, before_); } TrackInsertBlockBetweenBlocksCommand::TrackInsertBlockBetweenBlocksCommand(TrackOutput *track, @@ -138,7 +125,7 @@ TrackInsertBlockBetweenBlocksCommand::TrackInsertBlockBetweenBlocksCommand(Track void TrackInsertBlockBetweenBlocksCommand::redo() { - track_->InsertBlockBetweenBlocks(block_, before_, after_); + track_->InsertBlockAfter(block_, before_); } void TrackInsertBlockBetweenBlocksCommand::undo() @@ -245,7 +232,7 @@ void TrackRippleRemoveAreaCommand::redo() track_->AppendBlock(insert_); } else { // This is somewhere in the middle of the Sequence - track_->InsertBlockBetweenBlocks(insert_, trim_out_, trim_in_); + track_->InsertBlockAfter(insert_, trim_out_); } } @@ -320,14 +307,14 @@ void TrackPlaceBlockCommand::redo() track_ = timeline_->TrackAt(track_index_); - append_ = (in_ >= track_->in()); + append_ = (in_ >= track_->track_length()); // Check if the placement location is past the end of the timeline if (append_) { - if (in_ > track_->in()) { + if (in_ > track_->track_length()) { // If so, insert a gap here gap_ = new GapBlock(); - gap_->set_length(in_ - track_->in()); + gap_->set_length(in_ - track_->track_length()); track_->AppendBlock(gap_); } @@ -471,7 +458,11 @@ BlockSplitPreservingLinksCommand::BlockSplitPreservingLinksCommand(const QVector Block* b = blocks.at(j); if (b->in() < time && b->out() > time) { - BlockSplitCommand* split_command = new BlockSplitCommand(TrackFromBlock(b), b, time, this); + TrackOutput* track = TrackOutput::TrackFromBlock(b); + + Q_ASSERT(track); + + BlockSplitCommand* split_command = new BlockSplitCommand(track, b, time, this); splits.replace(j, split_command->new_block()); } else { splits.replace(j, nullptr); diff --git a/app/widget/timelinewidget/undo/undo.h b/app/widget/timelinewidget/undo/undo.h index 10da80859..6cba18bf3 100644 --- a/app/widget/timelinewidget/undo/undo.h +++ b/app/widget/timelinewidget/undo/undo.h @@ -80,7 +80,6 @@ private: Block* block_; Block* before_; - Block* after_; }; class TrackPrependBlockCommand : public QUndoCommand { diff --git a/app/widget/timelinewidget/view/timelineviewblockitem.cpp b/app/widget/timelinewidget/view/timelineviewblockitem.cpp index 09525ef71..48752201b 100644 --- a/app/widget/timelinewidget/view/timelineviewblockitem.cpp +++ b/app/widget/timelinewidget/view/timelineviewblockitem.cpp @@ -118,7 +118,7 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI painter->fillRect(rect(), Qt::white); } break; - case Block::kEnd: + case Block::kTrack: break; } }