Warning, file /multimedia/kdenlive/tests/sequencetest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2023 Jean-Baptiste Mardelle <jb@kdenlive.org> 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 #include "test_utils.hpp" 0006 // test specific headers 0007 #include "bin/binplaylist.hpp" 0008 #include "doc/kdenlivedoc.h" 0009 #include "timeline2/model/builders/meltBuilder.hpp" 0010 #include "xml/xml.hpp" 0011 0012 #include <QTemporaryFile> 0013 #include <QUndoGroup> 0014 0015 using namespace fakeit; 0016 0017 TEST_CASE("Test saving sequences elements", "[TSG]") 0018 { 0019 auto binModel = pCore->projectItemModel(); 0020 binModel->clean(); 0021 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0022 0023 SECTION("Group save") 0024 { 0025 // Create document 0026 KdenliveDoc document(undoStack); 0027 pCore->projectManager()->m_project = &document; 0028 QDateTime documentDate = QDateTime::currentDateTime(); 0029 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0030 auto timeline = document.getTimeline(document.uuid()); 0031 pCore->projectManager()->testSetActiveDocument(&document, timeline); 0032 KdenliveDoc::next_id = 0; 0033 QDir dir = QDir::temp(); 0034 0035 QString binId = createProducerWithSound(pCore->getProjectProfile(), binModel); 0036 QString binId2 = createProducer(pCore->getProjectProfile(), "red", binModel, 20, false); 0037 0038 int tid1 = timeline->getTrackIndexFromPosition(2); 0039 0040 // Setup timeline audio drop info 0041 QMap<int, QString> audioInfo; 0042 audioInfo.insert(1, QStringLiteral("stream1")); 0043 timeline->m_binAudioTargets = audioInfo; 0044 timeline->m_videoTarget = tid1; 0045 // Insert 2 clips (length=20, pos = 80 / 100) 0046 int cid1 = -1; 0047 REQUIRE(timeline->requestClipInsertion(binId2, tid1, 80, cid1, true, true, false)); 0048 int l = timeline->getClipPlaytime(cid1); 0049 int cid2 = -1; 0050 REQUIRE(timeline->requestClipInsertion(binId, tid1, 80 + l, cid2, true, true, false)); 0051 // Resize first clip (length=100) 0052 REQUIRE(timeline->requestItemResize(cid1, 100, false) == 100); 0053 0054 auto state = [&]() { 0055 REQUIRE(timeline->checkConsistency()); 0056 REQUIRE(timeline->getTrackClipsCount(tid1) == 2); 0057 REQUIRE(timeline->getClipTrackId(cid1) == tid1); 0058 REQUIRE(timeline->getClipTrackId(cid2) == tid1); 0059 REQUIRE(timeline->getClipPosition(cid1) == 0); 0060 REQUIRE(timeline->getClipPosition(cid2) == 100); 0061 REQUIRE(timeline->getClipPlaytime(cid1) == 100); 0062 REQUIRE(timeline->getClipPlaytime(cid2) == 10); 0063 }; 0064 state(); 0065 REQUIRE(timeline->checkConsistency()); 0066 pCore->projectManager()->testSaveFileAs(dir.absoluteFilePath(QStringLiteral("test.kdenlive"))); 0067 // Undo resize 0068 undoStack->undo(); 0069 // Undo first insert 0070 undoStack->undo(); 0071 // Undo second insert 0072 undoStack->undo(); 0073 pCore->projectManager()->closeCurrentDocument(false, false); 0074 // Reopen and check for groups 0075 QString saveFile = dir.absoluteFilePath(QStringLiteral("test.kdenlive")); 0076 QUrl openURL = QUrl::fromLocalFile(saveFile); 0077 0078 QUndoGroup *undoGroup = new QUndoGroup(&document); 0079 undoGroup->addStack(undoStack.get()); 0080 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0081 REQUIRE(openResults.isSuccessful() == true); 0082 0083 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0084 pCore->projectManager()->m_project = openedDoc.get(); 0085 const QUuid uuid = openedDoc->uuid(); 0086 documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0087 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0088 QMap<QUuid, QString> allSequences = binModel->getAllSequenceClips(); 0089 const QString firstSeqId = allSequences.value(uuid); 0090 pCore->projectManager()->openTimeline(firstSeqId, uuid); 0091 timeline = pCore->projectManager()->m_project->getTimeline(uuid); 0092 pCore->projectManager()->testSetActiveDocument(openedDoc.get(), timeline); 0093 REQUIRE(timeline->getTracksCount() == 4); 0094 REQUIRE(timeline->m_allGroups.size() == 1); 0095 timeline.reset(); 0096 pCore->projectManager()->closeCurrentDocument(false, false); 0097 } 0098 SECTION("Save / Load multiple sequences") 0099 { 0100 // Create document 0101 binModel->clean(); 0102 KdenliveDoc document(undoStack); 0103 pCore->projectManager()->m_project = &document; 0104 QDateTime documentDate = QDateTime::currentDateTime(); 0105 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0106 auto timeline = document.getTimeline(document.uuid()); 0107 pCore->projectManager()->testSetActiveDocument(&document, timeline); 0108 KdenliveDoc::next_id = 0; 0109 QDir dir = QDir::temp(); 0110 0111 QString binId = createProducerWithSound(pCore->getProjectProfile(), binModel); 0112 QString binId2 = createProducer(pCore->getProjectProfile(), "red", binModel, 20, false); 0113 0114 int tid1 = timeline->getTrackIndexFromPosition(2); 0115 0116 // Setup timeline audio drop info 0117 QMap<int, QString> audioInfo; 0118 audioInfo.insert(1, QStringLiteral("stream1")); 0119 timeline->m_binAudioTargets = audioInfo; 0120 timeline->m_videoTarget = tid1; 0121 // Insert 2 clips (length=20, pos = 80 / 100) 0122 int cid1 = -1; 0123 REQUIRE(timeline->requestClipInsertion(binId2, tid1, 80, cid1, true, true, false)); 0124 int l = timeline->getClipPlaytime(cid1); 0125 int cid2 = -1; 0126 REQUIRE(timeline->requestClipInsertion(binId, tid1, 80 + l, cid2, true, true, false)); 0127 // Resize first clip (length=100) 0128 REQUIRE(timeline->requestItemResize(cid1, 100, false) == 100); 0129 0130 auto state = [&]() { 0131 REQUIRE(timeline->checkConsistency()); 0132 REQUIRE(timeline->getTrackClipsCount(tid1) == 2); 0133 REQUIRE(timeline->getClipTrackId(cid1) == tid1); 0134 REQUIRE(timeline->getClipTrackId(cid2) == tid1); 0135 REQUIRE(timeline->getClipPosition(cid1) == 0); 0136 REQUIRE(timeline->getClipPosition(cid2) == 100); 0137 REQUIRE(timeline->getClipPlaytime(cid1) == 100); 0138 REQUIRE(timeline->getClipPlaytime(cid2) == 10); 0139 }; 0140 state(); 0141 REQUIRE(timeline->checkConsistency()); 0142 // Add secondary timeline 0143 const QString seq2 = ClipCreator::createPlaylistClip(QStringLiteral("Sequence2"), {2, 2}, QString("-1"), binModel); 0144 QMap<QUuid, QString> uids = pCore->projectItemModel()->getAllSequenceClips(); 0145 QUuid secondaryUuid; 0146 QMapIterator<QUuid, QString> i(uids); 0147 while (i.hasNext()) { 0148 i.next(); 0149 if (i.value() == seq2) { 0150 secondaryUuid = i.key(); 0151 break; 0152 } 0153 } 0154 auto timeline2 = pCore->currentDoc()->getTimeline(secondaryUuid); 0155 pCore->projectManager()->m_activeTimelineModel = timeline2; 0156 tid1 = timeline2->getTrackIndexFromPosition(2); 0157 // Setup timeline audio drop info 0158 QMap<int, QString> audioInfo2; 0159 audioInfo2.insert(1, QStringLiteral("stream1")); 0160 timeline2->m_binAudioTargets = audioInfo; 0161 timeline2->m_videoTarget = tid1; 0162 0163 int cid3 = -1; 0164 REQUIRE(timeline2->requestClipInsertion(binId, tid1, 80 + l, cid3, true, true, false)); 0165 int cid4 = -1; 0166 REQUIRE(timeline2->requestClipInsertion(binId, tid1, 160 + l, cid4, true, true, false)); 0167 0168 pCore->projectManager()->m_activeTimelineModel = timeline; 0169 0170 pCore->projectManager()->testSaveFileAs(dir.absoluteFilePath(QStringLiteral("test.kdenlive"))); 0171 timeline.reset(); 0172 timeline2.reset(); 0173 pCore->projectManager()->closeCurrentDocument(false, false); 0174 0175 // Reopen and check for groups 0176 QString saveFile = dir.absoluteFilePath(QStringLiteral("test.kdenlive")); 0177 QUrl openURL = QUrl::fromLocalFile(saveFile); 0178 0179 QUndoGroup *undoGroup = new QUndoGroup(&document); 0180 undoGroup->addStack(undoStack.get()); 0181 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0182 REQUIRE(openResults.isSuccessful() == true); 0183 0184 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0185 pCore->projectManager()->m_project = openedDoc.get(); 0186 QUuid uuid = openedDoc->uuid(); 0187 documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0188 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0189 QMap<QUuid, QString> allSequences = binModel->getAllSequenceClips(); 0190 QString firstSeqId = allSequences.value(uuid); 0191 QString secondSeqId = allSequences.value(secondaryUuid); 0192 pCore->projectManager()->openTimeline(firstSeqId, uuid); 0193 timeline = pCore->currentDoc()->getTimeline(uuid); 0194 pCore->projectManager()->testSetActiveDocument(openedDoc.get(), timeline); 0195 REQUIRE(timeline->getTracksCount() == 4); 0196 REQUIRE(timeline->m_allGroups.size() == 1); 0197 // pCore->projectManager()->openTimeline(secondSeqId, secondaryUuid); 0198 timeline2 = pCore->currentDoc()->getTimeline(secondaryUuid); 0199 Q_ASSERT(timeline2 != nullptr); 0200 REQUIRE(timeline2->getTracksCount() == 4); 0201 REQUIRE(timeline2->m_allGroups.size() == 2); 0202 std::shared_ptr<ProjectClip> sequenceClip = binModel->getClipByBinID(secondSeqId); 0203 REQUIRE(sequenceClip->clipName() == QLatin1String("Sequence2")); 0204 pCore->projectManager()->m_activeTimelineModel = timeline; 0205 // Save again without any changes 0206 pCore->projectManager()->testSaveFileAs(dir.absoluteFilePath(QStringLiteral("test.kdenlive"))); 0207 sequenceClip.reset(); 0208 timeline2.reset(); 0209 timeline.reset(); 0210 pCore->projectManager()->closeCurrentDocument(false, false); 0211 0212 // Reopen test project and check closed sequence properties 0213 DocOpenResult openResults2 = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0214 REQUIRE(openResults2.isSuccessful() == true); 0215 0216 std::unique_ptr<KdenliveDoc> openedDoc2 = openResults2.getDocument(); 0217 pCore->projectManager()->m_project = openedDoc2.get(); 0218 uuid = openedDoc2->uuid(); 0219 documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0220 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0221 allSequences = binModel->getAllSequenceClips(); 0222 firstSeqId = allSequences.value(uuid); 0223 secondSeqId = allSequences.value(secondaryUuid); 0224 pCore->projectManager()->openTimeline(firstSeqId, uuid); 0225 timeline = pCore->currentDoc()->getTimeline(uuid); 0226 pCore->projectManager()->testSetActiveDocument(openedDoc2.get(), timeline); 0227 REQUIRE(timeline->getTracksCount() == 4); 0228 REQUIRE(timeline->m_allGroups.size() == 1); 0229 timeline2 = pCore->currentDoc()->getTimeline(secondaryUuid); 0230 qDebug() << "::: LOOKIG FOR UUID: " << secondaryUuid << ", ALL SEQS: " << allSequences.keys(); 0231 Q_ASSERT(timeline2 != nullptr); 0232 REQUIRE(timeline2->getTracksCount() == 4); 0233 REQUIRE(timeline2->m_allGroups.size() == 2); 0234 sequenceClip = binModel->getClipByBinID(secondSeqId); 0235 REQUIRE(sequenceClip->clipName() == QLatin1String("Sequence2")); 0236 sequenceClip.reset(); 0237 timeline2.reset(); 0238 timeline.reset(); 0239 pCore->projectManager()->closeCurrentDocument(false, false); 0240 } 0241 }