timeline: fixed dodgy code on gap insert command

Also added test for this command to help ensure correct behavior.
This commit is contained in:
itsmattkc
2021-05-29 20:02:16 +10:00
parent ab31df369d
commit 3592982b16
2 changed files with 130 additions and 8 deletions
+22 -8
View File
@@ -463,7 +463,6 @@ public:
Q_ASSERT(i == 0 || time > times_.at(i-1));
QVector<Block*> splits(blocks_.size());
commands_.resize(blocks_.size());
for (int j=0;j<blocks_.size();j++) {
Block* b = blocks_.at(j);
@@ -472,7 +471,7 @@ public:
BlockSplitCommand* split_command = new BlockSplitCommand(b, time);
split_command->redo();
splits.replace(j, split_command->new_block());
commands_.replace(j, split_command);
commands_.append(split_command);
} else {
splits.replace(j, nullptr);
}
@@ -2045,8 +2044,8 @@ public:
}
foreach (auto add_gap, gaps_added_) {
add_gap.gap->setParent(add_gap.before->parent());
add_gap.before->track()->InsertBlockAfter(add_gap.gap, add_gap.before);
add_gap.gap->setParent(add_gap.track->parent());
add_gap.track->InsertBlockAfter(add_gap.gap, add_gap.before);
}
foreach (Track* track, working_tracks_) {
@@ -2121,6 +2120,7 @@ private:
QVector<Block*> blocks_to_split;
QVector<Block*> blocks_to_append_gap_to;
QVector<Track*> tracks_to_append_gap_to;
foreach (Track* track, working_tracks_) {
foreach (Block* b, track->Blocks()) {
@@ -2129,11 +2129,24 @@ private:
gaps_to_extend_.append(b);
break;
} else if (dynamic_cast<ClipBlock*>(b) && b->out() >= point_) {
if (b->out() > point_) {
bool append_gap = true;
if (b->in() == point_) {
// The only reason we should be here is if this block is at the start of the track,
// in which case no split needs to occur
b = nullptr;
} else if (b->out() > point_) {
// Block must be split as well as having a gap appended to it
blocks_to_split.append(b);
} else if (!b->next()) {
// At the end of a track, no gap needs to be added at all
append_gap = false;
}
blocks_to_append_gap_to.append(b);
if (append_gap) {
tracks_to_append_gap_to.append(track);
blocks_to_append_gap_to.append(b);
}
break;
}
}
@@ -2143,11 +2156,11 @@ private:
split_command_ = new BlockSplitPreservingLinksCommand(blocks_to_split, {point_});
}
foreach (Block* block, blocks_to_append_gap_to) {
for (int i=0; i<blocks_to_append_gap_to.size(); i++) {
GapBlock* gap = new GapBlock();
gap->set_length_and_media_out(length_);
gap->setParent(&memory_manager_);
gaps_added_.append({gap, block});
gaps_added_.append({gap, blocks_to_append_gap_to.at(i), tracks_to_append_gap_to.at(i)});
}
}
@@ -2166,6 +2179,7 @@ private:
struct AddGap {
GapBlock* gap;
Block* before;
Track* track;
};
QVector<AddGap> gaps_added_;
+108
View File
@@ -488,4 +488,112 @@ OLIVE_ADD_TEST(ReplaceBlockWithGap_ClipsAndTransitions)
OLIVE_TEST_END;
}
OLIVE_ADD_TEST(InsertGaps_SingleTrack)
{
TIMELINE_TEST_START;
sequence.add_default_nodes();
TrackList *list = sequence.track_list(Track::kVideo);
Track *track = list->GetTracks().first();
ClipBlock *a = new ClipBlock();
a->setParent(&project);
track->AppendBlock(a);
ClipBlock *b = new ClipBlock();
b->setParent(&project);
track->AppendBlock(b);
ClipBlock *c = new ClipBlock();
c->setParent(&project);
track->AppendBlock(c);
OLIVE_ASSERT(track->Blocks().size() == 3);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(track->Blocks().at(1) == b);
OLIVE_ASSERT(track->Blocks().at(2) == c);
{
// Insert gap at the start of the track, all blocks should be unsplit and shifted to the right
TrackListInsertGaps command(list, 0, 2);
command.redo();
OLIVE_ASSERT(track->Blocks().size() == 4);
OLIVE_ASSERT(dynamic_cast<GapBlock *>(track->Blocks().at(0)));
OLIVE_ASSERT(track->Blocks().at(0)->length() == 2);
OLIVE_ASSERT(track->Blocks().at(1) == a);
OLIVE_ASSERT(track->Blocks().at(2) == b);
OLIVE_ASSERT(track->Blocks().at(3) == c);
command.undo();
OLIVE_ASSERT(track->Blocks().size() == 3);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(track->Blocks().at(1) == b);
OLIVE_ASSERT(track->Blocks().at(2) == c);
}
{
// Insert gap in the middle of block A, block A should be halved with a copy at 2 and the gap at 1
TrackListInsertGaps command(list, rational(1, 2), 2);
command.redo();
OLIVE_ASSERT(track->Blocks().size() == 5);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(track->Blocks().at(0)->length() == rational(1, 2));
OLIVE_ASSERT(dynamic_cast<GapBlock *>(track->Blocks().at(1)));
OLIVE_ASSERT(dynamic_cast<ClipBlock*>(track->Blocks().at(2)));
OLIVE_ASSERT(track->Blocks().at(3) == b);
OLIVE_ASSERT(track->Blocks().at(4) == c);
command.undo();
OLIVE_ASSERT(track->Blocks().size() == 3);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(track->Blocks().at(0)->length() = 1);
OLIVE_ASSERT(track->Blocks().at(1) == b);
OLIVE_ASSERT(track->Blocks().at(2) == c);
}
{
// Insert gap between block A and B, blocks should be unsplit with a gap at 1
TrackListInsertGaps command(list, 1, 2);
command.redo();
OLIVE_ASSERT(track->Blocks().size() == 4);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(dynamic_cast<GapBlock *>(track->Blocks().at(1)));
OLIVE_ASSERT(track->Blocks().at(2) == b);
OLIVE_ASSERT(track->Blocks().at(3) == c);
command.undo();
OLIVE_ASSERT(track->Blocks().size() == 3);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(track->Blocks().at(1) == b);
OLIVE_ASSERT(track->Blocks().at(2) == c);
}
{
// Insert gap at end, nothing should be added
TrackListInsertGaps command(list, 3, 2);
command.redo();
OLIVE_ASSERT(track->Blocks().size() == 3);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(track->Blocks().at(1) == b);
OLIVE_ASSERT(track->Blocks().at(2) == c);
command.undo();
OLIVE_ASSERT(track->Blocks().size() == 3);
OLIVE_ASSERT(track->Blocks().at(0) == a);
OLIVE_ASSERT(track->Blocks().at(1) == b);
OLIVE_ASSERT(track->Blocks().at(2) == c);
}
OLIVE_TEST_END;
}
}