From 1d7da2457cc52f8686ac0654b7fedb9a5bb21a8b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Fri, 8 Jun 2012 20:39:18 +0200 Subject: [PATCH] Fix broken keyframes when dropping an effect on another clip --- src/clipitem.cpp | 28 ++++++++++++++++++++++++---- src/clipitem.h | 5 ++++- src/customtrackview.cpp | 17 ++++++++++------- src/customtrackview.h | 3 ++- src/effectstack/effectstackview2.cpp | 2 ++ src/keyframeedit.cpp | 1 + 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/clipitem.cpp b/src/clipitem.cpp index f672cd8a..b663a6ed 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -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; diff --git a/src/clipitem.h b/src/clipitem.h index 59d0ce6d..a2317f42 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -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(); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 96f45d67..4c0214c9 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -1741,6 +1741,7 @@ void CustomTrackView::slotAddGroupEffect(QDomElement effect, AbstractGroupItem * QList 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 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); } diff --git a/src/customtrackview.h b/src/customtrackview.h index 0df31b42..dafe942c 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -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 ¶meters, QDomNodeList params, const QString &prefix = QString()); diff --git a/src/effectstack/effectstackview2.cpp b/src/effectstack/effectstackview2.cpp index dfec8f79..a2d83f00 100644 --- a/src/effectstack/effectstackview2.cpp +++ b/src/effectstack/effectstackview2.cpp @@ -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); } diff --git a/src/keyframeedit.cpp b/src/keyframeedit.cpp index 7e6801e1..0bb08a29 100644 --- a/src/keyframeedit.cpp +++ b/src/keyframeedit.cpp @@ -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")); -- 2.39.2