Commit 3569ac05 authored by Nicolas Carion's avatar Nicolas Carion
Browse files

nicer split track computed on drop

parent b671f7ed
......@@ -3663,7 +3663,7 @@ void MainWindow::slotInsertZoneToTimeline()
{
QPoint info = m_clipMonitor->getZoneInfo();
QString clipData = QString("%1#%2#%3").arg(m_clipMonitor->activeClipId()).arg(info.x()).arg(info.y());
int cid = getMainTimeline()->controller()->insertClip(-1, -1, clipData, true, true);
int cid = getMainTimeline()->controller()->insertClip(-1, -1, clipData, true, true, true);
if (cid == -1) {
pCore->displayMessage(i18n("Cannot insert clip at requested position"), InformationMessage);
} else {
......
......@@ -68,7 +68,7 @@ bool TimelineFunctions::requestMultipleClipsInsertion(std::shared_ptr<TimelineIt
for (const QString &binId : binIds) {
int clipId;
if (timeline->requestClipInsertion(binId, trackId, position, clipId, logUndo, refreshView, undo, redo)) {
if (timeline->requestClipInsertion(binId, trackId, position, clipId, logUndo, refreshView, true, undo, redo)) {
clipIds.append(clipId);
position += timeline->getItemPlaytime(clipId);
} else {
......@@ -250,7 +250,7 @@ bool TimelineFunctions::insertZone(std::shared_ptr<TimelineItemModel> timeline,
}
int newId = -1;
QString binClipId = QString("%1/%2/%3").arg(binId).arg(zone.x()).arg(zone.y() - 1);
timeline->requestClipInsertion(binClipId, trackId, insertFrame, newId, true, true, undo, redo);
timeline->requestClipInsertion(binClipId, trackId, insertFrame, newId, true, true, true, undo, redo);
pCore->pushUndo(undo, redo, overwrite ? i18n("Overwrite zone") : i18n("Insert zone"));
return result;
}
......
......@@ -267,10 +267,10 @@ QList<int> TimelineModel::getLowerTracksId(int trackId, TrackType type) const
results << (*it)->getId();
continue;
}
int audioTrack = (*it)->getProperty("kdenlive:audio_track").toInt();
if (type == TrackType::AudioTrack && audioTrack == 1) {
bool audioTrack = (*it)->isAudioTrack();
if (type == TrackType::AudioTrack && audioTrack) {
results << (*it)->getId();
} else if (type == TrackType::VideoTrack && audioTrack == 0) {
} else if (type == TrackType::VideoTrack && !audioTrack) {
results << (*it)->getId();
}
}
......@@ -284,13 +284,38 @@ int TimelineModel::getPreviousVideoTrackPos(int trackId) const
auto it = m_iteratorTable.at(trackId);
while (it != m_allTracks.begin()) {
--it;
if (it != m_allTracks.begin() && (*it)->getProperty("kdenlive:audio_track").toInt() == 0) {
if (it != m_allTracks.begin() && !(*it)->isAudioTrack()) {
break;
}
}
return it == m_allTracks.begin() ? 0 : getTrackMltIndex((*it)->getId());
}
int TimelineModel::getMirrorAudioTrackId(int trackId) const
{
READ_LOCK();
Q_ASSERT(isTrack(trackId));
auto it = m_iteratorTable.at(trackId);
if ((*it)->isAudioTrack()) {
// we expected a video track...
return -1;
}
int count = 0;
--it;
while (it != m_allTracks.begin()) {
if (!(*it)->isAudioTrack()) {
count++;
} else {
if (count == 0) {
return (*it)->getId();
}
count--;
}
--it;
}
return -1;
}
bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool updateView, bool invalidateTimeline, Fun &undo, Fun &redo)
{
qDebug() << "// FINAL MOVE: " << invalidateTimeline << ", UPDATE VIEW: " << updateView;
......@@ -538,21 +563,6 @@ int TimelineModel::suggestCompositionMove(int compoId, int trackId, int position
return position;
}
bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, bool refreshView)
{
#ifdef LOGGING
m_logFile << "timeline->requestClipInsertion(" << binClipId.toStdString() << "," << trackId << " ," << position << ", dummy_id );" << std::endl;
#endif
QWriteLocker locker(&m_lock);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool result = requestClipInsertion(binClipId, trackId, position, id, logUndo, refreshView, undo, redo);
if (result && logUndo) {
PUSH_UNDO(undo, redo, i18n("Insert Clip"));
}
return result;
}
bool TimelineModel::requestClipCreation(const QString &binClipId, int &id, PlaylistState::ClipState state, Fun &undo, Fun &redo)
{
qDebug() << "requestClipCreation " << binClipId;
......@@ -592,7 +602,23 @@ bool TimelineModel::requestClipCreation(const QString &binClipId, int &id, Playl
return true;
}
bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, bool refreshView, Fun &undo, Fun &redo)
bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, bool refreshView, bool useTargets)
{
#ifdef LOGGING
m_logFile << "timeline->requestClipInsertion(" << binClipId.toStdString() << "," << trackId << " ," << position << ", dummy_id );" << std::endl;
#endif
QWriteLocker locker(&m_lock);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool result = requestClipInsertion(binClipId, trackId, position, id, logUndo, refreshView, useTargets, undo, redo);
if (result && logUndo) {
PUSH_UNDO(undo, redo, i18n("Insert Clip"));
}
return result;
}
bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, bool refreshView, bool useTargets,
Fun &undo, Fun &redo)
{
std::function<bool(void)> local_undo = []() { return true; };
std::function<bool(void)> local_redo = []() { return true; };
......@@ -611,7 +637,7 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
type = master->clipType();
if (type == ClipType::AV) {
if (m_audioTarget >= 0 && m_videoTarget == -1) {
if (m_audioTarget >= 0 && m_videoTarget == -1 && !useTargets) {
// If audio target is set but no video target, only insert audio
trackId = m_audioTarget;
}
......@@ -627,8 +653,17 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
audioDrop = true;
}
}
if (res && !audioDrop) {
QList<int> possibleTracks = m_audioTarget >= 0 ? QList<int>() << m_audioTarget : getLowerTracksId(trackId, TrackType::AudioTrack);
if (res && (!audioDrop || !useTargets)) {
int target_track = m_audioTarget;
if (!useTargets) {
target_track = getMirrorAudioTrackId(trackId);
}
// QList<int> possibleTracks = m_audioTarget >= 0 ? QList<int>() << m_audioTarget : getLowerTracksId(trackId, TrackType::AudioTrack);
QList<int> possibleTracks;
qDebug() << "CREATING SPLIT " << target_track << " usetargets" << useTargets;
if (target_track >= 0) {
possibleTracks << target_track;
}
if (possibleTracks.isEmpty()) {
// No available audio track for splitting, abort
pCore->displayMessage(i18n("No available audio track for split operation"), ErrorMessage);
......
......@@ -104,13 +104,13 @@ public:
/// Two level model: tracks and clips on track
enum {
NameRole = Qt::UserRole + 1,
ResourceRole, /// clip only
ServiceRole, /// clip only
IsBlankRole, /// clip only
StartRole, /// clip only
BinIdRole, /// clip only
MarkersRole, /// clip only
StatusRole, /// clip only
ResourceRole, /// clip only
ServiceRole, /// clip only
IsBlankRole, /// clip only
StartRole, /// clip only
BinIdRole, /// clip only
MarkersRole, /// clip only
StatusRole, /// clip only
GroupDragRole, /// indicates if the clip is in current timeline selection, needed for group drag
KeyframesRole,
DurationRole,
......@@ -128,13 +128,13 @@ public:
IsCompositeRole, /// track only
IsLockedRole, /// track only
HeightRole, /// track only
TrackTagRole, /// track only
TrackTagRole, /// track only
FadeInRole, /// clip only
FadeOutRole, /// clip only
IsCompositionRole, /// clip only
FileHashRole, /// clip only
SpeedRole, /// clip only
ReloadThumbRole, /// clip only
ReloadThumbRole, /// clip only
ItemATrack, /// composition only
ItemIdRole
};
......@@ -247,13 +247,16 @@ public:
Returns an empty list if no track available
@param trackId Id of the track to test
*/
QList <int> getLowerTracksId(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
*/
int getPreviousVideoTrackPos(int trackId) const;
/* @brief Retuns the Id of the corresponding audio track. If trackId corresponds to video1, this will return audio 1 and so on */
int getMirrorAudioTrackId(int trackId) const;
/* @brief Move a clip to a specific position
This action is undoable
Returns true on success. If it fails, nothing is modified.
......@@ -307,10 +310,13 @@ public:
@param ID return parameter of the id of the inserted clip
@param logUndo if set to false, no undo object is stored
@param refreshView whether the view should be refreshed
@param useTargets: if true, the Audio/video split will occur on the set targets. Otherwise, they will be computed as an offset from the middle line
*/
bool requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo = true, bool refreshView = false);
bool requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo = true, bool refreshView = false,
bool useTargets = true);
/* Same function, but accumulates undo and redo*/
bool requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, bool refreshView, Fun &undo, Fun &redo);
bool requestClipInsertion(const QString &binClipId, int trackId, int position, int &id, bool logUndo, bool refreshView, bool useTargets, Fun &undo,
Fun &redo);
/* @brief Creates a new clip instance without inserting it.
This action is undoable, returns true on success
@param binClipId: Bin id of the clip to insert
......@@ -472,9 +478,11 @@ public:
@param id return parameter of the id of the inserted composition
@param logUndo if set to false, no undo object is stored
*/
bool requestCompositionInsertion(const QString &transitionId, int trackId, int position, int length, Mlt::Properties *transProps, int &id, bool logUndo = true);
bool requestCompositionInsertion(const QString &transitionId, int trackId, int position, int length, Mlt::Properties *transProps, int &id,
bool logUndo = true);
/* Same function, but accumulates undo and redo*/
bool requestCompositionInsertion(const QString &transitionId, int trackId, int compositionTrack, int position, int length, Mlt::Properties *transProps, int &id, Fun &undo, Fun &redo);
bool requestCompositionInsertion(const QString &transitionId, int trackId, int compositionTrack, int position, int length, Mlt::Properties *transProps,
int &id, Fun &undo, Fun &redo);
/* @brief This function change the global (timeline-wise) enabled state of the effects
It disables/enables track and clip effects (recursively)
......@@ -523,11 +531,11 @@ protected:
void registerTrack(std::shared_ptr<TrackModel> track, int pos = -1, bool doInsert = true, bool reloadView = true);
/* @brief Register a new clip. This is a call-back meant to be called from ClipModel
*/
*/
void registerClip(const std::shared_ptr<ClipModel> &clip);
/* @brief Register a new composition. This is a call-back meant to be called from CompositionModel
*/
*/
void registerComposition(const std::shared_ptr<CompositionModel> &composition);
/* @brief Register a new group. This is a call-back meant to be called from GroupsModel
......@@ -644,7 +652,7 @@ protected:
// The index of the temporary overlay track in tractor, or -1 if not connected
int m_overlayTrackCount;
// The preferred audio target for clip insertion or -1 if not defined
int m_audioTarget;
// The preferred video target for clip insertion or -1 if not defined
......
......@@ -219,9 +219,9 @@ Rectangle {
var id = -1
if (binIds.length == 1) {
id = timeline.insertClip(timeline.activeTrack, frame, clipBeingDroppedData, false, true)
id = timeline.insertClip(timeline.activeTrack, frame, clipBeingDroppedData, false, true, false)
} else {
var ids = timeline.insertClips(timeline.activeTrack, frame, binIds, false, true)
var ids = timeline.insertClips(timeline.activeTrack, frame, binIds, false, true, false)
// if the clip insertion succeeded, request the clips to be grouped
if (ids.length > 0) {
......@@ -290,7 +290,7 @@ Rectangle {
var binIds = clipBeingDroppedData.split(";")
if (binIds.length == 1) {
timeline.insertClip(track, frame, clipBeingDroppedData, true, true)
timeline.insertClip(track, frame, clipBeingDroppedData, true, true, false)
} else {
timeline.insertClips(track, frame, binIds, true, true)
}
......
......@@ -386,7 +386,7 @@ bool TimelineController::scrub()
return false;
}
int TimelineController::insertClip(int tid, int position, const QString &data_str, bool logUndo, bool refreshView)
int TimelineController::insertClip(int tid, int position, const QString &data_str, bool logUndo, bool refreshView, bool useTargets)
{
int id;
if (tid == -1) {
......@@ -395,7 +395,7 @@ int TimelineController::insertClip(int tid, int position, const QString &data_st
if (position == -1) {
position = timelinePosition();
}
if (!m_model->requestClipInsertion(data_str, tid, position, id, logUndo, refreshView)) {
if (!m_model->requestClipInsertion(data_str, tid, position, id, logUndo, refreshView, useTargets)) {
id = -1;
}
return id;
......
......@@ -120,7 +120,7 @@ public:
@param logUndo if set to false, no undo object is stored
@return the id of the inserted clip
*/
Q_INVOKABLE int insertClip(int tid, int position, const QString &xml, bool logUndo, bool refreshView);
Q_INVOKABLE int insertClip(int tid, int position, const QString &xml, bool logUndo, bool refreshView, bool useTargets);
/* @brief Request inserting multiple clips into the timeline (dragged from bin or monitor)
* @param tid is the destination track
* @param position is the timeline position
......
Supports Markdown
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