]> git.sesse.net Git - kdenlive/commitdiff
Fix broken keyframes when dropping an effect on another clip
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 8 Jun 2012 18:39:18 +0000 (20:39 +0200)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 8 Jun 2012 18:39:18 +0000 (20:39 +0200)
src/clipitem.cpp
src/clipitem.h
src/customtrackview.cpp
src/customtrackview.h
src/effectstack/effectstackview2.cpp
src/keyframeedit.cpp

index f672cd8af538ad020f0651ec9e06068f51c838e7..b663a6ed08eecf7220025facc679d4d8a5d235c0 100644 (file)
@@ -226,7 +226,7 @@ int ClipItem::selectedEffectIndex() const
     return m_selectedEffect;
 }
 
-void ClipItem::initEffect(QDomElement effect, int diff)
+void ClipItem::initEffect(QDomElement effect, int diff, int offset)
 {
     // the kdenlive_ix int is used to identify an effect in mlt's playlist, should
     // not be changed
@@ -258,9 +258,16 @@ void ClipItem::initEffect(QDomElement effect, int diff)
                 e.setAttribute("value", "1");
         }
 
-        if ((e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") && e.attribute("keyframes").isEmpty()) {
-            // Effect has a keyframe type parameter, we need to set the values
-            e.setAttribute("keyframes", QString::number(cropStart().frames(m_fps)) + ':' + e.attribute("default"));
+        if (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") {
+           if (e.attribute("keyframes").isEmpty()) {
+               // Effect has a keyframe type parameter, we need to set the values
+               e.setAttribute("keyframes", QString::number(cropStart().frames(m_fps)) + ':' + e.attribute("default"));
+           }
+           else if (offset != 0) {
+               // adjust keyframes to this clip
+               QString adjusted = adjustKeyframes(e.attribute("keyframes"), offset - cropStart().frames(m_fps));
+               e.setAttribute("keyframes", adjusted);
+           }
         }
     }
     if (effect.attribute("tag") == "volume" || effect.attribute("tag") == "brightness") {
@@ -320,6 +327,19 @@ void ClipItem::initEffect(QDomElement effect, int diff)
     }
 }
 
+const QString ClipItem::adjustKeyframes(QString keyframes, int offset)
+{
+    QStringList result;
+    // Simple keyframes
+    const QStringList list = keyframes.split(';', QString::SkipEmptyParts);
+    foreach(const QString &keyframe, list) {
+       int pos = keyframe.section(':', 0, 0).toInt() - offset;
+       QString newKey = QString::number(pos) + ":" + keyframe.section(':', 1);
+       result.append(newKey);
+    }
+    return result.join(";");
+}
+
 bool ClipItem::checkKeyFrames()
 {
     bool clipEffectsModified = false;
index 59d0ce6d7d0cdafe3c575668ae2d7856d8f61752..a2317f424baabb5c75136fb12bc4d17e3e669d34 100644 (file)
@@ -134,7 +134,8 @@ public:
     void updateKeyframeEffect();
     QDomElement selectedEffect();
     int selectedEffectIndex() const;
-    void initEffect(QDomElement effect, int diff = 0);
+    
+    void initEffect(QDomElement effect, int diff = 0, int offset = 0);
 
     /** @brief Gets all keyframes.
     * @param index Number of the effect
@@ -155,6 +156,8 @@ public:
     const ItemInfo speedIndependantInfo() const;
     int hasEffect(const QString &tag, const QString &id) const;
 
+    /** @brief Adjust keyframes to the new clip. */
+    const QString adjustKeyframes(QString keyframes, int offset);
     /** @brief Makes sure all keyframes are in the clip's cropped duration.
     * @return Whether or not changes were made */
     bool checkKeyFrames();
index 96f45d67bb340130a1c6be155dc12ce49a32bb0a..4c0214c9b55289d2b32bbc470bf1d33f7bbd9d84 100644 (file)
@@ -1741,6 +1741,7 @@ void CustomTrackView::slotAddGroupEffect(QDomElement effect, AbstractGroupItem *
     QList<QGraphicsItem *> itemList = group->childItems();
     QUndoCommand *effectCommand = new QUndoCommand();
     QString effectName;
+    int offset = effect.attribute("clipstart").toInt();
     QDomElement namenode = effect.firstChildElement("name");
     if (!namenode.isNull()) effectName = i18n(namenode.text().toUtf8().data());
     else effectName = i18n("effect");
@@ -1762,11 +1763,11 @@ void CustomTrackView::slotAddGroupEffect(QDomElement effect, AbstractGroupItem *
                            subeffect.setAttribute("kdenlive_info", effectInfo.toString());
                        }
                    }
-                   processEffect(item, subeffect, effectCommand);
+                   processEffect(item, subeffect, offset, effectCommand);
                }
            }
             else {
-               processEffect(item, effect, effectCommand);
+               processEffect(item, effect, offset, effectCommand);
            }
         }
     }
