]> git.sesse.net Git - kdenlive/commitdiff
Fix keyframes corruption:
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 26 Jan 2010 00:24:00 +0000 (00:24 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 26 Jan 2010 00:24:00 +0000 (00:24 +0000)
http://www.kdenlive.org/mantis/view.php?id=1392

svn path=/trunk/kdenlive/; revision=4249

src/abstractclipitem.cpp
src/abstractclipitem.h
src/clipitem.cpp
src/clipitem.h
src/customtrackview.cpp

index c9da1c326921faa3216b82911e3ef658ffcbbdc9..39ed506de31e7d0e9780c113ae58c78f377a3022 100644 (file)
@@ -334,45 +334,41 @@ void AbstractClipItem::updateSelectedKeyFrame()
     update(br.x() + maxw *(m_selectedKeyframe - cropStart().frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12);
 }
 
-int AbstractClipItem::selectedKeyFramePos() const
+int AbstractClipItem::editedKeyFramePos() const
 {
     return m_editedKeyframe;
 }
 
-double AbstractClipItem::selectedKeyFrameValue() const
+double AbstractClipItem::editedKeyFrameValue() const
 {
     return m_keyframes.value(m_editedKeyframe);
 }
 
+int AbstractClipItem::selectedKeyFramePos() const
+{
+    return m_selectedKeyframe;
+}
+
+double AbstractClipItem::selectedKeyFrameValue() const
+{
+    return m_keyframes.value(m_selectedKeyframe);
+}
+
 void AbstractClipItem::updateKeyFramePos(const GenTime pos, const double value)
 {
-    if (!m_keyframes.contains(m_selectedKeyframe)) return;
+    if (!m_keyframes.contains(m_editedKeyframe)) return;
     int newpos = (int) pos.frames(m_fps);
     int start = cropStart().frames(m_fps);
     int end = (cropStart() + cropDuration()).frames(m_fps) - 1;
     newpos = qMax(newpos, start);
     newpos = qMin(newpos, end);
-    if (value < -50 && m_selectedKeyframe != start && m_selectedKeyframe != end) {
-        // remove kexframe if it is dragged outside
-        m_keyframes.remove(m_selectedKeyframe);
-        m_selectedKeyframe = -1;
-        update();
-        return;
-    }
-    if (value > 150 && m_selectedKeyframe != start && m_selectedKeyframe != end) {
-        // remove kexframe if it is dragged outside
-        m_keyframes.remove(m_selectedKeyframe);
-        m_selectedKeyframe = -1;
-        update();
-        return;
-    }
+
     double newval = qMax(value, 0.0);
     newval = qMin(newval, 100.0);
     newval = newval / m_keyframeFactor;
-    if (m_selectedKeyframe != newpos) m_keyframes.remove(m_selectedKeyframe);
+    if (m_editedKeyframe != newpos) m_keyframes.remove(m_editedKeyframe);
     m_keyframes[newpos] = (int) newval;
-    m_selectedKeyframe = newpos;
-
+    m_editedKeyframe = newpos;
     update();
 }
 
index fdc914381809617c23b94ae1f1b51eabc8858f1c..38efede3af277f09cb5b36449bf1eb210b41d1df 100644 (file)
@@ -48,8 +48,10 @@ public:
     void updateKeyFramePos(const GenTime pos, const double value);
     int addKeyFrame(const GenTime pos, const double value);
     bool hasKeyFrames() const;
+    int editedKeyFramePos() const;
     int selectedKeyFramePos() const;
     double selectedKeyFrameValue() const;
+    double editedKeyFrameValue() const;
     double keyFrameFactor() const;
     ItemInfo info() const;
     CustomTrackScene* projectScene();
@@ -77,7 +79,9 @@ public:
 protected:
     ItemInfo m_info;
 //    int m_track;
+    /** The position of the current keyframe when it has moved */
     int m_editedKeyframe;
+    /** The position of the current keyframe before it was moved */
     int m_selectedKeyframe;
     /*    GenTime m_cropStart;
         GenTime m_cropDuration;
index 7c6cac2b976c476bb55a54a4c29843b530ff78fe..c59c33bf59c69e5f0b7a995c17eb543eedcebe84 100644 (file)
@@ -1628,7 +1628,7 @@ bool ClipItem::isVideoOnly() const
     return m_videoOnly;
 }
 
-void ClipItem::insertKeyframe(QDomElement effect, const int pos, const int val)
+void ClipItem::insertKeyframe(QDomElement effect, int pos, int val)
 {
     if (effect.attribute("disabled") == "1") return;
     QDomNodeList params = effect.elementsByTagName("parameter");
@@ -1652,8 +1652,49 @@ void ClipItem::insertKeyframe(QDomElement effect, const int pos, const int val)
         }
         if (!added) newkfr.append(QString::number(pos) + ":" + QString::number(val));
         e.setAttribute("keyframes", newkfr.join(";"));
-        kDebug() << "insert kfr: " << newkfr.join(";");
     }
 }
 
+void ClipItem::movedKeyframe(QDomElement effect, int oldpos, int newpos, double value)
+{
+    if (effect.attribute("disabled") == "1") return;
+    QDomNodeList params = effect.elementsByTagName("parameter");
+    int start = cropStart().frames(m_fps);
+    int end = (cropStart() + cropDuration()).frames(m_fps) - 1;
+    for (int i = 0; i < params.count(); i++) {
+        QDomElement e = params.item(i).toElement();
+        QString kfr = e.attribute("keyframes");
+        const QStringList keyframes = kfr.split(';', QString::SkipEmptyParts);
+        QStringList newkfr;
+        foreach(const QString &str, keyframes) {
+            if (str.section(':', 0, 0).toInt() != oldpos) {
+                newkfr.append(str);
+            } else if (newpos != -1) {
+                newpos = qMax(newpos, start);
+                newpos = qMin(newpos, end);
+                if (i == 0) newkfr.append(QString::number(newpos) + ":" + QString::number(value));
+                else newkfr.append(QString::number(newpos) + ":" + str.section(':', 1, 1));
+            }
+        }
+        e.setAttribute("keyframes", newkfr.join(";"));
+    }
+
+    updateKeyframes(effect);
+    update();
+}
+
+void ClipItem::updateKeyframes(QDomElement effect)
+{
+    m_keyframes.clear();
+    // parse keyframes
+    QDomNodeList params = effect.elementsByTagName("parameter");
+    QDomElement e = params.item(0).toElement();
+    const QStringList keyframes = e.attribute("keyframes").split(';', QString::SkipEmptyParts);
+    foreach(const QString &str, keyframes) {
+        int pos = str.section(':', 0, 0).toInt();
+        double val = str.section(':', 1, 1).toDouble();
+        m_keyframes[pos] = val;
+    }
+    if (!m_keyframes.contains(m_selectedKeyframe)) m_selectedKeyframe = -1;
+}
 #include "clipitem.moc"
index d55c659d95dfeade51837e9b065da6350006dff9..e764dd648639ec72604dc1afbbc82d74ff5cb7d9 100644 (file)
@@ -116,7 +116,9 @@ public:
     bool isAudioOnly() const;
     /** Called when clip start is resized, adjust keyframes values */
     bool checkEffectsKeyframesPos(const int previous, const int current, bool fromStart);
-    void insertKeyframe(QDomElement effect, const int pos, const int val);
+    void insertKeyframe(QDomElement effect, int pos, int val);
+    void movedKeyframe(QDomElement effect, int oldpos, int newpos, double value);
+    void updateKeyframes(QDomElement effect);
 
 protected:
     //virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
index 07965765e02d8040a1f6f6f8c2f8150abad7e58e..2ac233668ccae4a2b285eeae1ae5d97868740a6d 100644 (file)
@@ -1196,11 +1196,14 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event)
             GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart();
             int val = m_dragItem->addKeyFrame(keyFramePos, mapToScene(event->pos()).toPoint().y());
             ClipItem * item = static_cast <ClipItem *>(m_dragItem);
-            QString previous = item->keyframes(item->selectedEffectIndex());
+            //QString previous = item->keyframes(item->selectedEffectIndex());
+            QDomElement oldEffect = item->selectedEffect().cloneNode().toElement();
             item->insertKeyframe(item->getEffectAt(item->selectedEffectIndex()), keyFramePos.frames(m_document->fps()), val);
             //item->updateKeyframeEffect();
-            QString next = item->keyframes(item->selectedEffectIndex());
-            EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false);
+            //QString next = item->keyframes(item->selectedEffectIndex());
+            QDomElement newEffect = item->selectedEffect().cloneNode().toElement();
+            EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), oldEffect, newEffect, item->selectedEffectIndex(), false);
+            //EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false);
             m_commandStack->push(command);
             updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
             emit clipItemSelected(item, item->selectedEffectIndex());
@@ -3364,10 +3367,26 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
     } else if (m_operationMode == KEYFRAME) {
         // update the MLT effect
         ClipItem * item = static_cast <ClipItem *>(m_dragItem);
-        QString previous = item->keyframes(item->selectedEffectIndex());
-        item->updateKeyframeEffect();
-        QString next = item->keyframes(item->selectedEffectIndex());
-        EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false);
+        QDomElement oldEffect = item->selectedEffect().cloneNode().toElement();
+
+        // check if we want to remove keyframe
+        double val = mapToScene(event->pos()).toPoint().y();
+        QRectF br = item->sceneBoundingRect();
+        double maxh = 100.0 / br.height();
+        val = (br.bottom() - val) * maxh;
+        int start = item->cropStart().frames(m_document->fps());
+        int end = (item->cropStart() + item->cropDuration()).frames(m_document->fps()) - 1;
+        if ((val < -50 || val > 150) && item->editedKeyFramePos() != start && item->editedKeyFramePos() != end) {
+            //delete keyframe
+            kDebug() << "// DELETE KFR: " << item->editedKeyFramePos();
+            item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), -1, 0);
+        } else item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), item->editedKeyFramePos(), item->editedKeyFrameValue());
+        QDomElement newEffect = item->selectedEffect().cloneNode().toElement();
+        //item->updateKeyframeEffect();
+        //QString next = item->keyframes(item->selectedEffectIndex());
+        //EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false);
+        EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), oldEffect, newEffect, item->selectedEffectIndex(), false);
+
         m_commandStack->push(command);
         updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex());
         emit clipItemSelected(item, item->selectedEffectIndex());