Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

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