Commit 824b4cd0 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Show progress when loading a document

Related to #210
parent 75661730
......@@ -43,6 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KLocalizedString>
#include <QIcon>
#include <QMimeData>
#include <QProgressDialog>
#include <mlt++/Mlt.h>
#include <queue>
#include <qvarlengtharray.h>
......@@ -868,7 +869,7 @@ bool ProjectItemModel::isIdFree(const QString &id) const
return true;
}
void ProjectItemModel::loadBinPlaylist(Mlt::Tractor *documentTractor, Mlt::Tractor *modelTractor, std::unordered_map<QString, QString> &binIdCorresp)
void ProjectItemModel::loadBinPlaylist(Mlt::Tractor *documentTractor, Mlt::Tractor *modelTractor, std::unordered_map<QString, QString> &binIdCorresp, QProgressDialog *progressDialog)
{
QWriteLocker locker(&m_lock);
clean();
......@@ -896,7 +897,13 @@ void ProjectItemModel::loadBinPlaylist(Mlt::Tractor *documentTractor, Mlt::Tract
Fun redo = []() { return true; };
qDebug() << "Found " << playlist.count() << "clips";
int max = playlist.count();
if (progressDialog) {
progressDialog->setMaximum(progressDialog->maximum() + max);
}
for (int i = 0; i < max; i++) {
if (progressDialog) {
progressDialog->setValue(i);
}
QScopedPointer<Mlt::Producer> prod(playlist.get_clip(i));
std::shared_ptr<Mlt::Producer> producer(new Mlt::Producer(prod->parent()));
qDebug() << "dealing with bin clip" << i;
......
......@@ -39,6 +39,7 @@ class FileWatcher;
class MarkerListModel;
class ProjectClip;
class ProjectFolder;
class QProgressDialog;
namespace Mlt {
class Producer;
......@@ -107,7 +108,7 @@ public:
bool loadFolders(Mlt::Properties &folders);
/* @brief Parse a bin playlist from the document tractor and reconstruct the tree */
void loadBinPlaylist(Mlt::Tractor *documentTractor, Mlt::Tractor *modelTractor, std::unordered_map<QString, QString> &binIdCorresp);
void loadBinPlaylist(Mlt::Tractor *documentTractor, Mlt::Tractor *modelTractor, std::unordered_map<QString, QString> &binIdCorresp, QProgressDialog *progressDialog = nullptr);
/** @brief Save document properties in MLT's bin playlist */
void saveDocumentProperties(const QMap<QString, QString> &props, const QMap<QString, QString> &metadata, std::shared_ptr<MarkerListModel> guideModel);
......
......@@ -76,6 +76,7 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
: QObject(parent)
, m_autosave(nullptr)
, m_url(url)
, m_clipsCount(0)
, m_commandStack(std::make_shared<DocUndoStack>(undoGroup))
, m_modified(false)
, m_documentOpenStatus(CleanProject)
......@@ -252,6 +253,8 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
pCore->setCurrentProfile(profileName);
m_document = createEmptyDocument(tracks.x(), tracks.y());
updateProjectProfile(false);
} else {
m_clipsCount = m_document.elementsByTagName(QLatin1String("entry")).size();
}
if (!m_projectFolder.isEmpty()) {
......@@ -303,9 +306,18 @@ KdenliveDoc::~KdenliveDoc()
}
}
int KdenliveDoc::clipsCount() const
{
return m_clipsCount;
}
const QByteArray KdenliveDoc::getProjectXml()
{
return m_document.toString().toUtf8();
const QByteArray result = m_document.toString().toUtf8();
// We don't need the xml data anymore, throw away
m_document.clear();
return result;
}
QDomDocument KdenliveDoc::createEmptyDocument(int videotracks, int audiotracks)
......@@ -723,21 +735,11 @@ int KdenliveDoc::getFramePos(const QString &duration)
return m_timecode.getFrameCount(duration);
}
QDomDocument KdenliveDoc::toXml()
{
return m_document;
}
Timecode KdenliveDoc::timecode() const
{
return m_timecode;
}
QDomNodeList KdenliveDoc::producersList()
{
return m_document.elementsByTagName(QStringLiteral("producer"));
}
int KdenliveDoc::width() const
{
return pCore->getCurrentProfile()->width();
......
......@@ -65,14 +65,12 @@ public:
friend class LoadJob;
/** @brief Get current document's producer. */
const QByteArray getProjectXml();
QDomNodeList producersList();
double fps() const;
int width() const;
int height() const;
QUrl url() const;
KAutoSaveFile *m_autosave;
Timecode timecode() const;
QDomDocument toXml();
std::shared_ptr<DocUndoStack> commandStack();
int getFramePos(const QString &duration);
......@@ -159,10 +157,13 @@ public:
bool updatePreviewSettings(const QString &profile);
/** @brief Returns the recommended proxy profile parameters */
QString getAutoProxyProfile();
/** @brief Returns the number of clips in this project (useful to show loading progress) */
int clipsCount() const;
private:
QUrl m_url;
QDomDocument m_document;
int m_clipsCount;
/** @brief MLT's root (base path) that is stripped from urls in saved xml */
QString m_documentRoot;
Timecode m_timecode;
......
......@@ -542,6 +542,7 @@ void ProjectManager::doOpenFile(const QUrl &url, KAutoSaveFile *stale)
stale->setParent(doc);
}
m_progressDialog->setLabelText(i18n("Loading clips"));
m_progressDialog->setMaximum(doc->clipsCount());
// TODO refac delete this
pCore->bin()->setDocument(doc);
......@@ -870,7 +871,7 @@ bool ProjectManager::updateTimeline(int pos, int scrollPos)
}
m_mainTimelineModel = TimelineItemModel::construct(&pCore->getCurrentProfile()->profile(), m_project->getGuideModel(), m_project->commandStack());
pCore->window()->getMainTimeline()->setModel(m_mainTimelineModel);
if (!constructTimelineFromMelt(m_mainTimelineModel, tractor)) {
if (!constructTimelineFromMelt(m_mainTimelineModel, tractor, m_progressDialog)) {
//TODO: act on project load failure
qDebug()<<"// Project failed to load!!";
}
......
......@@ -33,6 +33,7 @@
#include <KLocalizedString>
#include <KMessageBox>
#include <QDebug>
#include <QProgressDialog>
#include <QSet>
#include <mlt++/MltPlaylist.h>
#include <mlt++/MltProducer.h>
......@@ -42,11 +43,11 @@
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, bool audioTrack);
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog = nullptr);
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Playlist &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack);
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog = nullptr);
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor tractor)
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor tractor, QProgressDialog *progressDialog)
{
Fun undo = []() { return true; };
Fun redo = []() { return true; };
......@@ -54,11 +55,10 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
timeline->requestReset(undo, redo);
m_errorMessage.clear();
std::unordered_map<QString, QString> binIdCorresp;
pCore->projectItemModel()->loadBinPlaylist(&tractor, timeline->tractor(), binIdCorresp);
pCore->projectItemModel()->loadBinPlaylist(&tractor, timeline->tractor(), binIdCorresp, progressDialog);
QSet<QString> reserved_names{QLatin1String("playlistmain"), QLatin1String("timeline_preview"), QLatin1String("timeline_overlay"),
QLatin1String("black_track")};
bool ok = true;
qDebug() << "//////////////////////\nTrying to construct" << tractor.count() << "tracks.\n////////////////////////////////";
for (int i = 0; i < tractor.count() && ok; i++) {
......@@ -79,7 +79,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
ok = timeline->requestTrackInsertion(-1, tid, QString(), audioTrack, undo, redo, false);
int lockState = track->get_int("kdenlive:locked_track");
Mlt::Tractor local_tractor(*track);
ok = ok && constructTrackFromMelt(timeline, tid, local_tractor, binIdCorresp, undo, redo, audioTrack);
ok = ok && constructTrackFromMelt(timeline, tid, local_tractor, binIdCorresp, undo, redo, audioTrack, progressDialog);
timeline->setTrackProperty(tid, QStringLiteral("kdenlive:thumbs_format"), track->get("kdenlive:thumbs_format"));
timeline->setTrackProperty(tid, QStringLiteral("kdenlive:audio_rec"), track->get("kdenlive:audio_rec"));
if (lockState > 0) {
......@@ -100,7 +100,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
timeline->setTrackProperty(tid, QStringLiteral("hide"), QString::number(muteState));
}
int lockState = local_playlist.get_int("kdenlive:locked_track");
ok = ok && constructTrackFromMelt(timeline, tid, local_playlist, binIdCorresp, undo, redo, audioTrack);
ok = ok && constructTrackFromMelt(timeline, tid, local_playlist, binIdCorresp, undo, redo, audioTrack, progressDialog);
timeline->setTrackProperty(tid, QStringLiteral("kdenlive:thumbs_format"), local_playlist.get("kdenlive:thumbs_format"));
timeline->setTrackProperty(tid, QStringLiteral("kdenlive:audio_rec"), track->get("kdenlive:audio_rec"));
if (lockState > 0) {
......@@ -160,7 +160,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
// build internal track compositing
timeline->buildTrackCompositing();
timeline->updateDuration();
//timeline->updateDuration();
if (!ok) {
// TODO log error
......@@ -175,7 +175,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
}
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Tractor &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack)
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog)
{
if (track.count() != 2) {
// we expect a tractor with two tracks (a "fake" track)
......@@ -189,7 +189,7 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
return false;
}
Mlt::Playlist playlist(*sub_track);
constructTrackFromMelt(timeline, tid, playlist, binIdCorresp, undo, redo, audioTrack);
constructTrackFromMelt(timeline, tid, playlist, binIdCorresp, undo, redo, audioTrack, progressDialog);
if (i == 0) {
// Pass track properties
int height = track.get_int("kdenlive:trackheight");
......@@ -250,12 +250,15 @@ PlaylistState::ClipState inferState(const std::shared_ptr<Mlt::Producer> &prod,
} // namespace
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Playlist &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack)
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog)
{
for (int i = 0; i < track.count(); i++) {
if (track.is_blank(i)) {
continue;
}
if (progressDialog) {
progressDialog->setValue(progressDialog->value() + 1);
}
std::shared_ptr<Mlt::Producer> clip(track.get_clip(i));
int position = track.clip_start(i);
switch (clip->type()) {
......
......@@ -25,10 +25,11 @@
#include <mlt++/MltTractor.h>
class TimelineItemModel;
class QProgressDialog;
/** @brief This function can be used to construct a TimelineModel object from a Mlt object hierarchy
*/
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor mlt_timeline);
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor mlt_timeline, QProgressDialog *progressDialog = nullptr);
#endif
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