]> git.sesse.net Git - kdenlive/commitdiff
Fix corruption when changing the project profile
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 11 Sep 2009 00:37:09 +0000 (00:37 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 11 Sep 2009 00:37:09 +0000 (00:37 +0000)
svn path=/trunk/kdenlive/; revision=3886

13 files changed:
src/abstractclipitem.cpp
src/abstractclipitem.h
src/customtrackview.cpp
src/customtrackview.h
src/documentchecker.cpp
src/guide.cpp
src/guide.h
src/kdenlivedoc.cpp
src/kdenlivedoc.h
src/mainwindow.cpp
src/renderer.cpp
src/renderer.h
src/trackview.cpp

index 90b0c8fcfaec532e5a3cbbd4920b35399c60056f..90641d762f738791ddd722b3f65b555c2c1d1f60 100644 (file)
@@ -185,6 +185,13 @@ double AbstractClipItem::fps() const
     return m_fps;
 }
 
+void AbstractClipItem::updateFps(double fps)
+{
+    m_fps = fps;
+    setPos((qreal) startPos().frames(m_fps), pos().y());
+    updateRectGeometry();
+}
+
 GenTime AbstractClipItem::maxDuration() const
 {
     return m_maxDuration;
index 47a66631ccefcc4de023fc3a55d0ab2fd9aa616e..226e20754f2efe5c2f631e469f0e503aabd8b282 100644 (file)
@@ -57,6 +57,7 @@ public:
     virtual void resizeStart(int posx, double speed = 1.0);
     virtual void resizeEnd(int posx, double speed = 1.0);
     virtual double fps() const;
+    virtual void updateFps(double fps);
     virtual GenTime maxDuration() const;
     virtual void setCropStart(GenTime pos);
 
index fa5dfc466bbd729f84a730e85f5a5629a62f17ae..e2a2a758ae06e42f783c5bbe15a7d9da829be1fc 100644 (file)
@@ -1000,13 +1000,11 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup)
     }
     QList<QGraphicsItem *> selection = m_scene->selectedItems();
     if (selection.isEmpty()) return;
-    QPointF top = selection.at(0)->sceneBoundingRect().topLeft();
+    QRectF rectUnion;
     // Find top left position of selection
-    for (int i = 1; i < selection.count(); i++) {
+    for (int i = 0; i < selection.count(); i++) {
         if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET) {
-            QPointF currenttop = selection.at(i)->sceneBoundingRect().topLeft();
-            if (currenttop.x() < top.x()) top.setX(currenttop.x());
-            if (currenttop.y() < top.y()) top.setY(currenttop.y());
+            rectUnion = rectUnion.united(selection.at(i)->sceneBoundingRect());
         }
     }
 
@@ -1015,8 +1013,8 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup)
         KdenliveSettings::setSnaptopoints(false);
         if (createNewGroup) {
             AbstractGroupItem *newGroup = m_document->clipManager()->createGroup();
-            newGroup->translate(-top.x(), -top.y() + 1);
-            newGroup->setPos(top.x(), top.y() - 1);
+            newGroup->translate(-rectUnion.left(), -rectUnion.top() + 1);
+            newGroup->setPos(rectUnion.left(), rectUnion.top() - 1);
             scene()->addItem(newGroup);
 
             // CHeck if we are trying to include a group in a group
@@ -1045,8 +1043,8 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup)
             KdenliveSettings::setSnaptopoints(snap);
         } else {
             m_selectionGroup = new AbstractGroupItem(m_document->fps());
-            m_selectionGroup->translate(-top.x(), -top.y() + 1);
-            m_selectionGroup->setPos(top.x(), top.y() - 1);
+            m_selectionGroup->translate(-rectUnion.left(), -rectUnion.top() + 1);
+            m_selectionGroup->setPos(rectUnion.left(), rectUnion.top() - 1);
             scene()->addItem(m_selectionGroup);
             for (int i = 0; i < selection.count(); i++) {
                 if (selection.at(i)->parentItem() == NULL && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) {
@@ -3413,8 +3411,10 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
         ClipItem *clip = getClipItemAt(startClip.at(i).startPos, startClip.at(i).track);
         if (clip) {
             clip->setItemLocked(false);
-            if (clip->parentItem()) clip->parentItem()->setSelected(true);
-            else clip->setSelected(true);
+            if (clip->parentItem()) {
+                clip->parentItem()->setSelected(true);
+            }
+            clip->setSelected(true);
             m_document->renderer()->mltRemoveClip(m_document->tracksCount() - startClip.at(i).track, startClip.at(i).startPos);
         } else kDebug() << "//MISSING CLIP AT: " << startClip.at(i).startPos.frames(25);
     }
@@ -3426,8 +3426,9 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
         Transition *tr = getTransitionItemAt(startTransition.at(i).startPos, startTransition.at(i).track);
         if (tr) {
             tr->setItemLocked(false);
-            if (tr->parentItem()) tr->parentItem()->setSelected(true);
-            else tr->setSelected(true);
+            if (tr->parentItem()) {
+                tr->parentItem()->setSelected(true);
+            } else tr->setSelected(true);
             m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_document->tracksCount() - startTransition.at(i).track, startTransition.at(i).startPos, startTransition.at(i).endPos, tr->toXML());
         } else kDebug() << "//MISSING TRANSITION AT: " << startTransition.at(i).startPos.frames(25);
     }
