File indexing completed on 2025-04-13 04:29:48
0001 /* 0002 SPDX-FileCopyrightText: 2022 Jean-Baptiste Mardelle <jb@kdenlive.org> 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 #include "catch.hpp" 0006 #include "test_utils.hpp" 0007 // test specific headers 0008 #include "core.h" 0009 #include "definitions.h" 0010 #include "doc/docundostack.hpp" 0011 #include "doc/kdenlivedoc.h" 0012 0013 using namespace fakeit; 0014 0015 TEST_CASE("Remove all spaces", "[Spacer]") 0016 { 0017 // Create timeline 0018 auto binModel = pCore->projectItemModel(); 0019 binModel->clean(); 0020 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0021 0022 // Here we do some trickery to enable testing. 0023 KdenliveDoc document(undoStack, {1, 2}); 0024 pCore->projectManager()->m_project = &document; 0025 QDateTime documentDate = QDateTime::currentDateTime(); 0026 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0027 auto timeline = document.getTimeline(document.uuid()); 0028 pCore->projectManager()->m_activeTimelineModel = timeline; 0029 pCore->projectManager()->testSetActiveDocument(&document, timeline); 0030 0031 int tid1 = timeline->getTrackIndexFromPosition(2); 0032 int tid2 = timeline->getTrackIndexFromPosition(1); 0033 0034 // Create clip with audio (40 frames long) 0035 QString binId = createProducer(pCore->getProjectProfile(), "red", binModel, 20); 0036 QString avBinId = createProducerWithSound(pCore->getProjectProfile(), binModel, 100); 0037 0038 // Setup insert stream data 0039 QMap<int, QString> audioInfo; 0040 audioInfo.insert(1, QStringLiteral("stream1")); 0041 timeline->m_binAudioTargets = audioInfo; 0042 0043 // Create clips in timeline 0044 int cid1; 0045 int cid2; 0046 int cid3; 0047 int cid4; 0048 REQUIRE(timeline->requestClipInsertion(binId, tid1, 10, cid1)); 0049 REQUIRE(timeline->requestClipInsertion(binId, tid1, 80, cid2)); 0050 REQUIRE(timeline->requestClipInsertion(binId, tid1, 101, cid3)); 0051 REQUIRE(timeline->requestClipInsertion(binId, tid2, 20, cid4)); 0052 0053 auto state1 = [&]() { 0054 REQUIRE(timeline->checkConsistency()); 0055 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0056 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0057 REQUIRE(timeline->getClipsCount() == 4); 0058 REQUIRE(timeline->getClipPosition(cid1) == 10); 0059 REQUIRE(timeline->getClipPosition(cid2) == 80); 0060 REQUIRE(timeline->getClipPosition(cid3) == 101); 0061 REQUIRE(timeline->getClipPosition(cid4) == 20); 0062 }; 0063 0064 SECTION("Ensure remove spaces behaves correctly") 0065 { 0066 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0067 // One clip at 20 on track 2 0068 REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 20)); 0069 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0070 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0071 REQUIRE(timeline->getClipsCount() == 4); 0072 REQUIRE(timeline->getClipPosition(cid1) == 10); 0073 REQUIRE(timeline->getClipPosition(cid2) == 30); 0074 REQUIRE(timeline->getClipPosition(cid3) == 50); 0075 REQUIRE(timeline->getClipPosition(cid4) == 20); 0076 undoStack->undo(); 0077 state1(); 0078 } 0079 SECTION("Ensure remove spaces behaves correctly with a group") 0080 { 0081 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0082 // One clip at 20 on track 2 0083 std::unordered_set<int> ids = {cid2, cid3}; 0084 int gid = timeline->requestClipsGroup(ids); 0085 REQUIRE(gid > -1); 0086 REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 20)); 0087 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0088 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0089 REQUIRE(timeline->getClipsCount() == 4); 0090 REQUIRE(timeline->getClipPosition(cid1) == 10); 0091 REQUIRE(timeline->getClipPosition(cid2) == 30); 0092 REQUIRE(timeline->getClipPosition(cid3) == 51); 0093 REQUIRE(timeline->getClipPosition(cid4) == 20); 0094 undoStack->undo(); 0095 state1(); 0096 undoStack->undo(); 0097 } 0098 SECTION("Ensure remove spaces behaves correctly with a group on different tracks") 0099 { 0100 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0101 // One clip at 20 on track 2 0102 // Grouping clip at 80 on tid1 and at 20 on tid2, so the group move will be rejected for the 80 clip 0103 std::unordered_set<int> ids = {cid2, cid4}; 0104 int gid = timeline->requestClipsGroup(ids); 0105 REQUIRE(gid > -1); 0106 REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 20)); 0107 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0108 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0109 REQUIRE(timeline->getClipsCount() == 4); 0110 REQUIRE(timeline->getClipPosition(cid1) == 10); 0111 REQUIRE(timeline->getClipPosition(cid2) == 80); 0112 REQUIRE(timeline->getClipPosition(cid3) == 100); 0113 REQUIRE(timeline->getClipPosition(cid4) == 20); 0114 undoStack->undo(); 0115 state1(); 0116 undoStack->undo(); 0117 } 0118 SECTION("Ensure remove spaces behaves correctly with a group on different tracks") 0119 { 0120 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0121 // One clip at 20 on track 2 0122 // Grouping clip at 10 on tid1 and at 20 on tid2, so the clip on tid2 will be moved 0123 std::unordered_set<int> ids = {cid1, cid4}; 0124 int gid = timeline->requestClipsGroup(ids); 0125 REQUIRE(gid > -1); 0126 REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 0)); 0127 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0128 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0129 REQUIRE(timeline->getClipsCount() == 4); 0130 REQUIRE(timeline->getClipPosition(cid1) == 0); 0131 REQUIRE(timeline->getClipPosition(cid2) == 20); 0132 REQUIRE(timeline->getClipPosition(cid3) == 40); 0133 REQUIRE(timeline->getClipPosition(cid4) == 10); 0134 undoStack->undo(); 0135 state1(); 0136 undoStack->undo(); 0137 } 0138 SECTION("Ensure remove all clips on track behaves correctly") 0139 { 0140 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0141 // One clip at 20 on track 2 0142 // Grouping clip at 10 on tid1 and at 20 on tid2, so the clip on tid2 will be moved 0143 std::unordered_set<int> ids = {cid1, cid4}; 0144 int gid = timeline->requestClipsGroup(ids); 0145 REQUIRE(gid > -1); 0146 REQUIRE(TimelineFunctions::requestDeleteAllClipsFrom(timeline, tid1, 80)); 0147 REQUIRE(timeline->getTrackClipsCount(tid1) == 1); 0148 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0149 undoStack->undo(); 0150 state1(); 0151 REQUIRE(TimelineFunctions::requestDeleteAllClipsFrom(timeline, tid1, 20)); 0152 REQUIRE(timeline->getTrackClipsCount(tid1) == 0); 0153 REQUIRE(timeline->getTrackClipsCount(tid2) == 0); 0154 undoStack->undo(); 0155 state1(); 0156 undoStack->undo(); 0157 } 0158 SECTION("Ensure delete blank works correctly with grouped clips") 0159 { 0160 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0161 // One clip at 20 on track 2 0162 // Grouping clip at 80 and 101 on tid1 0163 std::unordered_set<int> ids = {cid2, cid3}; 0164 int gid = timeline->requestClipsGroup(ids); 0165 REQUIRE(gid > -1); 0166 REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 80, false) == false); 0167 REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 70, false)); 0168 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0169 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0170 REQUIRE(timeline->getClipPosition(cid1) == 10); 0171 REQUIRE(timeline->getClipPosition(cid2) == 30); 0172 REQUIRE(timeline->getClipPosition(cid3) == 51); 0173 REQUIRE(timeline->getClipPosition(cid4) == 20); 0174 undoStack->undo(); 0175 state1(); 0176 // Delete space between 2 grouped clips, should fail 0177 REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 100, false) == false); 0178 undoStack->undo(); 0179 } 0180 SECTION("Ensure delete blank works correctly with ungrouped clips") 0181 { 0182 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0183 // One clip at 20 on track 2 0184 REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 5, false)); 0185 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0186 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0187 REQUIRE(timeline->getClipPosition(cid1) == 0); 0188 REQUIRE(timeline->getClipPosition(cid2) == 70); 0189 REQUIRE(timeline->getClipPosition(cid3) == 91); 0190 REQUIRE(timeline->getClipPosition(cid4) == 20); 0191 undoStack->undo(); 0192 REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 5, true)); 0193 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0194 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0195 REQUIRE(timeline->getClipPosition(cid1) == 0); 0196 REQUIRE(timeline->getClipPosition(cid2) == 70); 0197 REQUIRE(timeline->getClipPosition(cid3) == 91); 0198 REQUIRE(timeline->getClipPosition(cid4) == 10); 0199 undoStack->undo(); 0200 REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 60, false)); 0201 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0202 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0203 REQUIRE(timeline->getClipPosition(cid1) == 10); 0204 REQUIRE(timeline->getClipPosition(cid2) == 30); 0205 REQUIRE(timeline->getClipPosition(cid3) == 51); 0206 REQUIRE(timeline->getClipPosition(cid4) == 20); 0207 undoStack->undo(); 0208 state1(); 0209 } 0210 SECTION("Insert space test with ungrouped clips") 0211 { 0212 // We have clips at 10, 80, 101 on track 1 (length 20 frames each) 0213 // One clip at 20 on track 2 0214 // operation on one track (tid1) 0215 std::pair<int, int> spacerOp = TimelineFunctions::requestSpacerStartOperation(timeline, tid1, 40); 0216 int cid = spacerOp.first; 0217 REQUIRE(cid > -1); 0218 Fun undo = []() { return true; }; 0219 Fun redo = []() { return true; }; 0220 int start = timeline->getItemPosition(cid); 0221 REQUIRE(TimelineFunctions::requestSpacerEndOperation(timeline, cid, start, start + 100, tid1, -1, undo, redo)); 0222 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0223 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0224 REQUIRE(timeline->getClipPosition(cid1) == 10); 0225 REQUIRE(timeline->getClipPosition(cid2) == 180); 0226 REQUIRE(timeline->getClipPosition(cid3) == 201); 0227 REQUIRE(timeline->getClipPosition(cid4) == 20); 0228 undoStack->undo(); 0229 state1(); 0230 // operation on all tracks 0231 /*spacerOp = TimelineFunctions::requestSpacerStartOperation(timeline, -1, 35); 0232 cid = spacerOp.first; 0233 REQUIRE(cid > -1); 0234 start = timeline->getItemPosition(cid); 0235 REQUIRE(TimelineFunctions::requestSpacerEndOperation(timeline, cid, start, start + 100, -1, -1, undo, redo)); 0236 REQUIRE(timeline->getTrackClipsCount(tid1) == 3); 0237 REQUIRE(timeline->getTrackClipsCount(tid2) == 1); 0238 REQUIRE(timeline->getClipPosition(cid1) == 10); 0239 REQUIRE(timeline->getClipPosition(cid2) == 180); 0240 REQUIRE(timeline->getClipPosition(cid3) == 201); 0241 REQUIRE(timeline->getClipPosition(cid4) == 120); 0242 undoStack->undo(); 0243 state1();*/ 0244 } 0245 pCore->projectManager()->closeCurrentDocument(false, false); 0246 }