Don't check duration each time a clip is inserted on project load,

and only once in group moves (makes group operation much faster)
parent 824b4cd0
Pipeline #4104 passed with stage
in 28 minutes and 15 seconds
......@@ -203,6 +203,11 @@ void MonitorProxy::resetZone()
m_zoneOut = -1;
}
double MonitorProxy::fps() const
{
return pCore->getCurrentFps();
}
QPoint MonitorProxy::zone() const
{
return {m_zoneIn, m_zoneOut};
......
......@@ -82,6 +82,7 @@ public:
QPoint zone() const;
QImage extractFrame(int frame_position, const QString &path = QString(), int width = -1, int height = -1, bool useSourceProfile = false);
Q_INVOKABLE QString toTimecode(int frames) const;
Q_INVOKABLE double fps() const;
void setClipHasAV(bool hasAV);
signals:
......
......@@ -24,15 +24,19 @@ Rectangle {
function updateRuler()
{
var projectFps = controller.fps()
root.timeScale = width / root.duration
if (root.duration < 200) {
root.frameSize = 5 * root.timeScale
} else if (duration < 2500) {
frameSize = 25 * root.timeScale
} else if (duration < 10000) {
root.frameSize = 50 * root.timeScale
if (root.duration < 10 * projectFps) {
root.frameSize = projectFps * root.timeScale * 0.2
} else if (duration < 100 * projectFps) {
frameSize = projectFps * root.timeScale
} else if (duration < 400 * projectFps) {
root.frameSize = projectFps * root.timeScale * 2
} else {
root.frameSize = 100 * root.timeScale
root.frameSize = projectFps * root.timeScale * 4
while (root.frameSize < 10) {
root.frameSize *= 4
}
}
}
......
......@@ -239,6 +239,7 @@ bool ProjectManager::closeCurrentDocument(bool saveChanges, bool quit)
break;
}
}
disconnect(pCore->window()->getMainTimeline()->controller(), &TimelineController::durationChanged, this, &ProjectManager::adjustProjectDuration);
pCore->window()->getMainTimeline()->controller()->clipActions.clear();
pCore->window()->getMainTimeline()->controller()->prepareClose();
if (m_mainTimelineModel) {
......@@ -885,7 +886,7 @@ bool ProjectManager::updateTimeline(int pos, int scrollPos)
if (!groupsData.isEmpty()) {
m_mainTimelineModel->loadGroups(groupsData);
}
connect(pCore->window()->getMainTimeline()->controller(), &TimelineController::durationChanged, this, &ProjectManager::adjustProjectDuration);
pCore->monitorManager()->projectMonitor()->setProducer(m_mainTimelineModel->producer(), pos);
pCore->monitorManager()->projectMonitor()->adjustRulerSize(m_mainTimelineModel->duration() - 1, m_project->getGuideModel());
pCore->window()->getMainTimeline()->controller()->setZone(m_project->zone());
......
......@@ -513,7 +513,7 @@ bool TimelineModel::requestFakeClipMove(int clipId, int trackId, int position, b
return false;
}
bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool updateView, bool invalidateTimeline, bool finalMove, Fun &undo, Fun &redo)
bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool updateView, bool invalidateTimeline, bool finalMove, Fun &undo, Fun &redo, bool groupMove)
{
// qDebug() << "// FINAL MOVE: " << invalidateTimeline << ", UPDATE VIEW: " << updateView<<", FINAL: "<<finalMove;
if (trackId == -1) {
......@@ -557,14 +557,14 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
if (notifyViewOnly) {
PUSH_LAMBDA(update_model, local_undo);
}
ok = getTrackById(old_trackId)->requestClipDeletion(clipId, updateView, finalMove, local_undo, local_redo);
ok = getTrackById(old_trackId)->requestClipDeletion(clipId, updateView, finalMove, local_undo, local_redo, groupMove);
if (!ok) {
bool undone = local_undo();
Q_ASSERT(undone);
return false;
}
}
ok = ok & getTrackById(trackId)->requestClipInsertion(clipId, position, updateView, finalMove, local_undo, local_redo);
ok = 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();
......@@ -1369,7 +1369,10 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
// Moving groups is a two stage process: first we remove the clips from the tracks, and then try to insert them back at their calculated new positions.
// This way, we ensure that no conflict will arise with clips inside the group being moved
Fun update_model = []() { return true; };
Fun update_model = [this]() {
updateDuration();
return true;
};
// Check if there is a track move
bool updatePositionOnly = false;
......@@ -1388,6 +1391,7 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
}
notifyChange(modelIndex, modelIndex, roles);
}
updateDuration();
return true;
};
}
......@@ -1400,7 +1404,7 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
if (old_trackId != -1) {
bool updateThisView = allowViewRefresh;
if (isClip(item)) {
ok = ok && getTrackById(old_trackId)->requestClipDeletion(item, updateThisView, finalMove, local_undo, local_redo);
ok = ok && getTrackById(old_trackId)->requestClipDeletion(item, updateThisView, finalMove, local_undo, local_redo, true);
old_position[item] = m_allClips[item]->getPosition();
} else {
// ok = ok && getTrackById(old_trackId)->requestCompositionDeletion(item, updateThisView, finalMove, local_undo, local_redo);
......@@ -1441,7 +1445,7 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
int target_track = (*it)->getId();
int target_position = old_position[item] + delta_pos;
if (isClip(item)) {
ok = ok && requestClipMove(item, target_track, target_position, updateThisView, finalMove, finalMove, local_undo, local_redo);
ok = ok && requestClipMove(item, target_track, target_position, updateThisView, finalMove, finalMove, local_undo, local_redo, true);
} else {
ok = ok &&
requestCompositionMove(item, target_track, old_forced_track[item], target_position, updateThisView, finalMove, local_undo, local_redo);
......@@ -1456,6 +1460,7 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
return false;
}
}
updateDuration();
if (updatePositionOnly) {
update_model();
PUSH_LAMBDA(update_model, local_redo);
......
......@@ -356,7 +356,7 @@ public:
/* Same function, but accumulates undo and redo, and doesn't check
for group*/
bool requestClipMove(int clipId, int trackId, int position, bool updateView, bool invalidateTimeline, bool finalMove, Fun &undo, Fun &redo);
bool requestClipMove(int clipId, int trackId, int position, bool updateView, bool invalidateTimeline, bool finalMove, Fun &undo, Fun &redo, bool groupMove = false);
bool requestCompositionMove(int transid, int trackId, int compositionTrack, int position, bool updateView, bool finalMove, Fun &undo, Fun &redo);
/* When timeline edit mode is insert or overwrite, we fake the move (as it will overlap existing clips, and only process the real move on drop */
......
......@@ -119,7 +119,7 @@ int TrackModel::getClipsCount()
return count;
}
Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updateView, bool finalMove)
Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updateView, bool finalMove, bool groupMove)
{
QWriteLocker locker(&m_lock);
// By default, insertion occurs in topmost track
......@@ -165,7 +165,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
};
if (target_clip >= count && isBlankAt(position)) {
// In that case, we append after, in the first playlist
return [this, position, clipId, end_function, finalMove]() {
return [this, position, clipId, end_function, finalMove, groupMove]() {
if (isLocked()) return false;
if (auto ptr = m_parent.lock()) {
// Lock MLT playlist so that we don't end up with an invalid frame being displayed
......@@ -175,7 +175,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
int index = m_playlists[0].insert_at(position, *clip, 1);
m_playlists[0].consolidate_blanks();
m_playlists[0].unlock();
if (finalMove) {
if (finalMove && !groupMove) {
ptr->updateDuration();
}
return index != -1 && end_function(0);
......@@ -212,7 +212,7 @@ Fun TrackModel::requestClipInsertion_lambda(int clipId, int position, bool updat
return []() { return false; };
}
bool TrackModel::requestClipInsertion(int clipId, int position, bool updateView, bool finalMove, Fun &undo, Fun &redo)
bool TrackModel::requestClipInsertion(int clipId, int position, bool updateView, bool finalMove, Fun &undo, Fun &redo, bool groupMove)
{
QWriteLocker locker(&m_lock);
if (isLocked()) {
......@@ -236,10 +236,10 @@ bool TrackModel::requestClipInsertion(int clipId, int position, bool updateView,
if (ptr->getClipPtr(clipId)->clipState() != PlaylistState::Disabled) {
res = res && ptr->getClipPtr(clipId)->setClipState(isAudioTrack() ? PlaylistState::AudioOnly : PlaylistState::VideoOnly, local_undo, local_redo);
}
auto operation = requestClipInsertion_lambda(clipId, position, updateView, finalMove);
auto operation = requestClipInsertion_lambda(clipId, position, updateView, finalMove, groupMove);
res = res && operation();
if (res) {
auto reverse = requestClipDeletion_lambda(clipId, updateView, finalMove);
auto reverse = requestClipDeletion_lambda(clipId, updateView, finalMove, groupMove);
UPDATE_UNDO_REDO(operation, reverse, local_undo, local_redo);
UPDATE_UNDO_REDO(local_redo, local_undo, undo, redo);
return true;
......@@ -278,7 +278,7 @@ void TrackModel::replugClip(int clipId)
m_playlists[target_track].unlock();
}
Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView, bool finalMove)
Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView, bool finalMove, bool groupMove)
{
QWriteLocker locker(&m_lock);
// Find index of clip
......@@ -286,7 +286,7 @@ Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView, bool fin
bool audioOnly = m_allClips[clipId]->isAudioOnly();
int old_in = clip_position;
int old_out = old_in + m_allClips[clipId]->getPlaytime();
return [clip_position, clipId, old_in, old_out, updateView, audioOnly, finalMove, this]() {
return [clip_position, clipId, old_in, old_out, updateView, audioOnly, finalMove, groupMove, this]() {
if (isLocked()) return false;
auto clip_loc = getClipIndexAt(clip_position);
if (updateView) {
......@@ -316,7 +316,7 @@ Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView, bool fin
if (!audioOnly && !isAudioTrack()) {
ptr->invalidateZone(old_in, old_out);
}
if (target_clip >= m_playlists[target_track].count()) {
if (!groupMove && target_clip >= m_playlists[target_track].count()) {
// deleted last clip in playlist
ptr->updateDuration();
}
......@@ -333,7 +333,7 @@ Fun TrackModel::requestClipDeletion_lambda(int clipId, bool updateView, bool fin
};
}
bool TrackModel::requestClipDeletion(int clipId, bool updateView, bool finalMove, Fun &undo, Fun &redo)
bool TrackModel::requestClipDeletion(int clipId, bool updateView, bool finalMove, Fun &undo, Fun &redo, bool groupMove)
{
QWriteLocker locker(&m_lock);
Q_ASSERT(m_allClips.count(clipId) > 0);
......@@ -343,9 +343,9 @@ bool TrackModel::requestClipDeletion(int clipId, bool updateView, bool finalMove
auto old_clip = m_allClips[clipId];
int old_position = old_clip->getPosition();
// qDebug() << "/// REQUESTOING CLIP DELETION_: " << updateView;
auto operation = requestClipDeletion_lambda(clipId, updateView, finalMove);
auto operation = requestClipDeletion_lambda(clipId, updateView, finalMove, groupMove);
if (operation()) {
auto reverse = requestClipInsertion_lambda(clipId, old_position, updateView, finalMove);
auto reverse = requestClipInsertion_lambda(clipId, old_position, updateView, finalMove, groupMove);
UPDATE_UNDO_REDO(operation, reverse, undo, redo);
return true;
}
......
......@@ -137,9 +137,9 @@ protected:
@param undo Lambda function containing the current undo stack. Will be updated with current operation
@param redo Lambda function containing the current redo queue. Will be updated with current operation
*/
bool requestClipInsertion(int clipId, int position, bool updateView, bool finalMove, Fun &undo, Fun &redo);
bool requestClipInsertion(int clipId, int position, bool updateView, bool finalMove, Fun &undo, Fun &redo, bool groupMove = false);
/* @brief This function returns a lambda that performs the requested operation */
Fun requestClipInsertion_lambda(int clipId, int position, bool updateView, bool finalMove);
Fun requestClipInsertion_lambda(int clipId, int position, bool updateView, bool finalMove, bool groupMove = false);
/* @brief Performs an deletion of the given clip.
Returns true if the operation succeeded, and otherwise, the track is not modified.
......@@ -150,9 +150,9 @@ protected:
@param undo Lambda function containing the current undo stack. Will be updated with current operation
@param redo Lambda function containing the current redo queue. Will be updated with current operation
*/
bool requestClipDeletion(int clipId, bool updateView, bool finalMove, Fun &undo, Fun &redo);
bool requestClipDeletion(int clipId, bool updateView, bool finalMove, Fun &undo, Fun &redo, bool groupMove = false);
/* @brief This function returns a lambda that performs the requested operation */
Fun requestClipDeletion_lambda(int clipId, bool updateView, bool finalMove);
Fun requestClipDeletion_lambda(int clipId, bool updateView, bool finalMove, bool groupMove = false);
/* @brief Performs an insertion of the given composition.
Returns true if the operation succeeded, and otherwise, the track is not modified.
......
......@@ -63,7 +63,6 @@ void TimelineTabs::connectTimeline(TimelineWidget *timeline)
connect(timeline->controller(), &TimelineController::seeked, pCore->monitorManager()->projectMonitor(), &Monitor::requestSeek, Qt::DirectConnection);
connect(pCore->monitorManager()->projectMonitor(), &Monitor::seekPosition, timeline->controller(), &TimelineController::onSeeked, Qt::DirectConnection);
connect(timeline, &TimelineWidget::focusProjectMonitor, pCore->monitorManager(), &MonitorManager::focusProjectMonitor);
connect(timeline->controller(), &TimelineController::durationChanged, pCore->projectManager(), &ProjectManager::adjustProjectDuration);
connect(this, &TimelineTabs::audioThumbFormatChanged, timeline->controller(), &TimelineController::audioThumbFormatChanged);
connect(this, &TimelineTabs::showThumbnailsChanged, timeline->controller(), &TimelineController::showThumbnailsChanged);
......
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