@@ -1786,6 +1787,8 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track)
     QList<QGraphicsItem *> itemList;
     QUndoCommand *effectCommand = new QUndoCommand();
     QString effectName;
+    
+    int offset = effect.attribute("clipstart").toInt();
     if (effect.tagName() == "effectgroup") {
        effectName = effect.attribute("name");
     } else {
@@ -1829,10 +1832,10 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track)
                            subeffect.setAttribute("kdenlive_info", effectInfo.toString());
                        }
                    }
-                   processEffect(item, subeffect, effectCommand);
+                   processEffect(item, subeffect, offset, effectCommand);
                }
            }
-            else processEffect(item, effect, effectCommand);
+            else processEffect(item, effect, offset, effectCommand);
         }
     }
     if (effectCommand->childCount() > 0) {
@@ -1856,7 +1859,7 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track)
     } else delete effectCommand;
 }
 
-void CustomTrackView::processEffect(ClipItem *item, QDomElement effect, QUndoCommand *effectCommand)
+void CustomTrackView::processEffect(ClipItem *item, QDomElement effect, int offset, QUndoCommand *effectCommand)
 {
     if (effect.attribute("type") == "audio") {
        // Don't add audio effects on video clips
@@ -1886,9 +1889,9 @@ void CustomTrackView::processEffect(ClipItem *item, QDomElement effect, QUndoCom
     }
 
     if (effect.attribute("id") == "freeze" && m_cursorPos > item->startPos().frames(m_document->fps()) && m_cursorPos < item->endPos().frames(m_document->fps())) {
-       item->initEffect(effect, m_cursorPos - item->startPos().frames(m_document->fps()));
+       item->initEffect(effect, m_cursorPos - item->startPos().frames(m_document->fps()), offset);
     } else {
-       item->initEffect(effect);
+       item->initEffect(effect, 0, offset);
     }
     new AddEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), effect, true, effectCommand);
 }
index 0df31b42816866a99f5f32ba566e4af022712d99..dafe942c1824d399a1ecf314491961da30f26fc0 100644 (file)
@@ -79,6 +79,7 @@ public:
     void addMarker(const QString &id, const GenTime &pos, const QString &comment);
     void setScale(double scaleFactor, double verticalScale);
     void deleteClip(const QString &clipId);
+    /** @brief Add effect to current clip */
     void slotAddEffect(QDomElement effect, GenTime pos, int track);
     void slotAddGroupEffect(QDomElement effect, AbstractGroupItem *group);
     void addEffect(int track, GenTime pos, QDomElement effect);
@@ -462,7 +463,7 @@ private:
     void adjustEffects(ClipItem *item, ItemInfo oldInfo, QUndoCommand *command);
     
     /** @brief Prepare an add clip command for an effect */
-    void processEffect(ClipItem *item, QDomElement effect, QUndoCommand *effectCommand);
+    void processEffect(ClipItem *item, QDomElement effect, int offset, QUndoCommand *effectCommand);
     
     /** @brief Get effect parameters ready for MLT*/
     void adjustEffectParameters(EffectsParameterList &parameters, QDomNodeList params, const QString &prefix = QString());
index dfec8f7950c0d8e960f6905f2c4d43de6a3e5cd8..a2d83f00a15ead7e501bd85a5639d51f69a3272e 100644 (file)
@@ -375,6 +375,8 @@ void EffectStackView2::startDrag()
     QPixmap pixmap;
     if (m_draggedEffect) {
         QDomElement effect = m_draggedEffect->effect().cloneNode().toElement();
+       // Keep clip crop start in case we want to paste effect 
+       effect.setAttribute("clipstart", m_clipref->cropStart().frames(KdenliveSettings::project_fps()));
         doc.appendChild(doc.importNode(effect, true));
         pixmap = QPixmap::grabWidget(m_draggedEffect->title);
     }
index 7e6801e11a70821e1039b3bea9d9858d88376d82..0bb08a2907dfc56acfc155f6498daba84f33aa2a 100644 (file)
@@ -242,6 +242,7 @@ void KeyframeEdit::slotGenerateParams(int row, int column)
 
         for (int col = 0; col < keyframe_list->horizontalHeader()->count(); col++) {
             item = keyframe_list->item(row, col);
+           if (!item) continue;
             int v = item->text().toInt();
             if (v >= m_params.at(col).attribute("max").toInt())
                 item->setText(m_params.at(col).attribute("max"));