Commit 676b79c1 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix errors/crash in insert mode (lift/extract) with mixes

parent 504154d1
......@@ -696,18 +696,46 @@ bool TimelineFunctions::liftZone(const std::shared_ptr<TimelineItemModel> &timel
if (startClipId > -1) {
// There is a clip, cut it
if (timeline->getClipPosition(startClipId) < zone.x()) {
qDebug() << "/// CUTTING AT START: " << zone.x() << ", ID: " << startClipId;
TimelineFunctions::requestClipCut(timeline, startClipId, zone.x(), undo, redo);
qDebug() << "/// CUTTING AT START DONE";
// Check if we have a mix
std::pair<MixInfo,MixInfo> mixData = timeline->getTrackById_const(trackId)->getMixInfo(startClipId);
bool abortCut = false;
if (mixData.first.firstClipId > -1) {
// Clip has a start mix
if (mixData.first.secondClipInOut.first + (mixData.first.firstClipInOut.second - mixData.first.secondClipInOut.first) - mixData.first.mixOffset >= zone.x()) {
// Cut pos is in the mix zone before clip cut, completely remove clip
abortCut = true;
}
}
if (!abortCut) {
TimelineFunctions::requestClipCut(timeline, startClipId, zone.x(), undo, redo);
} else {
// Remove the clip now, so that the mix is deleted before checking items in range
timeline->requestClipUngroup(startClipId, undo, redo);
timeline->requestItemDeletion(startClipId, undo, redo);
}
}
}
int endClipId = timeline->getClipByPosition(trackId, zone.y());
if (endClipId > -1) {
// There is a clip, cut it
if (timeline->getClipPosition(endClipId) + timeline->getClipPlaytime(endClipId) > zone.y()) {
qDebug() << "/// CUTTING AT END: " << zone.y() << ", ID: " << endClipId;
TimelineFunctions::requestClipCut(timeline, endClipId, zone.y(), undo, redo);
qDebug() << "/// CUTTING AT END DONE";
// Check if we have a mix
std::pair<MixInfo,MixInfo> mixData = timeline->getTrackById_const(trackId)->getMixInfo(endClipId);
bool abortCut = false;
if (mixData.second.firstClipId > -1) {
// Clip has an end mix
if (mixData.second.firstClipInOut.second - (mixData.second.firstClipInOut.second - mixData.second.secondClipInOut.first) - mixData.first.mixOffset <= zone.y()) {
// Cut pos is in the mix zone after clip cut, completely remove clip
abortCut = true;
}
}
if (!abortCut) {
TimelineFunctions::requestClipCut(timeline, endClipId, zone.y(), undo, redo);
} else {
// Remove the clip now, so that the mix is deleted before checking items in range
timeline->requestClipUngroup(endClipId, undo, redo);
timeline->requestItemDeletion(endClipId, undo, redo);
}
}
}
std::unordered_set<int> clips = timeline->getItemsInRange(trackId, zone.x(), zone.y());
......
......@@ -801,7 +801,22 @@ int TrackModel::getClipByPosition(int position, int playlist)
if (!prod || prod->is_blank()) {
return -1;
}
return prod->get_int("_kdenlive_cid");
int cid = prod->get_int("_kdenlive_cid");
if (playlist == -1) {
if (hasStartMix(cid)) {
if (position < m_allClips[cid]->getPosition() + m_allClips[cid]->getMixCutPosition()) {
return m_mixList.key(cid, -1);
}
}
if (m_mixList.contains(cid)) {
// Clip has end mix
int otherId = m_mixList.value(cid);
if (position >= m_allClips[cid]->getPosition() + m_allClips[cid]->getPlaytime() - m_allClips[otherId]->getMixCutPosition()) {
return otherId;
}
}
}
return cid;
}
QSharedPointer<Mlt::Producer> TrackModel::getClipProducer(int clipId)
......
......@@ -2748,8 +2748,17 @@ void TimelineController::extract(int clipId)
}
int in = m_model->getClipPosition(clipId);
int out = in + m_model->getClipPlaytime(clipId);
QVector <int> tracks;
tracks << m_model->getClipTrackId(clipId);
int tid = m_model->getClipTrackId(clipId);
std::pair<MixInfo,MixInfo> mixData = m_model->getTrackById_const(tid)->getMixInfo(clipId);
if (mixData.first.firstClipId > -1) {
// Clip has a start mix, adjust in point
in += (mixData.first.firstClipInOut.second - mixData.first.secondClipInOut.first - mixData.first.mixOffset);
}
if (mixData.second.firstClipId > -1) {
// Clip has end mix, adjust out point
out -= mixData.second.mixOffset;
}
QVector <int> tracks = {tid};
if (m_model->m_groups->isInGroup(clipId)) {
int targetRoot = m_model->m_groups->getRootId(clipId);
if (m_model->isGroup(targetRoot)) {
......@@ -2760,9 +2769,19 @@ void TimelineController::extract(int clipId)
}
if (m_model->isClip(current_id)) {
int newIn = m_model->getClipPosition(current_id);
int newOut = newIn + m_model->getClipPlaytime(current_id);
int tk = m_model->getClipTrackId(current_id);
std::pair<MixInfo,MixInfo> mixData = m_model->getTrackById_const(tk)->getMixInfo(current_id);
if (mixData.first.firstClipId > -1) {
// Clip has a start mix, adjust in point
newIn += (mixData.first.firstClipInOut.second - mixData.first.secondClipInOut.first - mixData.first.mixOffset);
}
if (mixData.second.firstClipId > -1) {
// Clip has end mix, adjust out point
newOut -= mixData.second.mixOffset;
}
in = qMin(in, newIn);
out = qMax(out, newIn + m_model->getClipPlaytime(current_id));
out = qMax(out, newOut);
if (!tracks.contains(tk)) {
tracks << tk;
}
......
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