]> git.sesse.net Git - kdenlive/blobdiff - src/kdenlivedoc.cpp
Improve handling of missing clips:
[kdenlive] / src / kdenlivedoc.cpp
index 312ef1555f0d336967320d109c0f4019a47fe3e7..f10e6caa0636fa27ae7956f1ea36228c476018be 100644 (file)
@@ -26,6 +26,8 @@
 #include "clipmanager.h"
 #include "titlewidget.h"
 #include "mainwindow.h"
+#include "documentchecker.h"
+#include "kdenlive-config.h"
 
 #include <KDebug>
 #include <KStandardDirs>
@@ -41,7 +43,6 @@
 
 #include <mlt++/Mlt.h>
 
-
 KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QPoint tracks, Render *render, MainWindow *parent) :
         QObject(parent),
         m_autosave(NULL),
@@ -133,9 +134,9 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                         }
                         westley.removeChild(tracksinfo);
                     }
-
                     QDomNodeList producers = m_document.elementsByTagName("producer");
                     QDomNodeList infoproducers = m_document.elementsByTagName("kdenlive_producer");
+                    if (checkDocumentClips(producers, infoproducers) == false) m_abortLoading = true;
                     const int max = producers.count();
                     const int infomax = infoproducers.count();
 
@@ -250,7 +251,9 @@ KdenliveDoc::~KdenliveDoc()
 void KdenliveDoc::setSceneList()
 {
     m_render->setSceneList(m_document.toString(), m_startPos);
-    //checkProjectClips();
+    // m_document xml is now useless, clear it
+    m_document.clear();
+    checkProjectClips();
 }
 
 QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int audiotracks)
@@ -1008,6 +1011,7 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene)
 
     QDomElement markers = sceneList.createElement("markers");
     addedXml.setAttribute("version", "0.82");
+    addedXml.setAttribute("kdenliveversion", VERSION);
     addedXml.setAttribute("profile", profilePath());
     addedXml.setAttribute("position", m_render->seekPosition().frames(m_fps));
     addedXml.setAttribute("zonein", m_zoneStart);
@@ -1195,6 +1199,7 @@ void KdenliveDoc::setRenderer(Render *render) {
 
 void KdenliveDoc::checkProjectClips()
 {
+    kDebug() << "+++++++++++++ + + + + CHK PCLIPS";
     if (m_render == NULL) return;
     m_clipManager->resetProducersList(m_render->producersList());
     return;
@@ -1277,34 +1282,6 @@ QString KdenliveDoc::producerName(const QString &id)
     return result;
 }
 
-void KdenliveDoc::setProducerDuration(const QString &id, int duration)
-{
-    QDomNodeList prods = producersList();
-    int ct = prods.count();
-    for (int i = 0; i <  ct ; i++) {
-        QDomElement e = prods.item(i).toElement();
-        if (e.attribute("id") != "black" && e.attribute("id") == id) {
-            e.setAttribute("duration", QString::number(duration));
-            break;
-        }
-    }
-}
-
-int KdenliveDoc::getProducerDuration(const QString &id)
-{
-    int result = 0;
-    QDomNodeList prods = producersList();
-    int ct = prods.count();
-    for (int i = 0; i <  ct ; i++) {
-        QDomElement e = prods.item(i).toElement();
-        if (e.attribute("id") != "black" && e.attribute("id") == id) {
-            result = e.attribute("duration").toInt();
-            break;
-        }
-    }
-    return result;
-}
-
 QDomDocument KdenliveDoc::toXml()
 {
     return m_document;
@@ -1380,6 +1357,7 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
 {
     const QString producerId = clipId.section('_', 0, 0);
     DocClipBase *clip = m_clipManager->getClipById(producerId);
+
     if (clip == NULL) {
         elem.setAttribute("id", producerId);
         QString path = elem.attribute("resource");
@@ -1411,7 +1389,8 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
             setNewClipResource(clipId, titleresource);
             delete dia_ui;
         }
-        if (path.isEmpty() == false && QFile::exists(path) == false && elem.attribute("type").toInt() != TEXT) {
+
+        if (path.isEmpty() == false && QFile::exists(path) == false && elem.attribute("type").toInt() != TEXT && !elem.hasAttribute("placeholder")) {
             kDebug() << "// FOUND MISSING CLIP: " << path << ", TYPE: " << elem.attribute("type").toInt();
             const QString size = elem.attribute("file_size");
             const QString hash = elem.attribute("file_hash");
@@ -1425,17 +1404,17 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
                     int res = KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br>is invalid or missing, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search manually")), KGuiItem(i18n("Keep as placeholder")));
                     if (res == KMessageBox::Yes)
                         newpath = KFileDialog::getExistingDirectory(KUrl("kfiledialog:///clipfolder"), kapp->activeWindow(), i18n("Looking for %1", path));
-                    else if (res == KMessageBox::Cancel) {
+                    else {
                         // Abort project loading
-                        action = KMessageBox::Cancel;
+                        action = res;
                     }
                 } else {
                     int res = KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br>is invalid or missing, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search manually")), KGuiItem(i18n("Keep as placeholder")));
                     if (res == KMessageBox::Yes)
                         newpath = KFileDialog::getOpenFileName(KUrl("kfiledialog:///clipfolder"), QString(), kapp->activeWindow(), i18n("Looking for %1", path));
-                    else if (res == KMessageBox::Cancel) {
+                    else {
                         // Abort project loading
-                        action = KMessageBox::Cancel;
+                        action = res;
                     }
                 }
             }
@@ -1448,6 +1427,9 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
             } else if (action == KMessageBox::Cancel) {
                 m_abortLoading = true;
                 return;
+            } 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);
@@ -1698,5 +1680,30 @@ QString KdenliveDoc::getLadspaFile() const
     return m_projectFolder.path() + "/ladspa/" + counter + ".ladspa";
 }
 
+bool KdenliveDoc::checkDocumentClips(QDomNodeList producers, QDomNodeList infoproducers)
+{
+    int clipType;
+    QDomElement e;
+    QString id;
+    QString resource;
+    QList <QDomElement> missingClips;
+    for (int i = 0; i < infoproducers.count(); i++) {
+        e = infoproducers.item(i).toElement();
+        clipType = e.attribute("type").toInt();
+        if (clipType == TEXT) continue;
+        id = e.attribute("id");
+        resource = e.attribute("resource");
+        if (clipType == SLIDESHOW) resource = KUrl(resource).directory();
+        if (!KIO::NetAccess::exists(KUrl(resource), KIO::NetAccess::SourceSide, 0)) {
+            // Missing clip found
+            missingClips.append(e);
+        }
+    }
+    if (missingClips.isEmpty()) return true;
+    DocumentChecker d(producers, infoproducers, missingClips, m_document);
+    return (d.exec() == QDialog::Accepted);
+}
+
+
 #include "kdenlivedoc.moc"