]> git.sesse.net Git - kdenlive/blobdiff - src/kdenlivedoc.cpp
Fix corruption when changing the project profile
[kdenlive] / src / kdenlivedoc.cpp
index ab33a5fb86dd23f3a97c0136df5c3dadddf78c99..f3591cc82af6695ac2d9b1afea26aa5e5760ec0e 100644 (file)
@@ -81,6 +81,7 @@ 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 {
@@ -121,6 +122,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);
                                 }
                             }
@@ -199,15 +201,17 @@ 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());
     }
 
+    KdenliveSettings::setCurrent_profile(profilePath());
+
     // Set the video profile (empty == default)
 
     // Make sure the project folder is usable
@@ -222,8 +226,8 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
     KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/");
 
     kDebug() << "Kdenlive document, init timecode: " << m_fps;
-    if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true);
-    else m_timecode.setFormat((int)(m_fps + 0.5));
+    if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(m_fps, true);
+    else m_timecode.setFormat(m_fps);
 
     //kDebug() << "// SETTING SCENE LIST:\n\n" << m_document.toString();
     connect(m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave()));
@@ -231,8 +235,11 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
 
 KdenliveDoc::~KdenliveDoc()
 {
+    m_autoSaveTimer->stop();
     delete m_commandStack;
+    kDebug() << "// DEL CLP MAN";
     delete m_clipManager;
+    kDebug() << "// DEL CLP MAN done";
     delete m_autoSaveTimer;
     if (m_autosave) {
         if (!m_autosave->fileName().isEmpty()) m_autosave->remove();
@@ -242,6 +249,7 @@ KdenliveDoc::~KdenliveDoc()
 
 int KdenliveDoc::setSceneList()
 {
+    m_render->resetProfile();
     if (m_render->setSceneList(m_document.toString(), m_documentProperties.value("position").toInt()) == -1) {
         // INVALID MLT Consumer, something is wrong
         return -1;
@@ -253,14 +261,8 @@ int KdenliveDoc::setSceneList()
     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;
@@ -273,6 +275,72 @@ 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.
+    QDomElement blk = doc.createElement("producer");
+    blk.setAttribute("in", 0);
+    blk.setAttribute("out", 500);
+    blk.setAttribute("id", "black");
+
+    QDomElement property = doc.createElement("property");
+    property.setAttribute("name", "mlt_type");
+    QDomText value = doc.createTextNode("producer");
+    property.appendChild(value);
+    blk.appendChild(property);
+
+    property = doc.createElement("property");
+    property.setAttribute("name", "aspect_ratio");
+    value = doc.createTextNode(QString::number(0.0));
+    property.appendChild(value);
+    blk.appendChild(property);
+
+    property = doc.createElement("property");
+    property.setAttribute("name", "length");
+    value = doc.createTextNode(QString::number(15000));
+    property.appendChild(value);
+    blk.appendChild(property);
+
+    property = doc.createElement("property");
+    property.setAttribute("name", "eof");
+    value = doc.createTextNode("pause");
+    property.appendChild(value);
+    blk.appendChild(property);
+
+    property = doc.createElement("property");
+    property.setAttribute("name", "resource");
+    value = doc.createTextNode("black");
+    property.appendChild(value);
+    blk.appendChild(property);
+
+    property = doc.createElement("property");
+    property.setAttribute("name", "mlt_service");
+    value = doc.createTextNode("colour");
+    property.appendChild(value);
+    blk.appendChild(property);
+
+    mlt.appendChild(blk);
+
+
     QDomElement tractor = doc.createElement("tractor");
     tractor.setAttribute("id", "maintractor");
     QDomElement multitrack = doc.createElement("multitrack");
@@ -280,9 +348,14 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a
     playlist.setAttribute("id", "black_track");
     mlt.appendChild(playlist);
 
+    QDomElement blank0 = doc.createElement("entry");
+    blank0.setAttribute("in", "0");
+    blank0.setAttribute("out", "0");
+    blank0.setAttribute("producer", "black");
+    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");
@@ -295,20 +368,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++) {
@@ -460,6 +529,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);
@@ -580,11 +650,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();
@@ -635,8 +706,9 @@ void KdenliveDoc::setProfilePath(QString path)
     m_width = m_profile.width;
     m_height = m_profile.height;
     kDebug() << "Kdenlive document, init timecode from path: " << path << ",  " << m_fps;
-    if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true);
-    else m_timecode.setFormat((int)(m_fps + 0.5));
+    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()
@@ -685,8 +757,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()
@@ -694,14 +768,14 @@ Render *KdenliveDoc::renderer()
     return m_render;
 }
 
-void KdenliveDoc::updateClip(const QString &id)
+void KdenliveDoc::updateClip(const QString id)
 {
     emit updateClipDisplay(id);
 }
 
 int KdenliveDoc::getFramePos(QString duration)
 {
-    return m_timecode.getFrameCount(duration, m_fps);
+    return m_timecode.getFrameCount(duration);
 }
 
 QString KdenliveDoc::producerName(const QString &id)
@@ -803,29 +877,6 @@ 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")) {
@@ -1037,13 +1088,9 @@ void KdenliveDoc::slotCreateTextClip(QString group, const QString &groupId, cons
 {
     QString titlesFolder = projectFolder().path(KUrl::AddTrailingSlash) + "titles/";
     KStandardDirs::makeDir(titlesFolder);
-    TitleWidget *dia_ui = new TitleWidget(templatePath, titlesFolder, m_render, kapp->activeWindow());
+    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(titleInfo.at(0), titleInfo.at(1), dia_ui->xml().toString(), group, groupId);
+        m_clipManager->slotAddTextClipFile(i18n("Title clip"), dia_ui->duration(), dia_ui->xml().toString(), group, groupId);
         setModified(true);
         emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
     }
@@ -1059,13 +1106,8 @@ void KdenliveDoc::slotCreateTextTemplateClip(QString group, const QString &group
 
     if (path.isEmpty()) return;
 
-    QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder(), true);
-
-    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);
+    //TODO: rewrite with new title system (just set resource)
+    m_clipManager->slotAddTextTemplateClip(i18n("Template title clip"), path, group, groupId);
     setModified(true);
     emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
 }
@@ -1117,6 +1159,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