Commit 842d8edc authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix audio split not restoring clip correctly on undo, and extract to lower audio track if available

parent 3612a417
......@@ -331,7 +331,20 @@ bool TimelineFunctions::changeClipState(std::shared_ptr<TimelineItemModel> timel
}
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
redo = [timeline, clipId, status]() {
bool result = changeClipState(timeline, clipId, status, undo, redo);
if (result) {
pCore->pushUndo(undo, redo, i18n("Change clip state"));
}
return result;
}
bool TimelineFunctions::changeClipState(std::shared_ptr<TimelineItemModel> timeline, int clipId, PlaylistState::ClipState status, Fun &undo, Fun &redo)
{
PlaylistState::ClipState oldState = timeline->m_allClips[clipId]->clipState();
if (oldState == status) {
return false;
}
Fun local_redo = [timeline, clipId, status]() {
int trackId = timeline->getClipTrackId(clipId);
bool res = timeline->m_allClips[clipId]->setClipState(status);
// in order to make the producer change effective, we need to unplant / replant the clip in int track
......@@ -346,7 +359,7 @@ bool TimelineFunctions::changeClipState(std::shared_ptr<TimelineItemModel> timel
}
return res;
};
undo = [timeline, clipId, oldState]() {
Fun local_undo = [timeline, clipId, oldState]() {
bool res = timeline->m_allClips[clipId]->setClipState(oldState);
// in order to make the producer change effective, we need to unplant / replant the clip in int track
int trackId = timeline->getClipTrackId(clipId);
......@@ -363,9 +376,10 @@ bool TimelineFunctions::changeClipState(std::shared_ptr<TimelineItemModel> timel
}
return res;
};
bool result = redo();
bool result = local_redo();
if (result) {
pCore->pushUndo(undo, redo, i18n("Change clip state"));
PUSH_LAMBDA(local_undo, undo);
PUSH_LAMBDA(local_redo, redo);
}
return result;
}
......@@ -380,26 +394,31 @@ bool TimelineFunctions::requestSplitAudio(std::shared_ptr<TimelineItemModel> tim
int position = timeline->getClipPosition(cid);
int duration = timeline->getClipPlaytime(cid);
int track = timeline->getClipTrackId(cid);
int newTrack = audioTarget >= 0 ? audioTarget : timeline->getLowerTrackId(track, TrackType::AudioTrack);
if (newTrack == -1) {
QList<int> possibleTracks = audioTarget >= 0 ? QList<int>() <<audioTarget : timeline->getLowerTracksId(track, TrackType::AudioTrack);
if (possibleTracks.isEmpty()) {
// No available audio track for splitting, abort
undo();
pCore->displayMessage(i18n("No available audio track for split operation"), ErrorMessage);
return false;
}
int newId;
TimelineFunctions::changeClipState(timeline, clipId, PlaylistState::VideoOnly);
bool res = copyClip(timeline, cid, newId, PlaylistState::AudioOnly, undo, redo);
res = res && timeline->requestClipMove(newId, newTrack, position, true, false, undo, redo);
bool move = false;
while (!move && !possibleTracks.isEmpty()) {
int newTrack = possibleTracks.takeFirst();
move = timeline->requestClipMove(newId, newTrack, position, true, false, undo, redo);
}
std::unordered_set<int> clips;
clips.insert(clipId);
clips.insert(cid);
clips.insert(newId);
timeline->requestClipsGroup(clips, undo, redo);
if (!res) {
if (!res || !move) {
bool undone = undo();
Q_ASSERT(undone);
pCore->displayMessage(i18n("Audio split failed"), ErrorMessage);
return false;
}
TimelineFunctions::changeClipState(timeline, cid, PlaylistState::VideoOnly, undo, redo);
timeline->requestClipsGroup(clips, undo, redo);
}
pCore->pushUndo(undo, redo, i18n("Split Audio"));
return true;
......
......@@ -62,6 +62,7 @@ struct TimelineFunctions
static void showClipKeyframes(std::shared_ptr<TimelineItemModel> timeline, int clipId, bool value);
static void showCompositionKeyframes(std::shared_ptr<TimelineItemModel> timeline, int compoId, bool value);
static bool changeClipState(std::shared_ptr<TimelineItemModel> timeline, int clipId, PlaylistState::ClipState status);
static bool changeClipState(std::shared_ptr<TimelineItemModel> timeline, int clipId, PlaylistState::ClipState status, Fun &undo, Fun &redo);
static bool requestSplitAudio(std::shared_ptr<TimelineItemModel> timeline, int clipId, int audioTarget);
};
......
......@@ -249,29 +249,27 @@ int TimelineModel::getTrackMltIndex(int trackId) const
return getTrackPosition(trackId) + 1;
}
int TimelineModel::getLowerTrackId(int trackId, TrackType type) const
QList <int> TimelineModel::getLowerTracksId(int trackId, TrackType type) const
{
READ_LOCK();
Q_ASSERT(isTrack(trackId));
QList <int> results;
auto it = m_iteratorTable.at(trackId);
while (it != m_allTracks.begin()) {
--it;
if (it == m_allTracks.begin()) {
// no track available
return -1;
}
if (type == TrackType::AnyTrack) {
return (*it)->getId();
results << (*it)->getId();
continue;
}
int audioTrack = (*it)->getProperty("kdenlive:audio_track").toInt();
if (type == TrackType::AudioTrack && audioTrack == 1) {
return (*it)->getId();
results << (*it)->getId();
}
if (type == TrackType::VideoTrack && audioTrack == 0) {
return (*it)->getId();
else if (type == TrackType::VideoTrack && audioTrack == 0) {
results << (*it)->getId();
}
}
return -1;
return results;
}
int TimelineModel::getPreviousVideoTrackPos(int trackId) const
......
......@@ -241,11 +241,11 @@ public:
*/
int getTrackMltIndex(int trackId) const;
/* @brief Returns the id of the track just below the given track in the order of the tracks
Return -1 if we give the last track
/* @brief Returns the ids of the tracks below the given track in the order of the tracks
Returns an empty list if no track available
@param trackId Id of the track to test
*/
int getLowerTrackId(int trackId, TrackType type = TrackType::AnyTrack) const;
QList <int> getLowerTracksId(int trackId, TrackType type = TrackType::AnyTrack) const;
/* @brief Returns the MLT track index of the video track just below the given trackC
@param trackId Id of the track to test
......
......@@ -774,7 +774,7 @@ Rectangle {
onTriggered: timeline.triggerAction('delete_timeline_clip')
}
OLD.MenuItem {
visible: true
visible: true
text: i18n('Extract')
onTriggered: timeline.extract(clipRoot.clipId)
}
......
......@@ -385,8 +385,8 @@ void TimelineController::addTrack(int tid)
QPointer<TrackDialog> d = new TrackDialog(m_model, m_model->getTrackMltIndex(tid), qApp->activeWindow());
if (d->exec() == QDialog::Accepted) {
int mltIndex = d->selectedTrack();
int tid;
m_model->requestTrackInsertion(mltIndex, tid, d->trackName(), d->addAudioTrack());
int newTid;
m_model->requestTrackInsertion(mltIndex, newTid, d->trackName(), d->addAudioTrack());
}
}
......
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