]> git.sesse.net Git - kdenlive/blobdiff - src/kdenlivedoc.cpp
Add project folder places entry to Kdenlive file dialogs:
[kdenlive] / src / kdenlivedoc.cpp
index c2a6e8368f96cf2ff55166f44240b729223428b7..f57e9efc34bc47ef37e6aa80e969a6f207925158 100644 (file)
 #include "documentchecker.h"
 #include "documentvalidator.h"
 #include "kdenlive-config.h"
+#include "initeffects.h"
 
 #include <KDebug>
 #include <KStandardDirs>
 #include <KMessageBox>
+#include <KProgressDialog>
 #include <KLocale>
 #include <KFileDialog>
 #include <KIO/NetAccess>
 #include <KIO/CopyJob>
 #include <KApplication>
+#include <KGlobal>
+#include <KBookmarkManager>
+#include <KBookmark>
+#include <KStandardDirs>
 
 #include <QCryptographicHash>
 #include <QFile>
 
 const double DOCUMENTVERSION = 0.85;
 
-KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, const QPoint tracks, Render *render, MainWindow *parent) :
-        QObject(parent),
-        m_autosave(NULL),
-        m_url(url),
-        m_render(render),
-        m_commandStack(new QUndoStack(undoGroup)),
-        m_modified(false),
-        m_projectFolder(projectFolder)
+KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, const QPoint tracks, Render *render, KTextEdit *notes, MainWindow *parent, KProgressDialog *progressDialog) :
+    QObject(parent),
+    m_autosave(NULL),
+    m_url(url),
+    m_render(render),
+    m_notesWidget(notes),
+    m_commandStack(new QUndoStack(undoGroup)),
+    m_modified(false),
+    m_projectFolder(projectFolder)
 {
     m_clipManager = new ClipManager(this);
     m_autoSaveTimer = new QTimer(this);
@@ -86,6 +93,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                 KMessageBox::error(parent, errorMsg);
             else {
                 parent->slotGotProgressInfo(i18n("Validating"), 0);
+                qApp->processEvents();
                 DocumentValidator validator(m_document);
                 success = validator.isProject();
                 if (!success) {
@@ -100,13 +108,27 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                     success = validator.validate(DOCUMENTVERSION);
                     if (success) { // Let the validator handle error messages
                         parent->slotGotProgressInfo(i18n("Check missing clips"), 0);
+                        qApp->processEvents();
                         QDomNodeList infoproducers = m_document.elementsByTagName("kdenlive_producer");
                         success = checkDocumentClips(infoproducers);
                         if (success) {
+                            if (m_document.documentElement().attribute("modified") == "1") setModified(true);
                             parent->slotGotProgressInfo(i18n("Loading"), 0);
                             QDomElement mlt = m_document.firstChildElement("mlt");
                             QDomElement infoXml = mlt.firstChildElement("kdenlivedoc");
+
+                            // Check embedded effects
+                            QDomElement customeffects = infoXml.firstChildElement("customeffects");
+                            if (!customeffects.isNull() && customeffects.hasChildNodes()) {
+                                parent->slotGotProgressInfo(i18n("Importing project effects"), 0);
+                                qApp->processEvents();
+                                if (saveCustomEffects(customeffects.childNodes())) parent->slotReloadEffects();
+                            }
+
                             QDomElement e;
+                            // Read notes
+                            QDomElement notesxml = infoXml.firstChildElement("documentnotes");
+                            if (!notesxml.isNull()) m_notesWidget->setText(notesxml.firstChild().nodeValue());
 
                             // Build tracks
                             QDomElement tracksinfo = infoXml.firstChildElement("tracksinfo");
@@ -131,7 +153,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                                 mlt.removeChild(tracksinfo);
                             }
 
-                            QDomNodeList                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    folders = m_document.elementsByTagName("folder");
+                            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"));
@@ -141,6 +163,16 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                             QDomNodeList producers = m_document.elementsByTagName("producer");
                             const int max = producers.count();
 
+                            if (!progressDialog) {
+                                progressDialog = new KProgressDialog(parent, i18n("Loading project"), i18n("Adding clips"));
+                                progressDialog->setAllowCancel(false);
+                            } else {
+                                progressDialog->setLabelText(i18n("Adding clips"));
+                            }
+                            progressDialog->progressBar()->setMaximum(infomax);
+                            progressDialog->show();
+                            qApp->processEvents();
+
                             for (int i = 0; i < infomax; i++) {
                                 e = infoproducers.item(i).cloneNode().toElement();
                                 QString prodId = e.attribute("id");
@@ -149,13 +181,14 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                                     // 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);
+                                        QDomNode o = producers.item(j);
+                                        QString origId = o.attributes().namedItem("id").nodeValue().section('_', 0, 0);
                                         if (origId == prodId) {
-                                            orig = o;
+                                            orig = o.cloneNode().toElement();
                                             break;
                                         }
                                     }
+
                                     if (!addClipInfo(e, orig, prodId)) {
                                         // The user manually aborted the loading.
                                         success = false;
@@ -165,6 +198,8 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                                         break;
                                     }
                                 }
+                                if (i % 10 == 0)
+                                    progressDialog->progressBar()->setValue(i);
                             }
 
                             if (success) {
@@ -186,7 +221,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                                 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());
+                                if (validator.isModified()) setModified(true);
                                 kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count();
                             }
                         }
