From 96c6045c119454944e5f61cf3c81d14597188262 Mon Sep 17 00:00:00 2001 From: Alberto Villa Date: Sun, 12 Sep 2010 03:21:19 +0000 Subject: [PATCH] - Cleanup the document creation logic: * avoid loading part of the document if we're going to abort; * replace m_abortLoading with the boolean return values of addClip() and addClipInfo(). svn path=/trunk/kdenlive/; revision=4871 --- src/kdenlivedoc.cpp | 207 ++++++++++++++++++++++---------------------- src/kdenlivedoc.h | 63 ++++++++++---- 2 files changed, 150 insertions(+), 120 deletions(-) diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 7ea9272a..c2a6e836 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -55,8 +55,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup m_render(render), m_commandStack(new QUndoStack(undoGroup)), m_modified(false), - m_projectFolder(projectFolder), - m_abortLoading(false) + m_projectFolder(projectFolder) { m_clipManager = new ClipManager(this); m_autoSaveTimer = new QTimer(this); @@ -91,7 +90,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup success = validator.isProject(); if (!success) { // It is not a project file - parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file", m_url.path()), 0); + parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file", m_url.path()), 100); } else { /* * Validate the file against the current version (upgrade @@ -100,95 +99,96 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup // TODO: backup the document or alert the user? success = validator.validate(DOCUMENTVERSION); if (success) { // Let the validator handle error messages - parent->slotGotProgressInfo(i18n("Loading"), 0); - QDomElement mlt = m_document.firstChildElement("mlt"); - QDomElement infoXml = mlt.firstChildElement("kdenlivedoc"); - - profileName = infoXml.attribute("profile"); - m_projectFolder = KUrl(infoXml.attribute("projectfolder")); - QDomElement docproperties = infoXml.firstChildElement("documentproperties"); - QDomNamedNodeMap props = docproperties.attributes(); - for (int i = 0; i < props.count(); i++) { - m_documentProperties.insert(props.item(i).nodeName(), props.item(i).nodeValue()); - } - // Build tracks - QDomElement e; - QDomElement tracksinfo = infoXml.firstChildElement("tracksinfo"); - if (!tracksinfo.isNull()) { - QDomNodeList trackslist = tracksinfo.childNodes(); - int maxchild = trackslist.count(); - for (int k = 0; k < maxchild; k++) { - e = trackslist.at(k).toElement(); - if (e.tagName() == "trackinfo") { - TrackInfo projectTrack; - if (e.attribute("type") == "audio") projectTrack.type = AUDIOTRACK; - else projectTrack.type = VIDEOTRACK; - projectTrack.isMute = e.attribute("mute").toInt(); - projectTrack.isBlind = e.attribute("blind").toInt(); - projectTrack.isLocked = e.attribute("locked").toInt(); - projectTrack.trackName = e.attribute("trackname"); - m_tracksList.append(projectTrack); + parent->slotGotProgressInfo(i18n("Check missing clips"), 0); + QDomNodeList infoproducers = m_document.elementsByTagName("kdenlive_producer"); + success = checkDocumentClips(infoproducers); + if (success) { + parent->slotGotProgressInfo(i18n("Loading"), 0); + QDomElement mlt = m_document.firstChildElement("mlt"); + QDomElement infoXml = mlt.firstChildElement("kdenlivedoc"); + QDomElement e; + + // Build tracks + QDomElement tracksinfo = infoXml.firstChildElement("tracksinfo"); + if (!tracksinfo.isNull()) { + QDomNodeList trackslist = tracksinfo.childNodes(); + int maxchild = trackslist.count(); + for (int k = 0; k < maxchild; k++) { + e = trackslist.at(k).toElement(); + if (e.tagName() == "trackinfo") { + TrackInfo projectTrack; + if (e.attribute("type") == "audio") + projectTrack.type = AUDIOTRACK; + else + projectTrack.type = VIDEOTRACK; + projectTrack.isMute = e.attribute("mute").toInt(); + projectTrack.isBlind = e.attribute("blind").toInt(); + projectTrack.isLocked = e.attribute("locked").toInt(); + projectTrack.trackName = e.attribute("trackname"); + m_tracksList.append(projectTrack); + } } + mlt.removeChild(tracksinfo); } - mlt.removeChild(tracksinfo); - } - QDomNodeList producers = m_document.elementsByTagName("producer"); - QDomNodeList infoproducers = m_document.elementsByTagName("kdenlive_producer"); - parent->slotGotProgressInfo(i18n("Check missing clips"), 0); - if (checkDocumentClips(infoproducers) == false) m_abortLoading = true; - const int max = producers.count(); - const int infomax = infoproducers.count(); - - QDomNodeList folders = m_document.elementsByTagName("folder"); - for (int i = 0; i < folders.count(); i++) { - e = folders.item(i).cloneNode().toElement(); - m_clipManager->addFolder(e.attribute("id"), e.attribute("name")); - } - for (int i = 0; i < infomax && !m_abortLoading; i++) { - e = infoproducers.item(i).cloneNode().toElement(); - QString prodId = e.attribute("id"); - if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion") && !m_abortLoading) { - e.setTagName("producer"); - // Get MLT's original producer properties - QDomElement orig; - for (int j = 0; j < max; j++) { - QDomElement o = producers.item(j).cloneNode().toElement(); - QString origId = o.attribute("id").section('_', 0, 0); - if (origId == prodId) { - orig = o; + QDomNodeList folders = m_document.elementsByTagName("folder"); + for (int i = 0; i < folders.count(); i++) { + e = folders.item(i).cloneNode().toElement(); + m_clipManager->addFolder(e.attribute("id"), e.attribute("name")); + } + + const int infomax = infoproducers.count(); + QDomNodeList producers = m_document.elementsByTagName("producer"); + const int max = producers.count(); + + for (int i = 0; i < infomax; i++) { + e = infoproducers.item(i).cloneNode().toElement(); + QString prodId = e.attribute("id"); + if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion")) { + e.setTagName("producer"); + // Get MLT's original producer properties + QDomElement orig; + for (int j = 0; j < max; j++) { + QDomElement o = producers.item(j).cloneNode().toElement(); + QString origId = o.attribute("id").section('_', 0, 0); + if (origId == prodId) { + orig = o; + break; + } + } + if (!addClipInfo(e, orig, prodId)) { + // The user manually aborted the loading. + success = false; + emit resetProjectList(); + m_tracksList.clear(); + m_clipManager->clear(); break; } } - addClipInfo(e, orig, prodId); } - } - if (m_abortLoading) { - //parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file."), 100); - emit resetProjectList(); - m_documentProperties.remove("position"); - m_url = KUrl(); - m_tracksList.clear(); - kWarning() << "Aborted loading of: " << url.path(); - m_document = createEmptyDocument(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()); - setProfilePath(KdenliveSettings::default_profile()); - m_clipManager->clear(); - } else { - QDomElement markers = infoXml.firstChildElement("markers"); - if (!markers.isNull()) { - QDomNodeList markerslist = markers.childNodes(); - int maxchild = markerslist.count(); - for (int k = 0; k < maxchild; k++) { - e = markerslist.at(k).toElement(); - if (e.tagName() == "marker") { - m_clipManager->getClipById(e.attribute("id"))->addSnapMarker(GenTime(e.attribute("time").toDouble()), e.attribute("comment")); + + if (success) { + QDomElement markers = infoXml.firstChildElement("markers"); + if (!markers.isNull()) { + QDomNodeList markerslist = markers.childNodes(); + int maxchild = markerslist.count(); + for (int k = 0; k < maxchild; k++) { + e = markerslist.at(k).toElement(); + if (e.tagName() == "marker") + m_clipManager->getClipById(e.attribute("id"))->addSnapMarker(GenTime(e.attribute("time").toDouble()), e.attribute("comment")); } + infoXml.removeChild(markers); } - infoXml.removeChild(markers); + + m_projectFolder = KUrl(infoXml.attribute("projectfolder")); + QDomElement docproperties = infoXml.firstChildElement("documentproperties"); + QDomNamedNodeMap props = docproperties.attributes(); + for (int i = 0; i < props.count(); i++) + m_documentProperties.insert(props.item(i).nodeName(), props.item(i).nodeValue()); + setProfilePath(infoXml.attribute("profile")); + setModified(validator.isModified()); + kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count(); } - setProfilePath(profileName); - setModified(validator.isModified()); - kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count(); } } } @@ -198,8 +198,8 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup // Something went wrong, or a new file was requested: create a new project if (!success) { - setProfilePath(profileName); m_url = KUrl(); + setProfilePath(profileName); m_document = createEmptyDocument(tracks.x(), tracks.y()); } @@ -865,7 +865,7 @@ const QString KdenliveDoc::description() const return m_url.fileName() + " / " + m_profile.description; } -void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) +bool KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) { const QString producerId = clipId.section('_', 0, 0); DocClipBase *clip = m_clipManager->getClipById(producerId); @@ -886,8 +886,10 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) QString newpath; int action = KMessageBox::No; if (!size.isEmpty() && !hash.isEmpty()) { - if (!m_searchFolder.isEmpty()) newpath = searchFileRecursively(m_searchFolder, size, hash); - else action = (KMessageBox::ButtonCode) KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip %1
is invalid, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search automatically")), KGuiItem(i18n("Keep as placeholder"))); + if (!m_searchFolder.isEmpty()) + newpath = searchFileRecursively(m_searchFolder, size, hash); + else + action = (KMessageBox::ButtonCode) KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip %1
is invalid, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search automatically")), KGuiItem(i18n("Keep as placeholder"))); } else { if (elem.attribute("type").toInt() == SLIDESHOW) { int res = KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip %1
is invalid or missing, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search manually")), KGuiItem(i18n("Keep as placeholder"))); @@ -910,18 +912,17 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) if (action == KMessageBox::Yes) { kDebug() << "// ASKED FOR SRCH CLIP: " << clipId; m_searchFolder = KFileDialog::getExistingDirectory(KUrl("kfiledialog:///clipfolder"), kapp->activeWindow()); - if (!m_searchFolder.isEmpty()) { + if (!m_searchFolder.isEmpty()) newpath = searchFileRecursively(QDir(m_searchFolder), size, hash); - } } else if (action == KMessageBox::Cancel) { - m_abortLoading = true; - return; + return false; } else if (action == KMessageBox::No) { // Keep clip as placeHolder elem.setAttribute("placeholder", '1'); } if (!newpath.isEmpty()) { - if (elem.attribute("type").toInt() == SLIDESHOW) newpath.append('/' + extension); + if (elem.attribute("type").toInt() == SLIDESHOW) + newpath.append('/' + extension); elem.setAttribute("resource", newpath); setNewClipResource(clipId, newpath); setModified(true); @@ -935,6 +936,8 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) emit addProjectClip(clip); //qApp->processEvents(); } + + return true; } void KdenliveDoc::setNewClipResource(const QString &id, const QString &path) @@ -994,17 +997,17 @@ QString KdenliveDoc::searchFileRecursively(const QDir &dir, const QString &match return foundFileName; } -void KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, QString clipId) +bool KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, QString clipId) { DocClipBase *clip = m_clipManager->getClipById(clipId); if (clip == NULL) { - addClip(elem, clipId, false); + if (!addClip(elem, clipId, false)) + return false; } else { QMap properties; QDomNamedNodeMap attributes = elem.attributes(); - QString attrname; for (int i = 0; i < attributes.count(); i++) { - attrname = attributes.item(i).nodeName(); + QString attrname = attributes.item(i).nodeName(); if (attrname != "resource") properties.insert(attrname, attributes.item(i).nodeValue()); kDebug() << attrname << " = " << attributes.item(i).nodeValue(); @@ -1014,19 +1017,19 @@ void KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, QString clipId } if (orig != QDomElement()) { QMap meta; - QDomNode m = orig.firstChild(); - while (!m.isNull()) { + for (QDomNode m = orig.firstChild(); !m.isNull(); m = m.nextSibling()) { QString name = m.toElement().attribute("name"); - if (name.startsWith("meta.attr")) { + if (name.startsWith("meta.attr")) meta.insert(name.section('.', 2, 3), m.firstChild().nodeValue()); - } - m = m.nextSibling(); } if (!meta.isEmpty()) { - if (clip == NULL) clip = m_clipManager->getClipById(clipId); - if (clip) clip->setMetadata(meta); + if (clip == NULL) + clip = m_clipManager->getClipById(clipId); + if (clip) + clip->setMetadata(meta); } } + return true; } diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index d8d2fc22..da9e5881 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -66,27 +66,43 @@ Q_OBJECT public: QDomDocument m_guidesXml; QDomElement guidesXml() const; ClipManager *clipManager(); - /** @brief Add a clip to the project tree */ - void addClip(QDomElement elem, QString clipId, bool createClipItem = true); - void addClipInfo(QDomElement elem, QDomElement orig, QString clipId); + + /** @brief Adds a clip to the project tree. + * @return false if the user aborted the operation, true otherwise */ + bool addClip(QDomElement elem, QString clipId, bool createClipItem = true); + + /** @brief Updates information about a clip. + * @param elem the + * @param orig the potential + * @param clipId the producer id + * @return false if the user aborted the operation (in case the clip wasn't + * there yet), true otherwise + * + * If the clip wasn't added before, it tries to add it to the project. */ + bool addClipInfo(QDomElement elem, QDomElement orig, QString clipId); void slotAddClipFile(const KUrl url, const QString group, const QString &groupId = QString()); void slotAddClipList(const KUrl::List urls, const QString group, const QString &groupId = QString()); void deleteClip(const QString &clipId); int getFramePos(QString duration); DocClipBase *getBaseClip(const QString &clipId); void updateClip(const QString id); - /** Inform application of the audio thumbnails generation progress */ + + /** @brief Informs Kdenlive of the audio thumbnails generation progress. */ void setThumbsProgress(const QString &message, int progress); const QString &profilePath() const; MltVideoProfile mltProfile() const; const QString description() const; void setUrl(KUrl url); - /** update project profile, returns true if fps was changed */ + + /** @brief Updates the project profile. + * @return true if frame rate was changed */ bool setProfilePath(QString path); const QString getFreeClipId(); - /** does the document need saving */ + + /** @brief Defines whether the document needs to be saved. */ bool isModified() const; - /** Returns project folder, used to store project files (titles, effects,...) */ + + /** @brief Returns the project folder, used to store project files. */ KUrl projectFolder() const; void syncGuides(QList guides); void setZoom(int horizontal, int vertical); @@ -114,7 +130,8 @@ Q_OBJECT public: bool isTrackLocked(int ix) const; void setDocumentProperty(const QString &name, const QString &value); const QString getDocumentProperty(const QString &name) const; - /** @brief get the list of renderer properties that were saved in the document */ + + /** @brief Gets the list of renderer properties saved into the document. */ QMap getRenderProperties() const; void addTrackEffect(int ix, QDomElement effect); void removeTrackEffect(int ix, QDomElement effect); @@ -135,11 +152,12 @@ private: MltVideoProfile m_profile; QTimer *m_autoSaveTimer; QString m_searchFolder; - /** tells whether current doc has been changed since last save event */ + + /** @brief Tells whether the current document has been changed after being saved. */ bool m_modified; - /** Project folder, used to store project files (titles, effects,...) */ + + /** @brief The project folder, used to store project files (titles, effects...). */ KUrl m_projectFolder; - bool m_abortLoading; QMap m_documentProperties; QList m_tracksList; @@ -147,20 +165,26 @@ private: QString searchFileRecursively(const QDir &dir, const QString &matchSize, const QString &matchHash) const; void moveProjectData(KUrl url); bool checkDocumentClips(QDomNodeList infoproducers); - /** Creates a new project */ + + /** @brief Creates a new project. */ QDomDocument createEmptyDocument(int videotracks, int audiotracks); QDomDocument createEmptyDocument(QList tracks); public slots: void slotCreateXmlClip(const QString &name, const QDomElement xml, QString group, const QString &groupId); void slotCreateColorClip(const QString &name, const QString &color, const QString &duration, QString group, const QString &groupId); - void slotCreateSlideshowClipFile(const QString name, const QString path, int count, const QString duration, - const bool loop, const bool crop, const bool fade, - const QString &luma_duration, const QString &luma_file, const int softness, - const QString &animation, QString group, const QString &groupId); + void slotCreateSlideshowClipFile(const QString name, const QString path, + int count, const QString duration, + const bool loop, const bool crop, + const bool fade, const QString &luma_duration, + const QString &luma_file, const int softness, + const QString &animation, QString group, + const QString &groupId); void slotCreateTextClip(QString group, const QString &groupId, const QString &templatePath = QString()); void slotCreateTextTemplateClip(QString group, const QString &groupId, KUrl path); - /** Set to true if document needs saving, false otherwise */ + + /** @brief Sets the document as modified or up to date. + * @param mod (optional) true if the document has to be saved */ void setModified(bool mod = true); void checkProjectClips(); @@ -174,7 +198,10 @@ signals: void updateClipDisplay(const QString&); void deleteTimelineClip(const QString&); void progressInfo(const QString &, int); - /** emitted when the document state has been modified (= needs saving or not) */ + + /** @brief Informs that the document status has been changed. + * + * If the document has been modified, it's called with true as an argument. */ void docModified(bool); void selectLastAddedClip(const QString &); void guidesUpdated(); -- 2.39.2