]> git.sesse.net Git - kdenlive/blobdiff - src/kdenlivedoc.cpp
Add subclips (dragging a zone from clip monitor to project tree)
[kdenlive] / src / kdenlivedoc.cpp
index b109c9d72668ac1817315910a28e6bef7169dac2..4df0fcf2d2d23e8a0b93f7f115d334b320ea3704 100644 (file)
@@ -45,7 +45,7 @@
 
 #include <mlt++/Mlt.h>
 
-const double DOCUMENTVERSION = 0.84;
+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),
@@ -55,8 +55,6 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
         m_commandStack(new QUndoStack(undoGroup)),
         m_modified(false),
         m_projectFolder(projectFolder),
-        m_documentLoadingStep(0.0),
-        m_documentLoadingProgress(0),
         m_abortLoading(false)
 {
     m_clipManager = new ClipManager(this);
@@ -81,14 +79,17 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
             success = m_document.setContent(&file, false, &errorMsg);
             file.close();
             KIO::NetAccess::removeTempFile(tmpFile);
+
             if (!success) // It is corrupted
                 KMessageBox::error(parent, errorMsg);
             else {
+                parent->slotGotProgressInfo(i18n("Validating"), 0);
                 DocumentValidator validator(m_document);
                 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()), 100);
-                else {
+                if (!success) {
+                    // It is not a project file
+                    parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file", m_url.path()), 0);
+                } else {
                     /*
                      * Validate the file against the current version (upgrade
                      * and recover it if needed). It is NOT a passive operation
@@ -96,6 +97,7 @@ 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");
 
@@ -121,6 +123,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                                     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);
                                 }
                             }
@@ -128,29 +131,19 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                         }
                         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");
+                        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"));
                         }
 
-                        if (max > 0) {
-                            m_documentLoadingStep = 100.0 / (max + infomax + m_document.elementsByTagName("entry").count());
-                            parent->slotGotProgressInfo(i18n("Loading project clips"), (int) m_documentLoadingProgress);
-                        }
-
-
                         for (int i = 0; i < infomax && !m_abortLoading; i++) {
                             e = infoproducers.item(i).cloneNode().toElement();
-                            if (m_documentLoadingStep > 0) {
-                                m_documentLoadingProgress += m_documentLoadingStep;
-                                parent->slotGotProgressInfo(QString(), (int) m_documentLoadingProgress);
-                                //qApp->processEvents();
-                            }
                             QString prodId = e.attribute("id");
                             if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion") && !m_abortLoading) {
                                 e.setTagName("producer");
@@ -199,11 +192,11 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
                 }
             }
         }
-    } else setProfilePath(profileName);
+    }
 
     // Something went wrong, or a new file was requested: create a new project
     if (!success) {
-        setProfilePath(QString());
+        setProfilePath(profileName);
         m_url = KUrl();
         m_document = createEmptyDocument(tracks.x(), tracks.y());
     }
@@ -247,7 +240,7 @@ KdenliveDoc::~KdenliveDoc()
 
 int KdenliveDoc::setSceneList()
 {
-    m_render->resetProfile();
+    m_render->resetProfile(KdenliveSettings::current_profile());
     if (m_render->setSceneList(m_document.toString(), m_documentProperties.value("position").toInt()) == -1) {
         // INVALID MLT Consumer, something is wrong
         return -1;
@@ -255,18 +248,11 @@ int KdenliveDoc::setSceneList()
     m_documentProperties.remove("position");
     // m_document xml is now useless, clear it
     m_document.clear();
-    checkProjectClips();
     return 0;
 }
 
-QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int audiotracks)
+QDomDocument KdenliveDoc::createEmptyDocument(int videotracks, int audiotracks)
 {
-    // Creating new document
-    QDomDocument doc;
-    QDomElement mlt = doc.createElement("mlt");
-    doc.appendChild(mlt);
-
-
     TrackInfo videoTrack;
     videoTrack.type = VIDEOTRACK;
     videoTrack.isMute = false;
@@ -279,6 +265,25 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a
     audioTrack.isBlind = true;
     audioTrack.isLocked = false;
 
+    m_tracksList.clear();
+
+    for (int i = 0; i < audiotracks; i++) {
+        m_tracksList.append(audioTrack);
+    }
+    for (int i = 0; i < videotracks; i++) {
+        m_tracksList.append(videoTrack);
+    }
+    return createEmptyDocument(m_tracksList);
+}
+
+QDomDocument KdenliveDoc::createEmptyDocument(QList <TrackInfo> tracks)
+{
+    // Creating new document
+    QDomDocument doc;
+    QDomElement mlt = doc.createElement("mlt");
+    doc.appendChild(mlt);
+
+
     // Create black producer
     // For some unknown reason, we have to build the black producer here and not in renderer.cpp, otherwise
     // the composite transitions with the black track are corrupted.
@@ -340,7 +345,7 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a
     playlist.appendChild(blank0);
 
     // create playlists
-    int total = audiotracks + videotracks + 1;
+    int total = tracks.count() + 1;
 
     for (int i = 1; i < total; i++) {
         QDomElement playlist = doc.createElement("playlist");
@@ -353,20 +358,16 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a
     tractor.appendChild(track0);
 
     // create audio tracks
-    for (int i = 1; i < audiotracks + 1; i++) {
-        QDomElement track = doc.createElement("track");
-        track.setAttribute("producer", "playlist" + QString::number(i));
-        track.setAttribute("hide", "video");
-        tractor.appendChild(track);
-        m_tracksList.append(audioTrack);
-    }
-
-    // create video tracks
-    for (int i = audiotracks + 1; i < total; i++) {
+    for (int i = 1; i < total; i++) {
         QDomElement track = doc.createElement("track");
         track.setAttribute("producer", "playlist" + QString::number(i));
+        if (tracks.at(i - 1).type == AUDIOTRACK)
+            track.setAttribute("hide", "video");
+        else if (tracks.at(i - 1).isBlind)
+            track.setAttribute("hide", "video");
+        if (tracks.at(i - 1).isMute)
+            track.setAttribute("hide", "audio");
         tractor.appendChild(track);
-        m_tracksList.append(videoTrack);
     }
 
     for (int i = 2; i < total ; i++) {
@@ -518,6 +519,7 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene)
         trackinfo.setAttribute("mute", info.isMute);
         trackinfo.setAttribute("blind", info.isBlind);
         trackinfo.setAttribute("locked", info.isLocked);
+        trackinfo.setAttribute("trackname", info.trackName);
         tracksinfo.appendChild(trackinfo);
     }
     addedXml.appendChild(tracksinfo);
@@ -638,11 +640,12 @@ MltVideoProfile KdenliveDoc::mltProfile() const
     return m_profile;
 }
 
-void KdenliveDoc::setProfilePath(QString path)
+bool KdenliveDoc::setProfilePath(QString path)
 {
     if (path.isEmpty()) path = KdenliveSettings::default_profile();
     if (path.isEmpty()) path = "dv_pal";
     m_profile = ProfilesDialog::getVideoProfile(path);
+    bool current_fps = m_fps;
     if (m_profile.path.isEmpty()) {
         // Profile not found, use embedded profile
         QDomElement profileInfo = m_document.elementsByTagName("profileinfo").at(0).toElement();
@@ -695,6 +698,7 @@ void KdenliveDoc::setProfilePath(QString path)
     kDebug() << "Kdenlive document, init timecode from path: " << path << ",  " << m_fps;
     if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(m_fps, true);
     else m_timecode.setFormat(m_fps);
+    return (current_fps != m_fps);
 }
 
 double KdenliveDoc::dar()
@@ -707,12 +711,6 @@ void KdenliveDoc::setThumbsProgress(const QString &message, int progress)
     emit progressInfo(message, progress);
 }
 
-void KdenliveDoc::loadingProgressed()
-{
-    m_documentLoadingProgress += m_documentLoadingStep;
-    emit progressInfo(QString(), (int) m_documentLoadingProgress);
-}
-
 QUndoStack *KdenliveDoc::commandStack()
 {
     return m_commandStack;
@@ -743,8 +741,10 @@ 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()
@@ -752,7 +752,7 @@ Render *KdenliveDoc::renderer()
     return m_render;
 }
 
-void KdenliveDoc::updateClip(const QString &id)
+void KdenliveDoc::updateClip(const QString id)
 {
     emit updateClipDisplay(id);
 }
@@ -861,30 +861,7 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
         if (elem.attribute("type").toInt() == SLIDESHOW) {
             extension = KUrl(path).fileName();
             path = KUrl(path).directory();
-        } /*else if (elem.attribute("type").toInt() == TEXT && QFile::exists(path) == false) {
-            kDebug() << "// TITLE: " << elem.attribute("name") << " Preview file: " << elem.attribute("resource") << " DOES NOT EXIST";
-            QString titlename = elem.attribute("name");
-            QString titleresource;
-            if (titlename.isEmpty()) {
-                QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder());
-                titlename = titleInfo.at(0);
-                titleresource = titleInfo.at(1);
-                elem.setAttribute("name", titlename);
-                kDebug() << "// New title set to: " << titlename;
-            } else {
-                titleresource = TitleWidget::getFreeTitleInfo(projectFolder()).at(1);
-                //titleresource = TitleWidget::getTitleResourceFromName(projectFolder(), titlename);
-            }
-            TitleWidget *dia_ui = new TitleWidget(KUrl(), KUrl(titleresource).directory(), m_render, kapp->activeWindow());
-            QDomDocument doc;
-            doc.setContent(elem.attribute("xmldata"));
-            dia_ui->setXml(doc);
-            QImage pix = dia_ui->renderedPixmap();
-            pix.save(titleresource);
-            elem.setAttribute("resource", titleresource);
-            setNewClipResource(clipId, titleresource);
-            delete dia_ui;
-        }*/
+        }
 
         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();
@@ -940,12 +917,10 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
 
     if (createClipItem) {
         emit addProjectClip(clip);
-        qApp->processEvents();
-        m_render->getFileProperties(clip->toXML(), clip->getId(), true);
+        //qApp->processEvents();
     }
 }
 