@@ -229,6 +264,8 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
     KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "thumbs/");
     KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/");
 
+    updateProjectFolderPlacesEntry();
+
     //kDebug() << "// SETTING SCENE LIST:\n\n" << m_document.toString();
     connect(m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
 }
@@ -453,15 +490,7 @@ void KdenliveDoc::slotAutoSave()
             kDebug() << "ERROR; CANNOT CREATE AUTOSAVE FILE";
         }
         kDebug() << "// AUTOSAVE FILE: " << m_autosave->fileName();
-        QString doc;
-        if (KdenliveSettings::dropbframes()) {
-            KdenliveSettings::setDropbframes(false);
-            m_clipManager->updatePreviewSettings();
-            doc = m_render->sceneList();
-            KdenliveSettings::setDropbframes(true);
-            m_clipManager->updatePreviewSettings();
-        } else doc = m_render->sceneList();
-        saveSceneList(m_autosave->fileName(), doc);
+        saveSceneList(m_autosave->fileName(), m_render->sceneList());
     }
 }
 
@@ -497,9 +526,34 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene)
         KMessageBox::error(kapp->activeWindow(), i18n("Cannot write to file %1, scene list is corrupted.", path));
         return false;
     }
+
     QDomElement addedXml = sceneList.createElement("kdenlivedoc");
     mlt.appendChild(addedXml);
 
+    // check if project contains custom effects to embed them in project file
+    QDomNodeList effects = mlt.elementsByTagName("filter");
+    int maxEffects = effects.count();
+    kDebug() << "// FOUD " << maxEffects << " EFFECTS+++++++++++++++++++++";
+    QMap <QString, QString> effectIds;
+    for (int i = 0; i < maxEffects; i++) {
+        QDomNode m = effects.at(i);
+        QDomNodeList params = m.childNodes();
+        QString id;
+        QString tag;
+        for (int j = 0; j < params.count(); j++) {
+            QDomElement e = params.item(j).toElement();
+            if (e.attribute("name") == "kdenlive_id") {
+                id = e.firstChild().nodeValue();
+            }
+            if (e.attribute("name") == "tag") {
+                tag = e.firstChild().nodeValue();
+            }
+            if (!id.isEmpty() && !tag.isEmpty()) effectIds.insert(id, tag);
+        }
+    }
+    QDomDocument customeffects = initEffects::getUsedCustomEffects(effectIds);
+    addedXml.appendChild(sceneList.importNode(customeffects.documentElement(), true));
+
     QDomElement markers = sceneList.createElement("markers");
     addedXml.setAttribute("version", DOCUMENTVERSION);
     addedXml.setAttribute("kdenliveversion", VERSION);
@@ -515,6 +569,11 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene)
     docproperties.setAttribute("position", m_render->seekPosition().frames(m_fps));
     addedXml.appendChild(docproperties);
 
+    QDomElement docnotes = sceneList.createElement("documentnotes");
+    QDomText value = sceneList.createTextNode(m_notesWidget->toPlainText());
+    docnotes.appendChild(value);
+    addedXml.appendChild(docnotes);
+
     // Add profile info
     QDomElement profileinfo = sceneList.createElement("profileinfo");
     profileinfo.setAttribute("description", m_profile.description);
@@ -617,6 +676,8 @@ void KdenliveDoc::setProjectFolder(KUrl url)
     KStandardDirs::makeDir(url.path(KUrl::AddTrailingSlash) + "thumbs/");
     if (KMessageBox::questionYesNo(kapp->activeWindow(), i18n("You have changed the project folder. Do you want to copy the cached data from %1 to the new folder %2?").arg(m_projectFolder.path(), url.path())) == KMessageBox::Yes) moveProjectData(url);
     m_projectFolder = url;
+
+    updateProjectFolderPlacesEntry();
 }
 
 void KdenliveDoc::moveProjectData(KUrl url)
@@ -718,7 +779,7 @@ bool KdenliveDoc::setProfilePath(QString path)
     return (current_fps != m_fps);
 }
 