@@ -3445,6 +3446,12 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
         for (int i = 0; i < max; i++) {
             if (children.at(i)->type() == GROUPWIDGET) {
                 children += children.at(i)->childItems();
+                AbstractGroupItem *grp = static_cast<AbstractGroupItem *>(children.at(i));
+                //grp->moveBy(offset.frames(m_document->fps()), trackOffset *(qreal) m_tracksHeight);
+                /*m_document->clipManager()->removeGroup(grp);
+                m_scene->destroyItemGroup(grp);*/
+                children.removeAll(children.at(i));
+                i--;
             }
         }
 
@@ -3860,7 +3867,7 @@ bool CustomTrackView::addGuide(const GenTime pos, const QString &comment)
             return false;
         }
     }
-    Guide *g = new Guide(this, pos, comment, m_document->fps(), m_tracksHeight * m_document->tracksCount());
+    Guide *g = new Guide(this, pos, comment, m_tracksHeight * m_document->tracksCount());
     scene()->addItem(g);
     m_guides.append(g);
     qSort(m_guides.begin(), m_guides.end(), sortGuidesList);
@@ -4931,4 +4938,54 @@ void CustomTrackView::reloadTransitionLumas()
     emit transitionItemSelected(NULL);
 }
 
-#include "customtrackview.moc"
+double CustomTrackView::fps() const
+{
+    return m_document->fps();
+}
+
+void CustomTrackView::updateProjectFps()
+{
+    // update all clips to the new fps
+    resetSelectionGroup();
+    scene()->clearSelection();
+    m_dragItem = NULL;
+    QList<QGraphicsItem *> itemList = items();
+    for (int i = 0; i < itemList.count(); i++) {
+        // remove all items and re-add them one by one
+        if (itemList.at(i) != m_cursorLine && itemList.at(i)->parentItem() == NULL) m_scene->removeItem(itemList.at(i));
+    }
+    for (int i = 0; i < itemList.count(); i++) {
+        if (itemList.at(i)->parentItem() == 0 && (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET)) {
+            AbstractClipItem *clip = static_cast <AbstractClipItem *>(itemList.at(i));
+            clip->updateFps(m_document->fps());
+            m_scene->addItem(clip);
+        } else if (itemList.at(i)->type() == GROUPWIDGET) {
+            AbstractGroupItem *grp = static_cast <AbstractGroupItem *>(itemList.at(i));
+            QList<QGraphicsItem *> children = grp->childItems();
+            for (int j = 0; j < children.count(); j++) {
+                if (children.at(j)->type() == AVWIDGET || children.at(j)->type() == TRANSITIONWIDGET) {
+                    AbstractClipItem *clip = static_cast <AbstractClipItem *>(children.at(j));
+                    clip->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+                    clip->updateFps(m_document->fps());
+                }
+            }
+            m_document->clipManager()->removeGroup(grp);
+            m_scene->addItem(grp);
+            scene()->destroyItemGroup(grp);
+            for (int j = 0; j < children.count(); j++) {
+                if (children.at(j)->type() == AVWIDGET || children.at(j)->type() == TRANSITIONWIDGET) {
+                    //children.at(j)->setParentItem(0);
+                    children.at(j)->setSelected(true);
+                }
+            }
+            groupSelectedItems(true, true);
+        } else if (itemList.at(i)->type() == GUIDEITEM) {
+            Guide *g = static_cast<Guide *>(itemList.at(i));
+            g->updatePos();
+            m_scene->addItem(g);
+        }
+    }
+    viewport()->update();
+}
+
+#include "customtrackview.moc"
\ No newline at end of file
index 70ef447cb808369955681fa9b1b2a69dec9f36ed..fecbcfaa1035bc8a51095bcb96cb5ba3b19745ba 100644 (file)
@@ -122,6 +122,8 @@ public:
     void doChangeClipType(const GenTime &pos, int track, bool videoOnly, bool audioOnly);
     int hasGuide(int pos, int offset);
     void reloadTransitionLumas();
