Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 2369585e authored by Nicolas Carion's avatar Nicolas Carion

[Timeline2][Model] Handle correctly grouped clips when deleting track + improve tests

parent 1510447c
......@@ -445,15 +445,20 @@ bool TimelineModel::requestClipsGroup(const std::unordered_set<int>& ids)
bool TimelineModel::requestClipUngroup(int id)
{
std::function<bool (void)> undo = [](){return true;};
std::function<bool (void)> redo = [](){return true;};
bool result = m_groups->ungroupItem(id, undo, redo);
Fun undo = [](){return true;};
Fun redo = [](){return true;};
bool result = requestClipUngroup(id, undo, redo);
if (result) {
PUSH_UNDO(undo, redo, i18n("Ungroup clips"));
}
return result;
}
bool TimelineModel::requestClipUngroup(int id, Fun& undo, Fun& redo)
{
return m_groups->ungroupItem(id, undo, redo);
}
bool TimelineModel::requestTrackInsertion(int position, int &id)
{
if (position == -1) {
......@@ -486,7 +491,13 @@ bool TimelineModel::requestTrackDeletion(int tid)
Fun undo = [](){return true;};
Fun redo = [](){return true;};
for(int clip : clips_to_delete) {
bool res = requestClipDeletion(clip, undo, redo);
bool res = true;
while (res && m_groups->isInGroup(clip)) {
res = requestClipUngroup(clip, undo, redo);
}
if (res) {
res = requestClipDeletion(clip, undo, redo);
}
if (!res) {
bool u = undo();
Q_ASSERT(u);
......
......@@ -207,6 +207,8 @@ public:
@param id of the clip to degroup (all clips belonging to the same group will be ungrouped as well)
*/
bool requestClipUngroup(int id);
/* Same function, but accumulates undo and redo*/
bool requestClipUngroup(int id, Fun& undo, Fun& redo);
/* @brief Create a track at given position
This action is undoable
......
......@@ -57,6 +57,34 @@ TEST_CASE("Basic creation/deletion of a track", "[TrackModel]")
REQUIRE(timeline->requestTrackDeletion(id2));
REQUIRE(timeline->getTracksCount() == 0);
SECTION("Delete a track with groups") {
int tid1, tid2;
REQUIRE(timeline->requestTrackInsertion(-1, tid1));
REQUIRE(timeline->requestTrackInsertion(-1, tid2));
std::shared_ptr<Mlt::Producer> producer = std::make_shared<Mlt::Producer>(profile_model, "color", "red");
producer->set("length", 20);
producer->set("out", 19);
int length = producer->get_playtime();
int cid1,cid2,cid3,cid4;
REQUIRE(timeline->requestClipInsertion(producer, tid1, 2, cid1));
REQUIRE(timeline->requestClipInsertion(producer, tid2, 0, cid2));
REQUIRE(timeline->requestClipInsertion(producer, tid2, length, cid3));
REQUIRE(timeline->requestClipInsertion(producer, tid2, 2*length, cid4));
REQUIRE(timeline->getClipsCount() == 4);
REQUIRE(timeline->getTracksCount() == 2);
auto g1 = std::unordered_set<int>({cid1, cid3});
auto g2 = std::unordered_set<int>({cid2, cid4});
auto g3 = std::unordered_set<int>({cid1, cid4});
REQUIRE(timeline->requestClipsGroup(g1));
REQUIRE(timeline->requestClipsGroup(g2));
REQUIRE(timeline->requestClipsGroup(g3));
REQUIRE(timeline->requestTrackDeletion(tid1));
REQUIRE(timeline->getClipsCount() == 3);
REQUIRE(timeline->getTracksCount() == 1);
}
}
......@@ -305,7 +333,6 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
}
SECTION("Clip Move"){
// // REQUIRE(timeline->allowClipMove(cid2, tid1, 5));
REQUIRE(timeline->requestClipMove(cid2, tid1, 5));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
......@@ -313,67 +340,42 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid2) == 5);
// // REQUIRE(timeline->allowClipMove(cid1, tid1, 5 + length));
REQUIRE(timeline->requestClipMove(cid1, tid1, 5 + length));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 5);
auto state = [&]() {
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 5);
};
state();
// // REQUIRE_FALSE(timeline->allowClipMove(cid1, tid1, 3 + length));
REQUIRE_FALSE(timeline->requestClipMove(cid1, tid1, 3 + length));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 5);
state();
// REQUIRE_FALSE(timeline->allowClipMove(cid1, tid1, 0));
REQUIRE_FALSE(timeline->requestClipMove(cid1, tid1, 0));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 5);
state();
// REQUIRE(timeline->allowClipMove(cid2, tid1, 0));
REQUIRE(timeline->requestClipMove(cid2, tid1, 0));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 0);
auto state2 = [&]() {
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 0);
};
state2();
// REQUIRE_FALSE(timeline->allowClipMove(cid1, tid1, 0));
REQUIRE_FALSE(timeline->requestClipMove(cid1, tid1, 0));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 0);
state2();
// REQUIRE_FALSE(timeline->allowClipMove(cid1, tid1, length - 5));
REQUIRE_FALSE(timeline->requestClipMove(cid1, tid1, length - 5));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid2) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5 + length);
REQUIRE(timeline->getClipPosition(cid2) == 0);
state2();
// REQUIRE(timeline->allowClipMove(cid1, tid1, length));
REQUIRE(timeline->requestClipMove(cid1, tid1, length));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
......@@ -406,7 +408,6 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
REQUIRE(timeline->getClipPosition(cid1) == length - 5);
REQUIRE(timeline->getClipPosition(cid2) == 5);
// REQUIRE_FALSE(timeline->allowClipMove(cid1, tid1, 0));
REQUIRE_FALSE(timeline->requestClipMove(cid1, tid1, 0));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
......@@ -414,7 +415,6 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
REQUIRE(timeline->getClipPosition(cid1) == length - 5);
REQUIRE(timeline->getClipPosition(cid2) == 5);
// REQUIRE(timeline->allowClipMove(cid2, tid1, 0));
REQUIRE(timeline->requestClipMove(cid2, tid1, 0));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
......@@ -897,14 +897,14 @@ TEST_CASE("Undo and Redo", "[ClipModel]")
};
state3();
REQUIRE(timeline->requestClipResize(cid1, 1, true));
REQUIRE(timeline->requestClipResize(cid3, 1, true));
auto state4 = [&]() {
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
REQUIRE(timeline->getClipTrackId(cid1) == tid1);
REQUIRE(timeline->getClipTrackId(cid3) == tid1);
REQUIRE(timeline->getClipPosition(cid1) == 5);
REQUIRE(timeline->getClipPlaytime(cid1) == 1);
REQUIRE(timeline->getClipPlaytime(cid3) == 1);
REQUIRE(timeline->getClipPosition(cid3) == 10 + length);
REQUIRE(undoStack->index() == init_index + 4);
};
......@@ -966,6 +966,9 @@ TEST_CASE("Undo and Redo", "[ClipModel]")
undoStack->redo();
state2();
undoStack->undo();
state1();
}
SECTION("Track insertion undo") {
......
......@@ -68,7 +68,7 @@ TEST_CASE("Regression2") {
undoStack->undo();
undoStack->undo();
undoStack->redo();
TrackModel::construct(timeline);
TrackModel::construct(timeline);
REQUIRE(timeline->getTrackById(0)->checkConsistency());
undoStack->undo();
REQUIRE(timeline->getTrackById(0)->checkConsistency());
......@@ -84,7 +84,7 @@ TEST_CASE("Regression2") {
REQUIRE(timeline->getTrackById(0)->checkConsistency());
undoStack->redo();
REQUIRE(timeline->getTrackById(0)->checkConsistency());
TrackModel::construct(timeline);
TrackModel::construct(timeline);
REQUIRE(timeline->getTrackById(0)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
{
......@@ -97,7 +97,7 @@ TEST_CASE("Regression2") {
REQUIRE(timeline->getTrackById(0)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
{
bool ok = timeline->requestClipMove(1,0 ,10 );
bool ok = timeline->requestClipMove(1,0 ,10 );
REQUIRE(ok);
}
REQUIRE(timeline->getTrackById(0)->checkConsistency());
......@@ -114,7 +114,7 @@ TEST_CASE("Regression2") {
}
REQUIRE(timeline->getTrackById(0)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
TrackModel::construct(timeline);
TrackModel::construct(timeline);
REQUIRE(timeline->getTrackById(0)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(4)->checkConsistency());
......@@ -125,7 +125,7 @@ TEST_CASE("Regression2") {
REQUIRE(timeline->getTrackById(0)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(4)->checkConsistency());
TrackModel::construct(timeline);
TrackModel::construct(timeline);
REQUIRE(timeline->getTrackById(0)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(4)->checkConsistency());
......@@ -139,7 +139,7 @@ TEST_CASE("Regression2") {
REQUIRE(timeline->getTrackById(4)->checkConsistency());
REQUIRE(timeline->getTrackById(6)->checkConsistency());
{
bool ok = timeline->requestClipMove(3,0 ,0 );
bool ok = timeline->requestClipMove(3,0 ,0 );
REQUIRE_FALSE(ok);
}
REQUIRE(timeline->getTrackById(0)->checkConsistency());
......@@ -195,3 +195,161 @@ TEST_CASE("Regression2") {
REQUIRE(timeline->getTrackById(6)->checkConsistency());
undoStack->redo();
}
TEST_CASE("Regression 3")
{
Mlt::Profile profile;
std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr);
std::shared_ptr<TimelineModel> timeline = TimelineItemModel::construct(undoStack);
TimelineModel::next_id = 0;
int dummy_id;
std::shared_ptr<Mlt::Producer> producer0 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer0->set("length", 20);
producer0->set("out", 19);
ClipModel::construct(timeline, producer0 );
{
bool ok = timeline->requestTrackInsertion(-1, dummy_id);
REQUIRE(ok);
}
TrackModel::construct(timeline);
TrackModel::construct(timeline);
std::shared_ptr<Mlt::Producer> producer1 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer1->set("length", 20);
producer1->set("out", 19);
ClipModel::construct(timeline, producer1 );
std::shared_ptr<Mlt::Producer> producer2 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer2->set("length", 20);
producer2->set("out", 19);
ClipModel::construct(timeline, producer2 );
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
std::shared_ptr<Mlt::Producer> producer3 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer3->set("length", 20);
producer3->set("out", 19);
ClipModel::construct(timeline, producer3 );
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
TrackModel::construct(timeline);
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
TrackModel::construct(timeline);
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
TrackModel::construct(timeline);
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
std::shared_ptr<Mlt::Producer> producer4 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer4->set("length", 20);
producer4->set("out", 19);
ClipModel::construct(timeline, producer4 );
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
std::shared_ptr<Mlt::Producer> producer5 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer5->set("length", 20);
producer5->set("out", 19);
ClipModel::construct(timeline, producer5 );
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
std::shared_ptr<Mlt::Producer> producer6 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer6->set("length", 20);
producer6->set("out", 19);
ClipModel::construct(timeline, producer6 );
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
{
bool ok = timeline->requestClipMove(0,1 ,10 );
REQUIRE(ok);
}
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
{
bool ok = timeline->requestClipMove(4,2 ,12 );
REQUIRE(ok);
}
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
{
auto group = {4, 0};
bool ok = timeline->requestClipsGroup(group);
REQUIRE(ok);
}
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
{
bool ok = timeline->requestClipMove(4,1 ,10 );
REQUIRE_FALSE(ok);
}
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
{
bool ok = timeline->requestClipMove(4,1 ,100 );
REQUIRE_FALSE(ok);
}
REQUIRE(timeline->getTrackById(1)->checkConsistency());
REQUIRE(timeline->getTrackById(2)->checkConsistency());
REQUIRE(timeline->getTrackById(3)->checkConsistency());
REQUIRE(timeline->getTrackById(7)->checkConsistency());
REQUIRE(timeline->getTrackById(8)->checkConsistency());
REQUIRE(timeline->getTrackById(9)->checkConsistency());
{
bool ok = timeline->requestClipMove(0,3 ,100 );
REQUIRE(ok);
}
std::shared_ptr<Mlt::Producer> producer7 = std::make_shared<Mlt::Producer>(profile, "color", "red");
producer7->set("length", 20);
producer7->set("out", 19);
ClipModel::construct(timeline, producer7 );
{
bool ok = timeline->requestTrackInsertion(-1, dummy_id);
REQUIRE(ok);
}
undoStack->undo();
{
bool ok = timeline->requestClipMove(0,1 ,5 );
REQUIRE(ok);
}
{
bool ok = timeline->requestTrackDeletion(1);
REQUIRE(ok);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment