Commit 19251661 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle

Merge branch '1912'

parents f9a23482 6a4b2c54
Pipeline #11480 canceled with stage
......@@ -262,7 +262,7 @@
</ul>
</description>
<releases>
<release date="2019-08-15" version="19.11.0"/>
<release date="2019-12-05" version="19.12.0"/>
</releases>
<url type="homepage">https://kdenlive.org/</url>
<url type="bugtracker">https://bugs.kde.org</url>
......
......@@ -555,7 +555,7 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
}
} else if (getTrackById_const(trackId)->trackType() != m_allClips[clipId]->clipState()) {
// Move not allowed (audio / video mismatch)
qDebug() << "// CLIP MISMATCH: " << getTrackById_const(trackId)->trackType() << " == " << m_allClips[clipId]->clipState();
qDebug() << "// CLIP MISMATC FOR TK: "<<trackId<< ", " << getTrackById_const(trackId)->trackType() << " == " << m_allClips[clipId]->clipState();
return false;
}
std::function<bool(void)> local_undo = []() { return true; };
......@@ -590,7 +590,7 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
return false;
}
}
ok = ok & getTrackById(trackId)->requestClipInsertion(clipId, position, updateView, finalMove, local_undo, local_redo, groupMove);
ok = getTrackById(trackId)->requestClipInsertion(clipId, position, updateView, finalMove, local_undo, local_redo, groupMove);
if (!ok) {
qDebug() << "-------------\n\nINSERTION FAILED, REVERTING\n\n-------------------";
bool undone = local_undo();
......@@ -1489,14 +1489,14 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
}
}
if (!moveMirrorTracks) {
if (getTrackById(old_track_ids[itemId])->isAudioTrack()) {
if (getTrackById_const(old_track_ids[itemId])->isAudioTrack()) {
// Master clip is audio, so reverse delta for video clips
video_delta = 0;
} else {
audio_delta = 0;
}
} else {
if (getTrackById(old_track_ids[itemId])->isAudioTrack()) {
if (getTrackById_const(old_track_ids[itemId])->isAudioTrack()) {
// Master clip is audio, so reverse delta for video clips
video_delta = -delta_track;
} else {
......@@ -1510,17 +1510,64 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
bool updateThisView = allowViewRefresh;
if (delta_track == 0) {
// Special case, we are moving on same track, avoid too many calculations
// First pass, check for collisions and suggest better delta
QVector <int> processedTracks;
for (int item : sorted_clips) {
int current_track_id = getItemTrackId(item);
if (processedTracks.contains(current_track_id)) {
// We only check the first clip for each track since they are sorted depending on the move direction
continue;
}
processedTracks << current_track_id;
if (!allowedTracks.isEmpty() && !allowedTracks.contains(current_track_id)) {
continue;
}
int current_in = getItemPosition(item);
int playtime = getItemPlaytime(item);
int target_position = current_in + delta_pos;
if (isClip(item)) {
if (delta_pos < 0) {
if (!getTrackById_const(current_track_id)->isAvailable(target_position, playtime)) {
int newStart = getTrackById_const(current_track_id)->getBlankStart(current_in - 1);
if (newStart == current_in - 1) {
// No move possible, abort
bool undone = local_undo();
Q_ASSERT(undone);
return false;
}
delta_pos = qMax(delta_pos, newStart - current_in);
}
} else {
int moveEnd = target_position + playtime;
int moveStart = qMax(current_in + playtime, target_position);
if (!getTrackById_const(current_track_id)->isAvailable(moveStart, moveEnd - moveStart)) {
int newStart = getTrackById_const(current_track_id)->getBlankEnd(current_in + playtime);
if (newStart == current_in + playtime) {
// No move possible, abort
bool undone = local_undo();
Q_ASSERT(undone);
return false;
}
delta_pos = qMin(delta_pos, newStart - (current_in + playtime));
}
}
}
}
for (int item : sorted_clips) {
int current_track_id = getItemTrackId(item);
if (!allowedTracks.isEmpty() && !allowedTracks.contains(current_track_id)) {
continue;
}
int target_position = getItemPosition(item) + delta_pos;
int current_in = getItemPosition(item);
int target_position = current_in + delta_pos;
if (isClip(item)) {
ok = ok && requestClipMove(item, current_track_id, target_position, moveMirrorTracks, updateThisView, finalMove, finalMove, local_undo, local_redo, true);
ok = requestClipMove(item, current_track_id, target_position, moveMirrorTracks, updateThisView, finalMove, finalMove, local_undo, local_redo, true);
} else {
ok = ok &&
requestCompositionMove(item, current_track_id, m_allCompositions[item]->getForcedTrack(), target_position, updateThisView, finalMove, local_undo, local_redo);
ok = requestCompositionMove(item, current_track_id, m_allCompositions[item]->getForcedTrack(), target_position, updateThisView, finalMove, local_undo, local_redo);
}
if (!ok) {
break;
}
}
if (!ok) {
......
......@@ -1332,3 +1332,15 @@ void TrackModel::unlock()
ptr->dataChanged(ix, ix, {TimelineModel::IsLockedRole});
}
}
bool TrackModel::isAvailable(int position, int duration)
{
//TODO: warning, does not work on second playlist
int start_clip = m_playlists[0].get_clip_index_at(position);
int end_clip = m_playlists[0].get_clip_index_at(position + duration - 1);
if (start_clip != end_clip) {
return false;
}
return m_playlists[0].is_blank(start_clip);
}
......@@ -266,6 +266,8 @@ protected:
bool importEffects(std::weak_ptr<Mlt::Service> service);
/* @brief Copy effects from anoter effect stack */
bool copyEffect(const std::shared_ptr<EffectStackModel> &stackModel, int rowId);
bool isAvailable(int position, int duration);
public slots:
/*Delete the current track and all its associated clips */
......
......@@ -377,8 +377,10 @@ Rectangle {
Rectangle {
id: trackLabel
color: 'transparent'
Layout.fillWidth: true
radius: 2
Layout.fillWidth: true
Layout.rightMargin: 2
Layout.leftMargin: 2
border.color: trackNameMouseArea.containsMouse ? activePalette.highlight : 'transparent'
height: nameEdit.height
visible: (trackHeadRoot.height >= trackLabel.height + muteButton.height + resizer.height + recLayout.height)
......@@ -437,7 +439,8 @@ Rectangle {
padding.top:0
padding.bottom: 0
background: Rectangle {
color: activePalette.base
radius: 2
color: activePalette.window
anchors.fill: parent
}
}
......
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