+    void updateProjectFps();
+    double fps() const;
 
 public slots:
     void setCursorPos(int pos, bool seek = true);
index 84bf683206768b295c860134883d7791996ecc11..ef8e5bb54a590d95c2370ea5343730cf1cc6fbac 100644 (file)
@@ -155,8 +155,7 @@ void DocumentChecker::slotSearchClips()
                 child->setIcon(0, KIcon("dialog-ok"));
                 child->setData(0, statusRole, CLIPOK);
             }
-        }
-        else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
+        } else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
             QString fileName = searchLuma(child->data(0, idRole).toString());
             if (!fileName.isEmpty()) {
                 child->setText(1, fileName);
@@ -248,7 +247,7 @@ void DocumentChecker::accept()
 
     // prepare transitions
     QDomNodeList trans = m_doc.elementsByTagName("transition");
-    
+
     QTreeWidgetItem *child = treeWidget->topLevelItem(ix);
     while (child) {
         if (child->data(0, statusRole).toInt() == CLIPOK) {
@@ -290,10 +289,10 @@ void DocumentChecker::accept()
         } else if (child->data(0, statusRole).toInt() == LUMAOK) {
             for (int i = 0; i < trans.count(); i++) {
                 QString luma = getProperty(trans.at(i).toElement(), "luma");
-                kDebug()<< "luma: "<<luma;
+                kDebug() << "luma: " << luma;
                 if (!luma.isEmpty() && luma == child->data(0, idRole).toString()) {
                     setProperty(trans.at(i).toElement(), "luma", child->text(1));
-                    kDebug()<< "replace with; "<<child->text(1);
+                    kDebug() << "replace with; " << child->text(1);
                 }
             }
         } else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
@@ -318,8 +317,7 @@ void DocumentChecker::slotPlaceholders()
         if (child->data(0, statusRole).toInt() == CLIPMISSING) {
             child->setData(0, statusRole, CLIPPLACEHOLDER);
             child->setIcon(0, KIcon("dialog-ok"));
-        }
-        else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
+        } else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
             child->setData(0, statusRole, LUMAPLACEHOLDER);
             child->setIcon(0, KIcon("dialog-ok"));
         }
index 5f289ed18f731b1a5901fe679407ff12be37e6ac..93d9d7973b05b5d7c849250f16badc88695bf27d 100644 (file)
 #include <QBrush>
 #include <QStyleOptionGraphicsItem>
 
-Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height) :
+Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double height) :
         QGraphicsLineItem(),
         m_position(pos),
         m_label(label),
-        m_fps(fps),
         m_view(view),
         m_pen(QPen())
 {
     setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIgnoresTransformations);
     setToolTip(label);
     setLine(0, 0, 0, height);
-    setPos(m_position.frames(m_fps), 0);
+    setPos(m_position.frames(m_view->fps()), 0);
     m_pen.setWidthF(0);
     m_pen.setColor(QColor(0, 0, 200, 180));
     //m_pen.setCosmetic(true);
