[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdenlive/Applications/16.12] /: * Fix crash on resize clip after removing keyframe effect
From:       Jean-Baptiste Mardelle <jb () kdenlive ! org>
Date:       2016-12-07 22:48:02
Message-ID: E1cEl0M-0007bI-LL () code ! kde ! org
[Download RAW message or body]

Git commit 406b7674ae24a0a2cba1e2aff6feeebaaa04d6c8 by Jean-Baptiste Mardelle.
Committed on 07/12/2016 at 22:47.
Pushed by mardelle into branch 'Applications/16.12'.

* Fix crash on resize clip after removing keyframe effect
* Do not display Transform rotation keyframes in timeline
* Fix Keyframes for animated rect (transform) not correctly displayed
* Fix Geometry keyframes (Position and Zoom)

M  +1    -1    data/effects/qtblend.xml
M  +2    -2    src/effectstack/widgets/animationwidget.cpp
M  +2    -1    src/mltcontroller/effectscontroller.cpp
M  +1    -1    src/timeline/abstractclipitem.cpp
M  +38   -17   src/timeline/keyframeview.cpp
M  +1    -0    src/timeline/keyframeview.h

https://commits.kde.org/kdenlive/406b7674ae24a0a2cba1e2aff6feeebaaa04d6c8

diff --git a/data/effects/qtblend.xml b/data/effects/qtblend.xml
index 4cf2e733c..829ecb239 100644
--- a/data/effects/qtblend.xml
+++ b/data/effects/qtblend.xml
@@ -6,7 +6,7 @@
 	<parameter type="animatedrect" name="rect" default="0 0 %width %height 1">
 		<name>Rectangle</name>
 	</parameter>
-        <parameter type="animated" name="rotation" max="360" min="-360" default="0">
+        <parameter type="animated" name="rotation" max="360" min="-360" default="0" \
notintimeline="1">  <name>Rotation</name>
         </parameter>
         <parameter type="list" name="compositing" default="0" \
                paramlist="0;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;6;8">
                
