]> git.sesse.net Git - kdenlive/blobdiff - src/documentvalidator.cpp
Fix encoding problem in renderer:
[kdenlive] / src / documentvalidator.cpp
index e28d3d1c72511e1bc9c403be1046798d5a324423..e6e0be7edaab395330d09b06003bc9b6c87986d9 100644 (file)
@@ -36,36 +36,34 @@ DocumentValidator::DocumentValidator(QDomDocument doc):
 
 bool DocumentValidator::validate(const double currentVersion)
 {
-    // Check if we're validating a Kdenlive project
-    if (!isProject())
+    QDomElement mlt = m_doc.firstChildElement("mlt");
+    // At least the root element must be there
+    if (mlt.isNull())
         return false;
 
+    QDomElement kdenliveDoc = mlt.firstChildElement("kdenlivedoc");
+    // Check if we're validating a Kdenlive project
+    if (kdenliveDoc.isNull())
+        return false;
     // Upgrade the document to the latest version
-    QDomNode kdenlivedocNode = m_doc.elementsByTagName("kdenlivedoc").at(0);
-    QDomElement kdenlivedocElm = kdenlivedocNode.toElement();
-    if (!upgrade(kdenlivedocElm.attribute("version").toDouble(), currentVersion))
+    if (!upgrade(kdenliveDoc.attribute("version").toDouble(), currentVersion))
         return false;
 
     /*
      * Check the syntax (this will be replaced by XSD validation with Qt 4.6)
      * and correct some errors
      */
-    QDomNode mltNode = m_doc.elementsByTagName("mlt").at(0);
-    QDomElement mltElm = mltNode.toElement();
-    if (mltElm.isNull()) // At least the root element must be there
-        return false;
-    else {
+    {
         // Return (or create) the tractor
-        QDomNode tractorNode = m_doc.elementsByTagName("tractor").at(0);
-        QDomElement tractorElm = tractorNode.toElement();
-        if (tractorElm.isNull()) {
+        QDomElement tractor = mlt.firstChildElement("tractor");
+        if (tractor.isNull()) {
             m_modified = true;
-            tractorElm = m_doc.createElement("tractor");
-            tractorElm.setAttribute("global_feed", "1");
-            tractorElm.setAttribute("in", "0");
-            tractorElm.setAttribute("out", "-1");
-            tractorElm.setAttribute("id", "maintractor");
-            mltElm.appendChild(tractorElm);
+            tractor = m_doc.createElement("tractor");
+            tractor.setAttribute("global_feed", "1");
+            tractor.setAttribute("in", "0");
+            tractor.setAttribute("out", "-1");
+            tractor.setAttribute("id", "maintractor");
+            mlt.appendChild(tractor);
         }
 
         /*
@@ -74,36 +72,67 @@ bool DocumentValidator::validate(const double currentVersion)
          */
         QDomNodeList playlists = m_doc.elementsByTagName("playlist");
         int tracksMax = playlists.count() - 1; // Remove the black track
-        QDomNodeList tracks = m_doc.elementsByTagName("track");
+        QDomNodeList tracks = tractor.elementsByTagName("track");
         tracksMax = qMax(tracks.count() - 1, tracksMax);
-        QDomNodeList tracksinfo = m_doc.elementsByTagName("trackinfo");
+        QDomNodeList tracksinfo = kdenliveDoc.elementsByTagName("trackinfo");
         tracksMax = qMax(tracksinfo.count(), tracksMax);
         tracksMax = qMax(1, tracksMax); // Force existance of one track
         if (playlists.count() - 1 < tracksMax ||
                 tracks.count() - 1 < tracksMax ||
                 tracksinfo.count() < tracksMax) {
+            kDebug() << "//// WARNING, PROJECT IS CORRUPTED, MISSING TRACK";
             m_modified = true;
             int difference;
+            // use the MLT tracks as reference
+            if (tracks.count() - 1 < tracksMax) {
+                // Looks like one MLT track is missing, remove the extra Kdenlive track if there is one.
+                if (tracksinfo.count() != tracks.count() - 1) {
+                    // The Kdenlive tracks are not ok, clear and rebuild them
+                    QDomNode tinfo = kdenliveDoc.elementsByTagName("tracksinfo").at(0);
+                    QDomNode tnode = tinfo.firstChild();
+                    while (!tnode.isNull()) {
+                        tinfo.removeChild(tnode);
+                        tnode = tinfo.firstChild();
+                    }
+
+                    for (int i = 1; i < tracks.count(); i++) {
+                        QString hide = tracks.at(i).toElement().attribute("hide");
+                        QDomElement newTrack = m_doc.createElement("trackinfo");
+                        if (hide == "video") {
+                            // audio track;
+                            newTrack.setAttribute("type", "audio");
+                            newTrack.setAttribute("blind", 1);
+                            newTrack.setAttribute("mute", 0);
+                            newTrack.setAttribute("lock", 0);
+                        } else {
+                            newTrack.setAttribute("blind", 0);
+                            newTrack.setAttribute("mute", 0);
+                            newTrack.setAttribute("lock", 0);
+                        }
+                        tinfo.appendChild(newTrack);
+                    }
+                }
+            }
+
             if (playlists.count() - 1 < tracksMax) {
                 difference = tracksMax - (playlists.count() - 1);
                 for (int i = 0; i < difference; ++i) {
                     QDomElement playlist = m_doc.createElement("playlist");
-                    mltElm.appendChild(playlist);
+                    mlt.appendChild(playlist);
                 }
             }
             if (tracks.count() - 1 < tracksMax) {
                 difference = tracksMax - (tracks.count() - 1);
                 for (int i = 0; i < difference; ++i) {
                     QDomElement track = m_doc.createElement("track");
-                    tractorElm.appendChild(track);
+                    tractor.appendChild(track);
                 }
             }
             if (tracksinfo.count() < tracksMax) {
-                QDomNode tracksinfoNode = m_doc.elementsByTagName("tracksinfo").at(0);
-                QDomElement tracksinfoElm = tracksinfoNode.toElement();
+                QDomElement tracksinfoElm = kdenliveDoc.firstChildElement("tracksinfo");
                 if (tracksinfoElm.isNull()) {
                     tracksinfoElm = m_doc.createElement("tracksinfo");
-                    kdenlivedocElm.appendChild(tracksinfoElm);
+                    kdenliveDoc.appendChild(tracksinfoElm);
                 }
                 difference = tracksMax - tracksinfo.count();
                 for (int i = 0; i < difference; ++i) {
@@ -128,14 +157,13 @@ bool DocumentValidator::upgrade(double version, const double currentVersion)
 
     // No conversion needed
     if (version == currentVersion) {
-        // TODO: uncomment when currentVersion == 0.84
-        //return true;
+        return true;
     }
 
     // The document is too new
     if (version > currentVersion) {
         kDebug() << "Unable to open document with version " << version;
-        KMessageBox::sorry(kapp->activeWindow(), i18n("This project type is unsupported (version %1) and can't be loaded.\nPlease consider upgrading you Kdenlive version.", version), i18n("Unable to open project"));
+        KMessageBox::sorry(kapp->activeWindow(), i18n("This project type is unsupported (version %1) and can't be loaded.\nPlease consider upgrading your Kdenlive version.", version), i18n("Unable to open project"));
         return false;
     }
 
@@ -149,6 +177,7 @@ bool DocumentValidator::upgrade(double version, const double currentVersion)
     // <kdenlivedoc />
     QDomNode infoXmlNode = m_doc.elementsByTagName("kdenlivedoc").at(0);
     QDomElement infoXml = infoXmlNode.toElement();
+    infoXml.setAttribute("upgraded", "1");
 
     if (version <= 0.6) {
         QDomElement infoXml_old = infoXmlNode.cloneNode(true).toElement(); // Needed for folders
@@ -675,7 +704,7 @@ bool DocumentValidator::upgrade(double version, const double currentVersion)
     if (version <= 0.83) {
         // Replace point size with pixel size in text titles
         if (m_doc.toString().contains("font-size")) {
-            KMessageBox::ButtonCode convert;
+            KMessageBox::ButtonCode convert = KMessageBox::Continue;
             QDomNodeList kproducerNodes = m_doc.elementsByTagName("kdenlive_producer");
             for (int i = 0; i < kproducerNodes.count() && convert != KMessageBox::No; ++i) {
                 QDomElement kproducer = kproducerNodes.at(i).toElement();
@@ -722,10 +751,71 @@ bool DocumentValidator::upgrade(double version, const double currentVersion)
         }
     }
 
+    if (version <= 0.84) {
+        // update the title clips to use the new MLT kdenlivetitle producer
+        QDomNodeList kproducerNodes = m_doc.elementsByTagName("kdenlive_producer");
+        for (int i = 0; i < kproducerNodes.count(); ++i) {
+            QDomElement kproducer = kproducerNodes.at(i).toElement();
+            if (kproducer.attribute("type").toInt() == TEXT) {
+                QString data = kproducer.attribute("xmldata");
+                QString datafile = kproducer.attribute("resource");
+                if (!datafile.endsWith(".kdenlivetitle")) {
+                    datafile = QString();
+                    kproducer.setAttribute("resource", QString());
+                }
+                QString id = kproducer.attribute("id");
+                QDomNodeList mltproducers = m_doc.elementsByTagName("producer");
+                bool foundData = false;
+                bool foundResource = false;
+                bool foundService = false;
+                for (int j = 0; j < mltproducers.count(); j++) {
+                    QDomElement wproducer = mltproducers.at(j).toElement();
+                    if (wproducer.attribute("id") == id) {
+                        QDomNodeList props = wproducer.childNodes();
+                        for (int k = 0; k < props.count(); k++) {
+                            if (props.at(k).toElement().attribute("name") == "xmldata") {
+                                props.at(k).firstChild().setNodeValue(data);
+                                foundData = true;
+                            } else if (props.at(k).toElement().attribute("name") == "mlt_service") {
+                                props.at(k).firstChild().setNodeValue("kdenlivetitle");
+                                foundService = true;
+                            } else if (props.at(k).toElement().attribute("name") == "resource") {
+                                props.at(k).firstChild().setNodeValue(datafile);
+                                foundResource = true;
+                            }
+                        }
+                        if (!foundData) {
+                            QDomElement e = m_doc.createElement("property");
+                            e.setAttribute("name", "xmldata");
+                            QDomText value = m_doc.createTextNode(data);
+                            e.appendChild(value);
+                            wproducer.appendChild(e);
+                        }
+                        if (!foundService) {
+                            QDomElement e = m_doc.createElement("property");
+                            e.setAttribute("name", "mlt_service");
+                            QDomText value = m_doc.createTextNode("kdenlivetitle");
+                            e.appendChild(value);
+                            wproducer.appendChild(e);
+                        }
+                        if (!foundResource) {
+                            QDomElement e = m_doc.createElement("property");
+                            e.setAttribute("name", "resource");
+                            QDomText value = m_doc.createTextNode(datafile);
+                            e.appendChild(value);
+                            wproducer.appendChild(e);
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+
     // The document has been converted: mark it as modified
     infoXml.setAttribute("version", currentVersion);
     m_modified = true;
-
     return true;
 }