-
 void KdenliveDoc::setNewClipResource(const QString &id, const QString &path)
 {
     QDomNodeList prods = m_document.elementsByTagName("producer");
@@ -1038,12 +1013,12 @@ void KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, QString clipId
     }
 }
 
-void KdenliveDoc::deleteProjectClip(QList <QString> ids)
+void KdenliveDoc::deleteProjectClip(QStringList ids)
 {
     for (int i = 0; i < ids.size(); ++i) {
         emit deleteTimelineClip(ids.at(i));
-        m_clipManager->slotDeleteClip(ids.at(i));
     }
+    m_clipManager->slotDeleteClips(ids);
     setModified(true);
 }
 
@@ -1055,7 +1030,7 @@ void KdenliveDoc::deleteClip(const QString &clipId)
 void KdenliveDoc::slotAddClipList(const KUrl::List urls, const QString group, const QString &groupId)
 {
     m_clipManager->slotAddClipList(urls, group, groupId);
-    emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
+    //emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
     setModified(true);
 }
 
@@ -1097,10 +1072,6 @@ void KdenliveDoc::slotCreateTextClip(QString group, const QString &groupId, cons
     KStandardDirs::makeDir(titlesFolder);
     TitleWidget *dia_ui = new TitleWidget(templatePath, m_timecode, titlesFolder, m_render, kapp->activeWindow());
     if (dia_ui->exec() == QDialog::Accepted) {
-        /*QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder());
-        QImage pix = dia_ui->renderedPixmap();
-        pix.save(titleInfo.at(1));*/
-        //dia_ui->saveTitle(path + ".kdenlivetitle");
         m_clipManager->slotAddTextClipFile(i18n("Title clip"), dia_ui->duration(), dia_ui->xml().toString(), group, groupId);
         setModified(true);
         emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
@@ -1117,15 +1088,9 @@ void KdenliveDoc::slotCreateTextTemplateClip(QString group, const QString &group
 
     if (path.isEmpty()) return;
 
-    QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder(), true);
-
     //TODO: rewrite with new title system (just set resource)
-    /*TitleWidget *dia_ui = new TitleWidget(path, titlesFolder, m_render, kapp->activeWindow());
-    QImage pix = dia_ui->renderedPixmap();
-    pix.save(titleInfo.at(1));
-    delete dia_ui;
-    m_clipManager->slotAddTextTemplateClip(titleInfo.at(0), titleInfo.at(1), path, group, groupId);
-    setModified(true);*/
+    m_clipManager->slotAddTextTemplateClip(i18n("Template title clip"), path, group, groupId);
+    setModified(true);
     emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
 }
 
@@ -1176,6 +1141,7 @@ void KdenliveDoc::setTrackType(int ix, TrackInfo type)
     m_tracksList[ix].isMute = type.isMute;
     m_tracksList[ix].isBlind = type.isBlind;
     m_tracksList[ix].isLocked = type.isLocked;
+    m_tracksList[ix].trackName = type.trackName;
 }
 
 const QList <TrackInfo> KdenliveDoc::tracksList() const