diff --git a/src/effectstack/widgets/animationwidget.cpp \
b/src/effectstack/widgets/animationwidget.cpp index 9f52e0d5e..f290c6561 100644
--- a/src/effectstack/widgets/animationwidget.cpp
+++ b/src/effectstack/widgets/animationwidget.cpp
@@ -717,7 +717,7 @@ void AnimationWidget::buildSliderWidget(const QString &paramTag, \
const QDomEleme  doubleparam->factor = factor;
     connect(doubleparam, SIGNAL(valueChanged(double)), this, \
SLOT(slotAdjustKeyframeValue(double)));  layout()->addWidget(doubleparam);
-    if (!e.hasAttribute(QStringLiteral("intimeline")) || \
e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) { +    if \
((!e.hasAttribute(QStringLiteral("intimeline")) || \
e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) && \
!e.hasAttribute(QStringLiteral("notintimeline"))) {  \
doubleparam->setInTimelineProperty(true);  doubleparam->setChecked(true);
         m_inTimeline = paramTag;
@@ -888,7 +888,7 @@ void AnimationWidget::slotAdjustRectKeyframeValue()
 {
     m_animController = \
m_animProperties.get_animation(m_rectParameter.toUtf8().constData());  m_inTimeline = \
                m_rectParameter;
-    int pos = m_ruler->position();
+    int pos = m_ruler->position() - m_offset;
     mlt_rect rect;
     rect.x = m_spinX->value();
     rect.y = m_spinY->value();
diff --git a/src/mltcontroller/effectscontroller.cpp \
b/src/mltcontroller/effectscontroller.cpp index 2cdb61037..a63366e77 100644
--- a/src/mltcontroller/effectscontroller.cpp
+++ b/src/mltcontroller/effectscontroller.cpp
@@ -273,7 +273,8 @@ void EffectsController::initEffect(ItemInfo info, ProfileInfo \
pInfo, EffectsList  bool hasValue = e.hasAttribute(QStringLiteral("value"));
         // Check if this effect has a variable parameter, init effects default value
         if ((type == QLatin1String("animatedrect") || type == \
                QLatin1String("geometry")) && !hasValue) {
-            QString kfr = \
AnimationWidget::getDefaultKeyframes(info.cropStart.frames(fps), \
e.attribute(QStringLiteral("default")), type == QLatin1String("geometry")); +         \
int pos = type == QLatin1String("geometry") ? 0 : info.cropStart.frames(fps); +       \
QString kfr = AnimationWidget::getDefaultKeyframes(pos, \
e.attribute(QStringLiteral("default")), type == QLatin1String("geometry"));  if \
(kfr.contains("%")) {  kfr = EffectsController::getStringRectEval(pInfo, kfr);
             }
diff --git a/src/timeline/abstractclipitem.cpp b/src/timeline/abstractclipitem.cpp
index 963ed125e..7d51cd5fa 100644
--- a/src/timeline/abstractclipitem.cpp
+++ b/src/timeline/abstractclipitem.cpp
@@ -481,7 +481,7 @@ void AbstractClipItem::movedKeyframe(QDomElement effect, int \
newpos, int oldpos,  QDomElement e = params.item(i).toElement();
         if (e.isNull()) continue;
         QString paramName = e.attribute(QStringLiteral("name"));
-        if (e.attribute(QStringLiteral("type")) == QLatin1String("animated")) {
+        if (e.attribute(QStringLiteral("type")).startsWith(QLatin1String("animated"))) \
{  if (m_keyframeView.activeParam(paramName)) {
                 // inserting a keyframe touches all animated params
                 for (int j = 0; j < params.count(); ++j) {
diff --git a/src/timeline/keyframeview.cpp b/src/timeline/keyframeview.cpp
index 30586c7d9..84777d428 100644
--- a/src/timeline/keyframeview.cpp
+++ b/src/timeline/keyframeview.cpp
@@ -74,7 +74,7 @@ QPointF KeyframeView::keyframePoint(QRectF br, int frame, double \
value, double f  
 void KeyframeView::drawKeyFrames(QRectF br, int length, bool active, QPainter \
*painter, const QTransform &transformation)  {
-    if (duration == 0 || m_keyframeType == NoKeyframe || !m_keyAnim.is_valid() || \
m_keyAnim.key_count() < 1) +    if (duration == 0 || m_inTimeline.isEmpty() || \
m_keyframeType == NoKeyframe || !m_keyAnim.is_valid() || m_keyAnim.key_count() < 1)  \
return;  duration = length;
     //m_keyAnim.set_length(length);
@@ -133,6 +133,8 @@ void KeyframeView::drawKeyFrames(QRectF br, int length, bool \
active, QPainter *p  // Make sure edited param is painted last
     paramNames.append(m_inTimeline);
     foreach (const QString &paramName, paramNames) {
+        if (m_notInTimeline.contains(paramName))
+            continue;
         ParameterInfo info = m_paramInfos.value(paramName);
         if (info.max == info.min) {
             // this is probably an animated rect
@@ -547,7 +549,13 @@ void KeyframeView::updateKeyFramePos(QRectF br, int frame, const \
double y)  int newpos = qBound(prev, frame - m_offset, next);
     double newval = keyframeUnmap(br, y);
     mlt_keyframe_type type = m_keyAnim.keyframe_type(activeKeyframe);
-    m_keyProperties.anim_set(m_inTimeline.toUtf8().constData(), newval, newpos, \
duration - m_offset, type); +    if (m_keyframeType == GeometryKeyframe) {
+        // Animated rect
+        mlt_rect rect = \
m_keyProperties.anim_get_rect(m_inTimeline.toUtf8().constData(), activeKeyframe - \
m_offset, duration - m_offset); +        \
m_keyProperties.anim_set(m_inTimeline.toUtf8().constData(), rect, newpos, duration - \
m_offset, type); +    } else {
+        m_keyProperties.anim_set(m_inTimeline.toUtf8().constData(), newval, newpos, \
duration - m_offset, type); +    }
     if (activeKeyframe != newpos) {
         m_keyAnim.remove(activeKeyframe);
         // Move keyframe in other geometries
@@ -838,6 +846,7 @@ bool KeyframeView::loadKeyframes(const QLocale locale, \
QDomElement effect, int c  m_keyframeType = NoKeyframe;
     duration = length;
     m_inTimeline.clear();
+    m_notInTimeline.clear();
     // reset existing properties
     int max = m_keyProperties.count();
     for (int i = max -1; i >= 0; i--) {
@@ -847,15 +856,16 @@ bool KeyframeView::loadKeyframes(const QLocale locale, \
                QDomElement effect, int c
     m_useOffset = effect.attribute(QStringLiteral("kdenlive:sync_in_out")) != \
                QLatin1String("1");
     m_offset = effect.attribute(QStringLiteral("in")).toInt() - cropStart;
     QDomNodeList params = effect.elementsByTagName(QStringLiteral("parameter"));
+    QStringList keyframeTypes;
+    keyframeTypes << QStringLiteral("keyframe") << QStringLiteral("simplekeyframe") \
<< QStringLiteral("geometry") << QStringLiteral("animatedrect") << \
QStringLiteral("animated");  for (int i = 0; i < params.count(); ++i) {
         QDomElement e = params.item(i).toElement();
-        if (e.isNull()) continue;
+        if (e.isNull()) {
+            continue;
+        }
         QString type = e.attribute(QStringLiteral("type"));
-        if (type == QLatin1String("keyframe")) m_keyframeType = NormalKeyframe;
-        else if (type == QLatin1String("simplekeyframe")) m_keyframeType = \
                SimpleKeyframe;
-        else if (type == QLatin1String("geometry") || type == \
                QLatin1String("animatedrect")) m_keyframeType = GeometryKeyframe;
-        else if (type == QLatin1String("animated")) m_keyframeType = \
                AnimatedKeyframe;
-        else continue;
+        if (!keyframeTypes.contains(type))
+            continue;
         QString paramName = e.attribute(QStringLiteral("name"));
         ParameterInfo info;
         info.factor = locale.toDouble(e.attribute(QStringLiteral("factor")));
@@ -866,14 +876,23 @@ bool KeyframeView::loadKeyframes(const QLocale locale, \
QDomElement effect, int c  info.factor = 1;
         }
         m_paramInfos.insert(paramName, info);
-        if (!e.hasAttribute(QStringLiteral("intimeline")) || \
                e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) {
-            // Active parameter
-            m_keyframeMin = info.min;
-            m_keyframeMax = info.max;
-            m_keyframeDefault = locale.toDouble(info.defaultValue);
-            m_keyframeFactor = info.factor;
-            attachToEnd = checkNegatives(e.attribute("value").toUtf8().constData(), \
                duration - m_offset);
-            m_inTimeline = paramName;
+        if (e.hasAttribute(QStringLiteral("notintimeline"))) {
+            // This param should not be drawn in timeline
+            m_notInTimeline << paramName;
+        } else {
+            if (type == QLatin1String("keyframe")) m_keyframeType = NormalKeyframe;
+            else if (type == QLatin1String("simplekeyframe")) m_keyframeType = \
SimpleKeyframe; +            else if (type == QLatin1String("geometry") || type == \
QLatin1String("animatedrect")) m_keyframeType = GeometryKeyframe; +            else \
if (type == QLatin1String("animated")) m_keyframeType = AnimatedKeyframe; +           \
if (!e.hasAttribute(QStringLiteral("intimeline")) || \
e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) { +                \
// Active parameter +                m_keyframeMin = info.min;
+                m_keyframeMax = info.max;
+                m_keyframeDefault = locale.toDouble(info.defaultValue);
+                m_keyframeFactor = info.factor;
+                attachToEnd = \
checkNegatives(e.attribute("value").toUtf8().constData(), duration - m_offset); +     \
m_inTimeline = paramName; +            }
         }
         // parse keyframes
         QString value = e.attribute(QStringLiteral("value"));
@@ -904,7 +923,7 @@ bool KeyframeView::loadKeyframes(const QLocale locale, \
QDomElement effect, int c  
 void KeyframeView::setOffset(int frames)
 {
-    if (!m_keyAnim.is_valid())
+    if (duration == 0 || !m_keyAnim.is_valid())
         return;
     if (m_keyAnim.is_key(-m_offset)) {
         mlt_keyframe_type type = m_keyAnim.keyframe_type(-m_offset);
@@ -955,6 +974,8 @@ void KeyframeView::reset()
     duration = 0;
     attachToEnd = -2;
     activeKeyframe = -1;
+    m_inTimeline.clear();
+    m_notInTimeline.clear();
     int max = m_keyProperties.count();
     for (int i = max -1; i >= 0; i--) {
         m_keyProperties.set(m_keyProperties.get_name(i), (char*) NULL);
diff --git a/src/timeline/keyframeview.h b/src/timeline/keyframeview.h
index 342b50f06..34b4e7212 100644
--- a/src/timeline/keyframeview.h
+++ b/src/timeline/keyframeview.h
@@ -120,6 +120,7 @@ private:
     int m_handleSize;
     bool m_useOffset;
     int m_offset;
+    QStringList m_notInTimeline;
     double keyframeUnmap(QRectF br, double y);
     double keyframeMap(QRectF br, double value);
     QPointF keyframeMap(QRectF br, int frame, double value);


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic