Commit 79aabb29 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix possible crash on project open

Improve error message on document opening
Save timeline thumbnails on project save
parent b5f46526
......@@ -11,6 +11,7 @@ the Free Software Foundation, either version 3 of the License, or
#include "projectmanager.h"
#include "bin/bin.h"
#include "bin/projectitemmodel.h"
#include "utils/thumbnailcache.hpp"
#include "core.h"
#include "doc/kdenlivedoc.h"
#include "jobs/jobmanager.h"
......@@ -291,7 +292,8 @@ bool ProjectManager::saveFileAs(const QString &outputFileName)
}
QUrl url = QUrl::fromLocalFile(outputFileName);
// Save timeline thumbnails
// m_trackView->projectView()->saveThumbnails();
QStringList thumbKeys = pCore->window()->getMainTimeline()->controller()->getThumbKeys();
ThumbnailCache::get()->saveCachedThumbs(thumbKeys);
m_project->setUrl(url);
// setting up autosave file in ~/.kde/data/stalefiles/kdenlive/
// saved under file name
......
......@@ -31,14 +31,14 @@
#include "kdenlivesettings.h"
#include <KLocalizedString>
#include <QMessageBox>
#include <KMessageBox>
#include <QDebug>
#include <QSet>
#include <mlt++/MltPlaylist.h>
#include <mlt++/MltProducer.h>
#include <mlt++/MltTransition.h>
static QString m_errorMessage;
static QStringList m_errorMessage;
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Tractor &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo);
......@@ -140,9 +140,9 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
ok = timeline->requestCompositionInsertion(id, timeline->getTrackIndexFromPosition(t->get_b_track() - 1), t->get_a_track(), t->get_in(),
t->get_length(), &transProps, compoId, undo, redo);
if (!ok) {
qDebug() << "ERROR : failed to insert composition in track " << t->get_b_track() << ", position" << t->get_in();
timeline->requestItemDeletion(compoId, false);
m_errorMessage.append(i18n("Invalid composition found on track %1 at %2.\n", t->get_b_track(), t->get_in()));
qDebug() << "ERROR : failed to insert composition in track " << t->get_b_track() << ", position" << t->get_in()<<", ID: "<<id<<", MLT ID: "<<t->get("id");
//timeline->requestItemDeletion(compoId, false);
m_errorMessage <<i18n("Invalid composition %1 found on track %2 at %3.", t->get("id"), t->get_b_track(), t->get_in());
continue;
}
qDebug() << "Inserted composition in track " << t->get_b_track() << ", position" << t->get_in() << "/" << t->get_out();
......@@ -159,7 +159,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
return false;
}
if (!m_errorMessage.isEmpty()) {
QMessageBox::warning(qApp->activeWindow(), i18n("Project problems"), m_errorMessage, QMessageBox::Close);
KMessageBox::sorry(qApp->activeWindow(), m_errorMessage.join("\n"), i18n("Problems found in your project file"));
}
return true;
}
......@@ -281,7 +281,7 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
if (!ok && cid > -1) {
qDebug() << "ERROR : failed to insert clip in track" << tid << "position" << position;
timeline->requestItemDeletion(cid, false);
m_errorMessage.append(i18n("Invalid clip found on track %1 at %2.\n", track.get("id"), position));
m_errorMessage << i18n("Invalid clip %1 found on track %2 at %3.", clip->parent().get("id"), track.get("id"), position);
break;
}
qDebug() << "Inserted clip in track" << tid << "at " << position;
......
......@@ -58,9 +58,11 @@ ClipModel::ClipModel(std::shared_ptr<TimelineModel> parent, std::shared_ptr<Mlt:
m_endlessResize = false;
}
QObject::connect(m_effectStack.get(), &EffectStackModel::dataChanged, [&](){
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->dataChanged(ix, ix, {TimelineModel::EffectNamesRole,TimelineModel::FadeInRole,TimelineModel::FadeOutRole});
if (m_currentTrackId != -1) {
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->dataChanged(ix, ix, {TimelineModel::EffectNamesRole,TimelineModel::FadeInRole,TimelineModel::FadeOutRole});
}
}
});
}
......
......@@ -2031,3 +2031,15 @@ bool TimelineController::endFakeGroupMove(int clipId, int groupId, int delta_tra
return true;
}
QStringList TimelineController::getThumbKeys()
{
QStringList result;
for (auto clp : m_model->m_allClips) {
const QString binId = getClipBinId(clp.first);
std::shared_ptr<ProjectClip> binClip = pCore->bin()->getBinClip(binId);
result << binClip->hash() + QLatin1Char('#') + QString::number(clp.second->getIn()) + QStringLiteral(".png");
result << binClip->hash() + QLatin1Char('#') + QString::number(clp.second->getOut()) + QStringLiteral(".png");
}
result.removeDuplicates();
return result;
}
......@@ -405,6 +405,8 @@ public:
Q_INVOKABLE const QString getAssetName(const QString &assetId, bool isTransition);
/** @brief Set keyboard grabbing on current selection */
void grabCurrent();
/** @brief Returns keys for all used thumbnails */
QStringList getThumbKeys();
public slots:
void selectMultitrack();
......
......@@ -162,6 +162,24 @@ void ThumbnailCache::storeThumbnail(const QString &binId, int pos, const QImage
}
}
void ThumbnailCache::saveCachedThumbs(QStringList keys)
{
bool ok;
QDir thumbFolder = getDir(&ok);
if (!ok) {
return;
}
for (const QString &key : keys) {
if (!thumbFolder.exists(key) && m_volatileCache->contains(key)) {
QImage img = m_volatileCache->get(key);
if (!img.save(thumbFolder.absoluteFilePath(key))) {
qDebug()<<"// Error writing thumbnails to "<<thumbFolder.absolutePath();
break;
}
}
}
}
void ThumbnailCache::invalidateThumbsForClip(const QString &binId)
{
QMutexLocker locker(&m_mutex);
......
......@@ -70,6 +70,9 @@ public:
/* @brief Removes all the thumbnails for a given clip */
void invalidateThumbsForClip(const QString &binId);
/* @brief Save all cached thumbs to disk */
void saveCachedThumbs(QStringList keys);
protected:
// Constructor is protected because class is a Singleton
ThumbnailCache();
......
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