Commit 2ea5bdcd authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Start implementing clip move when same track transition is active

parent c008bf1a
......@@ -611,36 +611,40 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
}
Fun move_mix = []() { return true; };
Fun restore_mix = []() { return true; };
if (m_allClips[clipId]->getMixDuration() > 0) {
std::pair<int, int> mixData = getTrackById_const(old_trackId)->getMixInfo(clipId);
int offset = position - mixData.first;
qDebug()<<"==== MIX UPDATED: "<<mixData.second<<", OFFSET: "<<offset;
if (old_trackId != trackId || position >= mixData.first + mixData.second) {;
// Clip moved to another track, or outside of mix duration, delete mix
move_mix = [this, old_trackId, clipId]() {
qDebug()<<"======\nRESETTING SUB PLAYLIST\n====";
return getTrackById_const(old_trackId)->deleteMix(clipId);
};
restore_mix = [this, old_trackId, clipId, mixData]() {
return getTrackById_const(old_trackId)->createMix(clipId, mixData);
};
qDebug()<<"========\n\n\nDELETED MIX\n\n================";
move_mix();
UPDATE_UNDO_REDO(move_mix, restore_mix, local_undo, local_redo);
} else if (old_trackId == trackId) {
// Clip moved on same track, resize mix
move_mix = [this, old_trackId, clipId, position]() {
return getTrackById_const(old_trackId)->resizeMix(clipId, position);
};
restore_mix = [this, old_trackId, clipId, position]() {
return getTrackById_const(old_trackId)->resizeMix(clipId, position);
};
if (isTrack(old_trackId) && getTrackById_const(old_trackId)->hasMix(clipId)) {
std::pair<MixInfo, MixInfo> mixData = getTrackById_const(old_trackId)->getMixInfo(clipId);
if (mixData.first.firstClipId > -1) {
// We have a mix at clip start
if (old_trackId != trackId || position >= mixData.first.firstClipInOut.second) {
// Clip moved to another track, or outside of mix duration, delete mix
move_mix = [this, old_trackId, clipId, finalMove]() {
bool result = getTrackById_const(old_trackId)->deleteMix(clipId, finalMove);
qDebug()<<"======\nRESETTING SUB PLAYLIST, RESULT: "<<result<<"\n====";
return result;
};
restore_mix = [this, old_trackId, mixData]() {
qDebug()<<"================0\nSTART RESTORING MIX\n\n================";
m_allClips[mixData.first.secondClipId]->setSubPlaylistIndex(1);
bool result = getTrackById_const(old_trackId)->createMix({mixData.first.firstClipId,mixData.first.secondClipId}, {mixData.first.secondClipInOut.first, mixData.first.firstClipInOut.second - mixData.first.secondClipInOut.first});
qDebug()<<"====================\nCREATED MIX ON UNDO: "<<result<<"\n\n========";
return result;
};
} else if (old_trackId == trackId) {
// Clip moved on same track, resize mix
move_mix = [this, old_trackId, clipId, position]() {
qDebug()<<"================0\nMIX RESIZE PROCESS 1\n\n================";
return getTrackById_const(old_trackId)->resizeMixStart(clipId, position);
};
restore_mix = [this, old_trackId, clipId, mixData]() {
// Resize mix to oringinal start
qDebug()<<"================0\nMIX RESIZE PROCESS 2\n\n================";
return getTrackById_const(old_trackId)->resizeMixStart(clipId, mixData.first.secondClipInOut.first);
};
}
move_mix();
UPDATE_UNDO_REDO(move_mix, restore_mix, local_undo, local_redo);
}
}
if (old_trackId != -1) {
if (notifyViewOnly) {
PUSH_LAMBDA(update_model, local_undo);
......@@ -1216,6 +1220,11 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
++it;
}
}
if (useTargets && allowedTracks.isEmpty()) {
pCore->displayMessage(i18n("No available track for insert operation"), InformationMessage, 500);
qDebug()<<"//////\nNO ACTIVE TRACK FOUND";
return false;
}
bool result = requestClipInsertion(binClipId, trackId, position, id, logUndo, refreshView, useTargets, undo, redo, allowedTracks);
if (result && logUndo) {
PUSH_UNDO(undo, redo, i18n("Insert Clip"));
......@@ -1476,6 +1485,7 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
}
} else {
std::shared_ptr<ProjectClip> binClip = pCore->projectItemModel()->getClipByBinID(bid);
qDebug() << "++++++++++++++++++\n\nCLIP INSERT TYPE 2 on TID: "<<trackId<<"\n\n+++++++++++++++++++";
if (dropType == PlaylistState::Disabled) {
dropType = getTrackById_const(trackId)->trackType();
} else if (dropType != getTrackById_const(trackId)->trackType()) {
......
......@@ -137,9 +137,9 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
if (auto ptr = m_parent.lock()) {
Q_ASSERT(ptr->getClipPtr(clipId)->getCurrentTrackId() == -1);
target_playlist = ptr->getClipPtr(clipId)->getSubPlaylistIndex();
if (target_playlist == 1 && ptr->getClipPtr(clipId)->getMixDuration() == 0) {
/*if (target_playlist == 1 && ptr->getClipPtr(clipId)->getMixDuration() == 0) {
target_playlist = 0;
}
}*/
qDebug()<<"==== GOT TRARGET PLAYLIST: "<<target_playlist;
} else {
qDebug() << "impossible to get parent timeline";
......@@ -156,7 +156,9 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
m_allClips[clip->getId()] = clip; // store clip
// update clip position and track
clip->setPosition(position);
clip->setSubPlaylistIndex(subPlaylist);
if (finalMove) {
clip->setSubPlaylistIndex(subPlaylist);
}
int new_in = clip->getPosition();
int new_out = new_in + clip->getPlaytime();
ptr->m_snaps->addPoint(new_in);
......@@ -1377,10 +1379,9 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
// Find out the clip id at position
int secondClipPos;
int secondClipDuration;
int firstClipPos;
int firstClipDuration;
int source_track;
MixInfo mixInfo;
int mixPosition;
qDebug()<<"=========MIXING CLIPS: "<<clipIds;
if (auto ptr = m_parent.lock()) {
// The clip that will be moved to playlist 1
......@@ -1390,10 +1391,7 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
source_track = secondClip->getSubPlaylistIndex();
std::shared_ptr<ClipModel> firstClip(ptr->getClipPtr(clipIds.first));
firstClipDuration = firstClip->getPlaytime();
firstClipPos = firstClip->getPosition();
mixInfo.mixPosition = secondClipPos - mixDuration;
mixInfo.mixDuration = mixDuration * 2;
secondClip->setMixDuration(mixInfo.mixDuration);
mixPosition = secondClipPos - mixDuration;
} else {
// Error, timeline unavailable
return false;
......@@ -1405,28 +1403,28 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
}
// Create mix compositing
Fun build_mix = [clipIds, mixInfo, this]() {
Fun build_mix = [clipIds, mixPosition, mixDuration, this]() {
if (auto ptr = m_parent.lock()) {
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipIds.second));
movedClip->setMixDuration(mixInfo.mixDuration);
movedClip->setMixDuration(mixDuration * 2);
// Insert mix transition
if (isAudioTrack()) {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "mix"));
t->set_in_and_out(mixInfo.mixPosition, mixInfo.mixPosition + mixInfo.mixDuration);
t->set_in_and_out(mixPosition, mixPosition + 2 * mixDuration);
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
} else {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "luma"));
t->set_in_and_out(mixInfo.mixPosition, mixInfo.mixPosition + mixInfo.mixDuration);
qDebug()<<"==== INSERTING MIX: : "<<mixInfo.mixPosition<<" - "<<(mixInfo.mixPosition + mixInfo.mixDuration);
t->set_in_and_out(mixPosition, mixPosition + 2 * mixDuration);
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
}
m_mixList.insert(clipIds.first, clipIds.second);
}
return true;
};
Fun destroy_mix = [clipIds, mixInfo, this]() {
Fun destroy_mix = [clipIds, this]() {
if (auto ptr = m_parent.lock()) {
Mlt::Transition &transition = *m_sameCompositions[clipIds.second].get();
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipIds.second));
......@@ -1438,6 +1436,7 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
field->disconnect_service(transition);
field->unlock();
m_sameCompositions.erase(clipIds.second);
m_mixList.remove(clipIds.first);
}
return true;
};
......@@ -1453,15 +1452,17 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
build_mix();
auto op = requestClipInsertion_lambda(clipIds.second, secondClipPos, updateView, finalMove, groupMove);
bool result = op();
std::function<bool(void)> local_undo = []() { return true; };
std::function<bool(void)> local_redo = []() { return true; };
if (auto ptr = m_parent.lock()) {
result = ptr->getClipPtr(clipIds.second)->requestResize(secondClipDuration + mixDuration, false, local_undo, local_redo, false);
result = ptr->getClipPtr(clipIds.first)->requestResize(firstClipDuration + mixDuration, true, local_undo, local_redo, false);
QModelIndex ix = ptr->makeClipIndexFromID(clipIds.second);
emit ptr->dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole});
if (result) {
std::function<bool(void)> local_undo = []() { return true; };
std::function<bool(void)> local_redo = []() { return true; };
if (auto ptr = m_parent.lock()) {
result = ptr->getClipPtr(clipIds.second)->requestResize(secondClipDuration + mixDuration, false, local_undo, local_redo, false);
result = ptr->getClipPtr(clipIds.first)->requestResize(firstClipDuration + mixDuration, true, local_undo, local_redo, false);
QModelIndex ix = ptr->makeClipIndexFromID(clipIds.second);
emit ptr->dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole});
}
}
return true;
return result;
};
Fun reverse = [this, clipIds, source_track, secondClipDuration, firstClipDuration, destroy_mix, secondClipPos, updateView, finalMove, groupMove, operation]() {
......@@ -1495,66 +1496,103 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
}
std::pair<int, int> TrackModel::getMixInfo(int clipId) const
std::pair<MixInfo, MixInfo> TrackModel::getMixInfo(int clipId) const
{
std::pair<int, int> result = {0,0};
std::pair<MixInfo, MixInfo> result;
MixInfo startMix;
MixInfo endMix;
if (m_sameCompositions.count(clipId) > 0) {
result.first = m_sameCompositions.at(clipId)->get_in();
result.second = m_sameCompositions.at(clipId)->get_out() - result.first;
// There is a mix at clip start
startMix.firstClipId = m_mixList.key(clipId, -1);
startMix.secondClipId = clipId;
if (auto ptr = m_parent.lock()) {
std::shared_ptr<ClipModel> clip1 = ptr->getClipPtr(startMix.firstClipId);
std::shared_ptr<ClipModel> clip2 = ptr->getClipPtr(startMix.secondClipId);
startMix.firstClipInOut.first = clip1->getPosition();
startMix.firstClipInOut.second = startMix.firstClipInOut.first + clip1->getPlaytime();
startMix.secondClipInOut.first = clip2->getPosition();
startMix.secondClipInOut.second = startMix.secondClipInOut.first + clip2->getPlaytime();
}
} else {
startMix.firstClipId = -1;
}
int secondClip = m_mixList.value(clipId, -1);
if (secondClip > -1) {
// There is a mix at clip end
endMix.firstClipId = clipId;
endMix.secondClipId = secondClip;
if (auto ptr = m_parent.lock()) {
std::shared_ptr<ClipModel> clip1 = ptr->getClipPtr(endMix.firstClipId);
std::shared_ptr<ClipModel> clip2 = ptr->getClipPtr(endMix.secondClipId);
endMix.firstClipInOut.first = clip1->getPosition();
endMix.firstClipInOut.second = endMix.firstClipInOut.first + clip1->getPlaytime();
endMix.secondClipInOut.first = clip2->getPosition();
endMix.secondClipInOut.second = endMix.secondClipInOut.first + clip2->getPlaytime();
}
} else {
endMix.firstClipId = -1;
}
result = {startMix, endMix};
return result;
}
bool TrackModel::deleteMix(int clipId)
bool TrackModel::deleteMix(int clipId, bool final)
{
qDebug()<<"=== DELETING MIX FROM CLIP: "<<clipId;
if (m_sameCompositions.count(clipId) <= 0) {
return false;
}
if (auto ptr = m_parent.lock()) {
Mlt::Transition &transition = *m_sameCompositions[clipId].get();
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipId));
movedClip->setMixDuration(0);
movedClip->setMixDuration(final ? 0 : 1);
QModelIndex ix = ptr->makeClipIndexFromID(clipId);
emit ptr->dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole});
QScopedPointer<Mlt::Field> field(m_track->field());
field->lock();
field->disconnect_service(transition);
field->unlock();
m_sameCompositions.erase(clipId);
if (final) {
Mlt::Transition &transition = *m_sameCompositions[clipId].get();
QScopedPointer<Mlt::Field> field(m_track->field());
field->lock();
field->disconnect_service(transition);
field->unlock();
m_sameCompositions.erase(clipId);
int firstClip = m_mixList.key(clipId, -1);
if (firstClip > -1) {
m_mixList.remove(firstClip);
}
}
return true;
}
return false;
}
bool TrackModel::createMix(int clipId, std::pair<int, int> mixData)
bool TrackModel::createMix(std::pair<int, int> clipIds, std::pair<int, int> mixData)
{
if (m_sameCompositions.count(clipId) > 0) {
if (m_sameCompositions.count(clipIds.second) > 0) {
return false;
}
if (auto ptr = m_parent.lock()) {
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipId));
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipIds.second));
movedClip->setMixDuration(mixData.second);
QModelIndex ix = ptr->makeClipIndexFromID(clipId);
QModelIndex ix = ptr->makeClipIndexFromID(clipIds.second);
emit ptr->dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole});
// Insert mix transition
if (isAudioTrack()) {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "mix"));
t->set_in_and_out(mixData.first, mixData.first + mixData.second);
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipId] = t;
m_sameCompositions[clipIds.second] = t;
} else {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "luma"));
t->set_in_and_out(mixData.first, mixData.first + mixData.second);
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipId] = t;
m_sameCompositions[clipIds.second] = t;
}
m_mixList.insert(clipIds.first, clipIds.second);
return true;
}
return false;
}
bool TrackModel::resizeMix(int clipId, int position)
bool TrackModel::resizeMixStart(int clipId, int position)
{
if (m_sameCompositions.count(clipId) <= 0) {
return false;
......@@ -1574,3 +1612,40 @@ bool TrackModel::resizeMix(int clipId, int position)
return false;
}
bool TrackModel::resizeMixEnd(int clipId, int position)
{
int secondClip = m_mixList.value(clipId, -1);
if (secondClip == -1) {
return false;
}
if (auto ptr = m_parent.lock()) {
Mlt::Transition &transition = *m_sameCompositions[secondClip].get();
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(secondClip));
int in = transition.get_in();
int out = position;
transition.set_in_and_out(in, out);
int updatedDuration = out - in;
movedClip->setMixDuration(qMax(1, updatedDuration));
QModelIndex ix = ptr->makeClipIndexFromID(secondClip);
emit ptr->dataChanged(ix, ix, {TimelineModel::MixRole});
return true;
}
return false;
}
int TrackModel::mixCount() const
{
Q_ASSERT(m_mixList.size() == (int) m_sameCompositions.size());
return m_mixList.size();
}
bool TrackModel::hasMix(int cid) const
{
if (m_mixList.contains(cid)) {
return true;
}
if (m_mixList.key(cid, -1) >= 0) {
return true;
}
return false;
}
......@@ -39,15 +39,12 @@ class EffectStackModel;
class MixInfo
{
public:
int firstClipId;
int secondClipId;
int firstClipOut;
int secondClipIn;
int secondClipDuration;
int mixPosition;
int mixDuration;
std::pair<int, int> firstClipInOut;
std::pair<int, int> secondClipInOut;
std::pair<int, int> mixInOut;
};
/* @brief This class represents a Track object, as viewed by the backend.
......@@ -124,14 +121,16 @@ public:
void setProperty(const QString &name, const QString &value);
/** @brief Create a composition between 2 same track clips */
bool requestClipMix(std::pair<int, int> clipIds, int mixDuration, bool updateView, bool finalMove, Fun &undo, Fun &redo, bool groupMove);
/** @brief Get in/out position for mix composition */
std::pair<int, int> getMixInfo(int position) const;
/** @brief Get clip ids and in/out position for mixes in this clip */
std::pair<MixInfo, MixInfo> getMixInfo(int cid) const;
/** @brief Delete a mix composition */
bool deleteMix(int clipId);
bool deleteMix(int clipId, bool final);
/** @brief Create a mix composition */
bool createMix(int clipId, std::pair<int, int> mixData);
/** @brief Resize a mix composition */
bool resizeMix(int clipId, int offset);
bool createMix(std::pair<int, int> clipIds, std::pair<int, int> mixData);
/** @brief Resize a mix composition start pos */
bool resizeMixStart(int clipId, int offset);
/** @brief Resize a mix composition end pos */
bool resizeMixEnd(int clipId, int position);
protected:
/* @brief This will lock the track: it will no longer allow insertion/deletion/resize of items
......@@ -291,6 +290,10 @@ protected:
bool copyEffect(const std::shared_ptr<EffectStackModel> &stackModel, int rowId);
/* @brief Returns true if we have a blank at position for duration */
bool isAvailable(int position, int duration);
/* @brief Returns the number of same track transitions (mix) in this track */
int mixCount() const;
/* @brief Returns true if the track has a same track transition for this clip (cid) */
bool hasMix(int cid) const;
public slots:
/*Delete the current track and all its associated clips */
......@@ -304,7 +307,8 @@ private:
std::shared_ptr<Mlt::Tractor> m_track;
std::shared_ptr<Mlt::Producer> m_mainPlaylist;
Mlt::Playlist m_playlists[2];
QList <MixInfo> m_mixList;
// A list of clips having a same track transition, in the form: {first_clip_id, second_clip_id} where first_clip is placed before second_clip
QMap <int, int> m_mixList;
std::map<int, std::shared_ptr<ClipModel>> m_allClips; /*this is important to keep an
ordered structure to store the clips, since we use their ids order as row order*/
......@@ -319,6 +323,7 @@ private:
protected:
std::shared_ptr<EffectStackModel> m_effectStack;
// A list of same track transitions for this track, in the form: {second_clip_id, transition}
std::unordered_map<int, std::shared_ptr<Mlt::Transition>> m_sameCompositions;
};
......
......@@ -45,46 +45,118 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
// Create clip with audio
QString binId = createProducerWithSound(profile_mix, binModel, 50);
// Create clip with audio
QString binId2 = createProducer(profile_mix, "red", binModel, 50, false);
// Setup insert stream data
QMap <int, QString>audioInfo;
audioInfo.insert(1,QStringLiteral("stream1"));
timeline->m_binAudioTargets = audioInfo;
// Create clip
// Create AV clip 1
int cid1;
int cid2;
int cid3;
int cid4;
REQUIRE(timeline->requestClipInsertion(binId, tid2, 100, cid1));
// Resize clip
REQUIRE(timeline->requestItemResize(cid1, 10, true, true));
// Create AV clip 2
REQUIRE(timeline->requestClipInsertion(binId, tid2, 110, cid2));
// Resize clip
REQUIRE(timeline->requestItemResize(cid2, 10, false, true));
REQUIRE(timeline->requestClipMove(cid2, tid2, 110));
// Create color clip 1
REQUIRE(timeline->requestClipInsertion(binId2, tid2, 500, cid3));
REQUIRE(timeline->requestItemResize(cid3, 20, true, true));
REQUIRE(timeline->requestClipInsertion(binId2, tid2, 520, cid4));
REQUIRE(timeline->requestItemResize(cid4, 20, true, true));
auto state0 = [&]() {
REQUIRE(timeline->getClipsCount() == 6);
REQUIRE(timeline->getClipPlaytime(cid1) == 10);
REQUIRE(timeline->getClipPosition(cid1) == 100);
REQUIRE(timeline->getClipPlaytime(cid2) == 10);
REQUIRE(timeline->getClipPosition(cid2) == 110);
REQUIRE(timeline->getClipPosition(cid3) == 500);
REQUIRE(timeline->getClipPlaytime(cid3) == 20);
REQUIRE(timeline->getClipPosition(cid4) == 520);
REQUIRE(timeline->getClipPlaytime(cid4) == 20);
REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
};
auto state1 = [&]() {
REQUIRE(timeline->getClipsCount() == 6);
REQUIRE(timeline->getClipPlaytime(cid1) > 10);
REQUIRE(timeline->getClipPosition(cid1) == 100);
REQUIRE(timeline->getClipPlaytime(cid2) > 10);
REQUIRE(timeline->getClipPosition(cid2) < 110);
REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 1);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1);
};
auto state2 = [&]() {
REQUIRE(timeline->getClipsCount() == 6);
REQUIRE(timeline->getClipPlaytime(cid3) > 20);
REQUIRE(timeline->getClipPosition(cid3) == 500);
REQUIRE(timeline->getClipPlaytime(cid4) > 20);
REQUIRE(timeline->getClipPosition(cid4) < 520);
REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1);
};
SECTION("Create and delete mix")
SECTION("Create and delete mix on color clips")
{
state0();
REQUIRE(timeline->mixClip(cid4));
state2();
undoStack->undo();
state0();
undoStack->redo();
state2();
undoStack->undo();
state0();
}
SECTION("Create and delete mix on AV clips")
{
state0();
REQUIRE(timeline->mixClip(cid2));
state1();
undoStack->undo();
state0();
undoStack->redo();
state1();
undoStack->undo();
state0();
}
SECTION("Create mix and move color clips")
{
state0();
REQUIRE(timeline->mixClip(cid4));
qDebug()<<"==========MIX COLOR DONE; CHECKING STATE";
state2();
// Move clip outside mix zone, should delete the mix
REQUIRE(timeline->requestClipMove(cid4, tid2, 600));
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
qDebug()<<"==========MIX COLOR STARTING UNDO";
undoStack->undo();
state2();
}
/*SECTION("Create mix and move AV clips")
{
state0();
REQUIRE(timeline->mixClip(cid2));
state1();
// Move clip outside mix zone, should delete the mix
REQUIRE(timeline->requestClipMove(cid2, tid2, 200));
REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
}*/
binModel->clean();
pCore->m_projectManager = nullptr;
Logger::print_trace();
}
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