@@ -68,7 +67,7 @@ CommentedTime Guide::info() const
 void Guide::updateGuide(const GenTime newPos, const QString &comment)
 {
     m_position = newPos;
-    setPos(m_position.frames(m_fps), 0);
+    setPos(m_position.frames(m_view->fps()), 0);
     if (!comment.isEmpty()) {
         m_label = comment;
         setToolTip(m_label);
@@ -78,6 +77,11 @@ void Guide::updateGuide(const GenTime newPos, const QString &comment)
     }
 }
 
+void Guide::updatePos()
+{
+    setPos(m_position.frames(m_view->fps()), 0);
+}
+
 //virtual
 int Guide::type() const
 {
index 150f83d67af1c67bc4924638c91eb04bdbfaa68a..1265d135ff2ec6fa16799834f200e70a56b79657 100644 (file)
@@ -34,11 +34,12 @@ class Guide : public QGraphicsLineItem
 {
 
 public:
-    Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height);
+    Guide(CustomTrackView *view, GenTime pos, QString label, double height);
     GenTime position() const;
     void updateGuide(const GenTime newPos, const QString &comment = QString());
     QString label() const;
     CommentedTime info() const;
+    void updatePos();
     virtual int type() const;
     virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w);
     virtual QRectF boundingRect() const;
@@ -52,7 +53,6 @@ protected:
 private:
     GenTime m_position;
     QString m_label;
-    double m_fps;
     CustomTrackView *m_view;
     int m_width;
     QPen m_pen;
index 6e065ea589eddff505440fbdbe0acd9591403173..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 {
@@ -260,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;
@@ -280,6 +275,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.
@@ -341,7 +355,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");
@@ -354,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++) {
@@ -640,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();
@@ -697,6 +708,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()
index 217d4bc2f6334e5f2ce4b06b50c6950673ebc4ed..6f6bfd3c653942bd10c6d1feb9ed4d456b9fae27 100644 (file)
@@ -81,7 +81,8 @@ Q_OBJECT public:
     MltVideoProfile mltProfile() const;
     const QString description() const;
     void setUrl(KUrl url);
-    void setProfilePath(QString path);
+    /** update project profile, returns true if fps was changed */
+    bool setProfilePath(QString path);
     const QString getFreeClipId();
     /** does the document need saving */
     bool isModified() const;
@@ -139,13 +140,12 @@ private:
     QMap <QString, QString> m_documentProperties;
 
     QList <TrackInfo> m_tracksList;
-
-    QDomDocument createEmptyDocument(const int videotracks, const int audiotracks);
-
     void setNewClipResource(const QString &id, const QString &path);
     QString searchFileRecursively(const QDir &dir, const QString &matchSize, const QString &matchHash) const;
     void moveProjectData(KUrl url);
     bool checkDocumentClips(QDomNodeList infoproducers);
+    QDomDocument createEmptyDocument(int videotracks, int audiotracks);
+    QDomDocument createEmptyDocument(QList <TrackInfo> tracks);
 
 public slots:
     void slotCreateColorClip(const QString &name, const QString &color, const QString &duration, QString group, const QString &groupId);
index 66bbb10ae921deaea9ac52d18b1b272917936fc0..005ed0e61a625f444038803c6a7f692c11c5d21d 100644 (file)
@@ -684,7 +684,7 @@ void MainWindow::setupActions()
     m_statusProgressBar->setMaximumWidth(150);
     m_statusProgressBar->setVisible(false);
 
-       KToolBar *toolbar = new KToolBar("statusToolBar", this, Qt::BottomToolBarArea);
+    KToolBar *toolbar = new KToolBar("statusToolBar", this, Qt::BottomToolBarArea);
     toolbar->setMovable(false);
     m_toolGroup = new QActionGroup(this);
     statusBar()->setStyleSheet(QString("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize()));
@@ -1627,7 +1627,7 @@ void MainWindow::slotEditProjectSettings()
             m_effectStack->slotClipItemSelected(NULL, 0);
             m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false);
             m_clipMonitor->slotSetXml(NULL, 0);
-            m_activeDocument->setProfilePath(profile);
+            bool updateFps = m_activeDocument->setProfilePath(profile);
             KdenliveSettings::setCurrent_profile(profile);
             KdenliveSettings::setProject_fps(m_activeDocument->fps());
             setCaption(m_activeDocument->description(), m_activeDocument->isModified());
@@ -1641,7 +1641,7 @@ void MainWindow::slotEditProjectSettings()
             m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
             //m_activeDocument->clipManager()->resetProducersList(m_projectMonitor->render->producersList());
             if (dar != m_activeDocument->dar()) m_projectList->reloadClipThumbnails();
-            m_activeTimeline->updateProjectFps();
+            if (updateFps) m_activeTimeline->updateProjectFps();
 
             // We need to desactivate & reactivate monitors to get a refresh
             //m_monitorManager->switchMonitors();
index db9823275092bd1411dab8c2a58c796b6b440919..7d535b855d0589d523abe500117e9b03775593b4 100644 (file)
@@ -116,12 +116,15 @@ void Render::closeMlt()
             Mlt::Tractor tractor(service);
             Mlt::Field *field = tractor.field();
             mlt_service nextservice = mlt_service_get_producer(service.get_service());
+            mlt_service nextservicetodisconnect;
             mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
             QString mlt_type = mlt_properties_get(properties, "mlt_type");
             QString resource = mlt_properties_get(properties, "mlt_service");
             // Delete all transitions
             while (mlt_type == "transition") {
-                mlt_field_disconnect_service(field->get_field(), nextservice);
+                nextservicetodisconnect = nextservice;
+                nextservice = mlt_service_producer(nextservice);
+                mlt_field_disconnect_service(field->get_field(), nextservicetodisconnect);
                 nextservice = mlt_service_producer(nextservice);
                 if (nextservice == NULL) break;
                 properties = MLT_SERVICE_PROPERTIES(nextservice);
@@ -244,7 +247,7 @@ int Render::resetProfile()
     m_mltConsumer = NULL;
     QString scene = sceneList();
     int pos = 0;
-
+    double current_fps = m_mltProfile->fps();
     delete m_blackClip;
     m_blackClip = NULL;
 
@@ -268,7 +271,11 @@ int Render::resetProfile()
     m_mltProducer = NULL;
 
     buildConsumer();
-
+    double new_fps = m_mltProfile->fps();
+    if (current_fps != new_fps) {
+        // fps changed, we must update the scenelist positions
+        scene = updateSceneListFps(current_fps, new_fps, scene);
+    }
     //kDebug() << "//RESET WITHSCENE: " << scene;
     setSceneList(scene, pos);
 
@@ -927,13 +934,15 @@ int Render::setSceneList(QString playlist, int position)
             Mlt::Tractor tractor(service);
             Mlt::Field *field = tractor.field();
             mlt_service nextservice = mlt_service_get_producer(service.get_service());
+            mlt_service nextservicetodisconnect;
             mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
             QString mlt_type = mlt_properties_get(properties, "mlt_type");
             QString resource = mlt_properties_get(properties, "mlt_service");
             // Delete all transitions
             while (mlt_type == "transition") {
-                mlt_field_disconnect_service(field->get_field(), nextservice);
+                nextservicetodisconnect = nextservice;
                 nextservice = mlt_service_producer(nextservice);
+                mlt_field_disconnect_service(field->get_field(), nextservicetodisconnect);
                 if (nextservice == NULL) break;
                 properties = MLT_SERVICE_PROPERTIES(nextservice);
                 mlt_type = mlt_properties_get(properties, "mlt_type");
@@ -3351,5 +3360,100 @@ void Render::updatePreviewSettings()
     setSceneList(scene, pos);
 }
 
+
+QString Render::updateSceneListFps(double current_fps, double new_fps, QString scene)
+{
+    // Update all frame positions to the new fps value
+    //WARNING: there are probably some effects or other that hold a frame value
+    // as parameter and will also need to be updated here!
+    QDomDocument doc;
+    doc.setContent(scene);
+
+    double factor = new_fps / current_fps;
+    QDomNodeList producers = doc.elementsByTagName("producer");
+    for (int i = 0; i < producers.count(); i++) {
+        QDomElement prod = producers.at(i).toElement();
+        prod.removeAttribute("in");
+        prod.removeAttribute("out");
+
+        QDomNodeList props = prod.childNodes();
+        for (int j = 0; j < props.count(); j++) {
+            QDomElement param =  props.at(j).toElement();
+            QString paramName = param.attribute("name");
+            if (paramName.startsWith("meta.") || paramName == "length") {
+                prod.removeChild(props.at(j));
+                j--;
+            }
+        }
+    }
+
+    QDomNodeList entries = doc.elementsByTagName("entry");
+    for (int i = 0; i < entries.count(); i++) {
+        QDomElement entry = entries.at(i).toElement();
+        int in = entry.attribute("in").toInt();
+        int out = entry.attribute("out").toInt();
+        in = factor * in + 0.5;
+        out = factor * out + 0.5;
+        entry.setAttribute("in", in);
+        entry.setAttribute("out", out);
+    }
+
+    QDomNodeList blanks = doc.elementsByTagName("blank");
+    for (int i = 0; i < blanks.count(); i++) {
+        QDomElement blank = blanks.at(i).toElement();
+        int length = blank.attribute("length").toInt();
+        length = factor * length + 0.5;
+        blank.setAttribute("length", QString::number(length));
+    }
+
+    QDomNodeList filters = doc.elementsByTagName("filter");
+    for (int i = 0; i < filters.count(); i++) {
+        QDomElement filter = filters.at(i).toElement();
+        int in = filter.attribute("in").toInt();
+        int out = filter.attribute("out").toInt();
+        in = factor * in + 0.5;
+        out = factor * out + 0.5;
+        filter.setAttribute("in", in);
+        filter.setAttribute("out", out);
+    }
+
+    QDomNodeList transitions = doc.elementsByTagName("transition");
+    for (int i = 0; i < transitions.count(); i++) {
+        QDomElement transition = transitions.at(i).toElement();
+        int in = transition.attribute("in").toInt();
+        int out = transition.attribute("out").toInt();
+        in = factor * in + 0.5;
+        out = factor * out + 0.5;
+        transition.setAttribute("in", in);
+        transition.setAttribute("out", out);
+        QDomNodeList props = transition.childNodes();
+        for (int j = 0; j < props.count(); j++) {
+            QDomElement param =  props.at(j).toElement();
+            QString paramName = param.attribute("name");
+            if (paramName == "geometry") {
+                QString geom = param.firstChild().nodeValue();
+                QStringList keys = geom.split(';');
+                QStringList newKeys;
+                for (int k = 0; k < keys.size(); ++k) {
+                    if (keys.at(k).contains('=')) {
+                        int pos = keys.at(k).section('=', 0, 0).toInt();
+                        pos = factor * pos + 0.5;
+                        newKeys.append(QString::number(pos) + '=' + keys.at(k).section('=', 1));
+                    } else newKeys.append(keys.at(k));
+                }
+                param.firstChild().setNodeValue(newKeys.join(";"));
+            }
+        }
+    }
+    QDomElement tractor = doc.elementsByTagName("tractor").at(0).toElement();
+    int out = tractor.attribute("out").toInt();
+    out = factor * out + 0.5;
+    tractor.setAttribute("out", out);
+    emit durationChanged(out);
+
+    kDebug() << "///////////////////////////// " << out << " \n" << doc.toString() << "\n-------------------------";
+    return doc.toString();
+}
+
 #include "renderer.moc"
 
index 74011cb25802e6b1948c6024bf84274950abdc6b..406e251288af080e6373bcabc989fddc65dcf4ae 100644 (file)
@@ -209,6 +209,7 @@ Q_OBJECT public:
     const QList <Mlt::Producer *> producersList();
     void updatePreviewSettings();
     void setDropFrames(bool show);
+    QString updateSceneListFps(double current_fps, double new_fps, QString scene);
 #ifdef Q_WS_MAC
     void showFrame(Mlt::Frame&);
 #endif
index 5bdf6996a90b9cff30407923a4c71cbf8d14e19f..e790a4c1c0e3bf01690381651250980be004c682 100644 (file)
@@ -847,6 +847,7 @@ void TrackView::slotVerticalZoomUp()
 void TrackView::updateProjectFps()
 {
     m_ruler->updateProjectFps(m_doc->timecode());
+    m_trackview->updateProjectFps();
 }
 
 void TrackView::slotRenameTrack(int ix)