-double KdenliveDoc::dar()
+double KdenliveDoc::dar() const
 {
     return (double) m_profile.display_aspect_num / m_profile.display_aspect_den;
 }
@@ -753,16 +814,6 @@ void KdenliveDoc::checkProjectClips()
     m_clipManager->resetProducersList(m_render->producersList());
 }
 
-void KdenliveDoc::updatePreviewSettings()
-{
-    m_clipManager->updatePreviewSettings();
-    m_render->updatePreviewSettings();
-    QList <Mlt::Producer *> prods = m_render->producersList();
-    m_clipManager->resetProducersList(m_render->producersList());
-    qDeleteAll(prods);
-    prods.clear();
-}
-
 Render *KdenliveDoc::renderer()
 {
     return m_render;
@@ -1078,9 +1129,9 @@ void KdenliveDoc::slotCreateColorClip(const QString &name, const QString &color,
 }
 
 void KdenliveDoc::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)
+        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)
 {
     m_clipManager->slotAddSlideshowClipFile(name, path, count, duration, loop,
                                             crop, fade, luma_duration,
@@ -1107,7 +1158,7 @@ void KdenliveDoc::slotCreateTextTemplateClip(QString group, const QString &group
 {
     QString titlesFolder = projectFolder().path(KUrl::AddTrailingSlash) + "titles/";
     if (path.isEmpty()) {
-        path = KFileDialog::getOpenUrl(KUrl(titlesFolder), "*.kdenlivetitle", kapp->activeWindow(), i18n("Enter Template Path"));
+        path = KFileDialog::getOpenUrl(KUrl(titlesFolder), "application/x-kdenlivetitle", kapp->activeWindow(), i18n("Enter Template Path"));
     }
 
     if (path.isEmpty()) return;
@@ -1375,5 +1426,74 @@ QDomElement KdenliveDoc::getTrackEffect(int trackIndex, int effectIndex) const
     return list.at(effectIndex).cloneNode().toElement();
 }
 
+bool KdenliveDoc::saveCustomEffects(QDomNodeList customeffects)
+{
+    QDomElement e;
+    QStringList importedEffects;
+    int maxchild = customeffects.count();
+    for (int i = 0; i < maxchild; i++) {
+        e = customeffects.at(i).toElement();
+        QString id = e.attribute("id");
+        QString tag = e.attribute("tag");
+        if (!id.isEmpty()) {
+            // Check if effect exists or save it
+            if (MainWindow::customEffects.hasEffect(tag, id) == -1) {
+                QDomDocument doc;
+                doc.appendChild(doc.importNode(e, true));
+                QString path = KStandardDirs::locateLocal("appdata", "effects/", true);
+                path += id + ".xml";
+                if (!QFile::exists(path)) {
+                    importedEffects << id;
+                    QFile file(path);
+                    if (file.open(QFile::WriteOnly | QFile::Truncate)) {
+                        QTextStream out(&file);
+                        out << doc.toString();
+                    }
+                }
+            }
+        }
+    }
+    if (!importedEffects.isEmpty()) KMessageBox::informationList(kapp->activeWindow(), i18n("The following effects were imported from the project:"), importedEffects);
+    return (!importedEffects.isEmpty());
+}
+
+void KdenliveDoc::updateProjectFolderPlacesEntry()
+{
+    const QString file = KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
+    KBookmarkManager *bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces");
+    KBookmarkGroup root = bookmarkManager->root();
+    KBookmark bookmark = root.first();
+
+    QString kdenliveName = KGlobal::mainComponent().componentName();
+    KUrl documentLocation = m_projectFolder;
+
+    bool exists = false;
+
+    while (!bookmark.isNull()) {
+        // UDI not empty indicates a device
+        QString udi = bookmark.metaDataItem("UDI");
+        QString appName = bookmark.metaDataItem("OnlyInApp");
+
+        if (udi.isEmpty() && appName == kdenliveName && bookmark.text() == i18n("Project Folder")) {
+            if (bookmark.url() != documentLocation) {
+                bookmark.setUrl(documentLocation);
+                bookmarkManager->emitChanged(root);
+            }
+            exists = true;
+            break;
+        }
+
+        bookmark = root.next(bookmark);
+    }
+
+    // if entry does not exist yet (was not found), well, create it then
+    if (!exists) {
+        KBookmark newBookmark = root.addBookmark(i18n("Project Folder"), documentLocation, "folder-favorites");
+        // Make this user selectable ?
+        newBookmark.setMetaDataItem("OnlyInApp", kdenliveName);
+        bookmarkManager->emitChanged(root);
+    }
+}
+
 #include "kdenlivedoc.moc"