Various timeline preview fixes (resize clip did not invalidate, undo/redo...

Various timeline preview fixes (resize clip did not invalidate, undo/redo sometimes restoring invalid chunks)
parent 6dca5a88
......@@ -32,7 +32,7 @@ DocUndoStack::DocUndoStack(QUndoGroup *parent)
void DocUndoStack::push(QUndoCommand *cmd)
{
if (index() < count()) {
emit invalidate();
emit invalidate(index());
}
QUndoStack::push(cmd);
}
......@@ -33,7 +33,7 @@ public:
explicit DocUndoStack(QUndoGroup *parent = Q_NULLPTR);
void push(QUndoCommand *cmd);
signals:
void invalidate();
void invalidate(int ix);
};
#endif
......@@ -86,7 +86,7 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
connect(this, SIGNAL(updateCompositionMode(int)), parent, SLOT(slotUpdateCompositeAction(int)));
bool success = false;
connect(m_commandStack.get(), &QUndoStack::indexChanged, this, &KdenliveDoc::slotModified);
connect(m_commandStack.get(), &DocUndoStack::invalidate, this, &KdenliveDoc::checkPreviewStack);
connect(m_commandStack.get(), &DocUndoStack::invalidate, this, &KdenliveDoc::checkPreviewStack, Qt::DirectConnection);
// connect(m_commandStack, SIGNAL(cleanChanged(bool)), this, SLOT(setModified(bool)));
// init default document properties
......@@ -1617,10 +1617,10 @@ void KdenliveDoc::initProxySettings()
m_proxyExtension = params.section(QLatin1Char(';'), 1);
}
void KdenliveDoc::checkPreviewStack()
void KdenliveDoc::checkPreviewStack(int ix)
{
// A command was pushed in the middle of the stack, remove all cached data from last undos
emit removeInvalidUndo(m_commandStack->count());
emit removeInvalidUndo(ix);
}
void KdenliveDoc::saveMltPlaylist(const QString &fileName)
......
......@@ -228,7 +228,7 @@ private slots:
void switchProfile(std::unique_ptr<ProfileParam> &profile, const QString &id, const QDomElement &xml);
void slotSwitchProfile(const QString &profile_path, bool reloadThumbs);
/** @brief Check if we did a new action invalidating more recent undo items. */
void checkPreviewStack();
void checkPreviewStack(int ix);
/** @brief Guides were changed, save to MLT. */
void guidesChanged();
......
......@@ -165,6 +165,8 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
}
int in = m_producer->get_in();
int out = m_producer->get_out();
int oldIn = m_position;
int oldOut = m_position + out - in;
int old_in = in, old_out = out;
// check if there is enough space on the chosen side
if (!m_endlessResize) {
......@@ -219,13 +221,30 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
roles.push_back(TimelineModel::OutPointRole);
}
Fun operation = [this, inPoint, outPoint, roles, track_operation]() {
Fun operation = [this, inPoint, outPoint, roles, oldIn, oldOut, right, logUndo, track_operation]() {
if (track_operation()) {
setInOut(inPoint, outPoint);
if (m_currentTrackId > -1) {
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->notifyChange(ix, ix, roles);
// invalidate timeline preview
if (logUndo) {
if (right) {
int newOut = m_position + getOut() - getIn();
if (oldOut < newOut) {
ptr->invalidateZone(oldOut, newOut);
} else {
ptr->invalidateZone(newOut, oldOut);
}
} else {
if (oldIn < m_position) {
ptr->invalidateZone(oldIn, m_position);
} else {
ptr->invalidateZone(m_position, oldIn);
}
}
}
}
}
return true;
......@@ -249,13 +268,29 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
track_reverse = ptr->getTrackById(m_currentTrackId)->requestClipResize_lambda(m_id, old_in, old_out, right);
}
}
reverse = [this, old_in, old_out, track_reverse, roles]() {
reverse = [this, old_in, old_out, track_reverse, logUndo, oldIn, oldOut, right, roles]() {
if (track_reverse()) {
setInOut(old_in, old_out);
if (m_currentTrackId > -1) {
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->notifyChange(ix, ix, roles);
if (logUndo) {
if (right) {
int newOut = m_position + getOut() - getIn();
if (oldOut < newOut) {
ptr->invalidateZone(oldOut, newOut);
} else {
ptr->invalidateZone(newOut, oldOut);
}
} else {
if (oldIn < m_position) {
ptr->invalidateZone(oldIn, m_position);
} else {
ptr->invalidateZone(m_position, oldIn);
}
}
}
}
}
return true;
......
......@@ -52,6 +52,8 @@ TrackModel::TrackModel(const std::weak_ptr<TimelineModel> &parent, int id, const
m_playlist.set("hide", 1);
}
}
// For now we never use the second playlist, only planned for same track transitions
m_playlists[1].set("hide", 3);
m_track->set("kdenlive:trackheight", KdenliveSettings::trackheight());
m_effectStack = EffectStackModel::construct(m_mainPlaylist, {ObjectType::TimelineTrack, m_id}, ptr->m_undoStack);
// TODO
......@@ -536,7 +538,7 @@ Fun TrackModel::requestClipResize_lambda(int clipId, int in, int out, bool right
if (old_out < new_out) {
ptr->checkRefresh(old_out, new_out);
} else {
ptr->checkRefresh(old_in, old_out);
ptr->checkRefresh(new_out, old_out);
}
} else if (old_in < new_in) {
ptr->checkRefresh(old_in, new_in);
......@@ -783,11 +785,12 @@ void TrackModel::setProperty(const QString &name, const QString &value)
{
QWriteLocker locker(&m_lock);
m_track->set(name.toUtf8().constData(), value.toUtf8().constData());
// Hide property mus be defined at playlist level or it won't be saved
// Hide property must be defined at playlist level or it won't be saved
if (name == QLatin1String("kdenlive:audio_track") || name == QLatin1String("hide")) {
for (auto &m_playlist : m_playlists) {
m_playlists[0].set(name.toUtf8().constData(), value.toInt());
/*for (auto &m_playlist : m_playlists) {
m_playlist.set(name.toUtf8().constData(), value.toInt());
}
}*/
}
}
......
......@@ -645,18 +645,20 @@ void PreviewManager::slotRemoveInvalidUndo(int ix)
void PreviewManager::invalidatePreview(int startFrame, int endFrame)
{
if (m_previewTrack == nullptr) {
return;
}
int chunkSize = KdenliveSettings::timelinechunks();
int start = startFrame - startFrame % chunkSize;
int end = endFrame - endFrame % chunkSize + chunkSize;
int end = endFrame - endFrame % chunkSize;
std::sort(m_renderedChunks.begin(), m_renderedChunks.end());
m_previewGatherTimer.stop();
abortRendering();
m_tractor->lock();
bool hasPreview = m_previewTrack != nullptr;
bool chunksChanged = false;
for (int i = start; i <= end; i += chunkSize) {
if (m_renderedChunks.contains(i) && hasPreview) {
if (m_renderedChunks.contains(i)) {
int ix = m_previewTrack->get_clip_index_at(i);
if (m_previewTrack->is_blank(ix)) {
continue;
......@@ -671,12 +673,12 @@ void PreviewManager::invalidatePreview(int startFrame, int endFrame)
}
}
}
m_tractor->unlock();
if (chunksChanged) {
m_previewTrack->consolidate_blanks();
m_controller->renderedChunksChanged();
m_controller->dirtyChunksChanged();
}
m_tractor->unlock();
m_previewGatherTimer.start();
}
......
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