Fix copy/paste of keyframes

parent ddae0fb1
...@@ -631,7 +631,13 @@ void CollapsibleEffect::dragLeaveEvent(QDragLeaveEvent */*event*/) ...@@ -631,7 +631,13 @@ void CollapsibleEffect::dragLeaveEvent(QDragLeaveEvent */*event*/)
void CollapsibleEffect::importKeyframes(const QString &keyframes) void CollapsibleEffect::importKeyframes(const QString &keyframes)
{ {
QMap <QString, QString> data; QMap <QString, QString> data;
data.insert(i18n("Geometry"), keyframes); if (keyframes.contains(QLatin1Char('\n'))) {
QStringList params = keyframes.split(QLatin1Char('\n'), QString::SkipEmptyParts);
foreach(const QString &param, params) {
data.insert(param.section("=", 0, 0), param.section("=", 1));
}
}
else data.insert(i18n("Geometry"), keyframes);
emit importClipKeyframes(AVWidget, m_itemInfo, m_effect.cloneNode().toElement(), data); emit importClipKeyframes(AVWidget, m_itemInfo, m_effect.cloneNode().toElement(), data);
} }
......
...@@ -1382,14 +1382,14 @@ void AnimationWidget::slotCopyKeyframes() ...@@ -1382,14 +1382,14 @@ void AnimationWidget::slotCopyKeyframes()
const QMap <QString, QString> anims = getAnimation(); const QMap <QString, QString> anims = getAnimation();
if (anims.isEmpty()) if (anims.isEmpty())
return; return;
QString value; QString result;
if (anims.count() == 1) { QMapIterator<QString, QString> i(anims);
value = anims.first(); while (i.hasNext()) {
} else { i.next();
value = anims.value(m_inTimeline); result.append(i.key() + QStringLiteral("=") + i.value() + QLatin1Char('\n'));
} }
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(value); clipboard->setText(result);
} }
void AnimationWidget::slotImportKeyframes() void AnimationWidget::slotImportKeyframes()
......
...@@ -69,10 +69,15 @@ KeyframeImport::KeyframeImport(ItemInfo srcInfo, ItemInfo dstInfo, QMap<QString, ...@@ -69,10 +69,15 @@ KeyframeImport::KeyframeImport(ItemInfo srcInfo, ItemInfo dstInfo, QMap<QString,
lay->addWidget(m_previewLabel); lay->addWidget(m_previewLabel);
m_keyframeView = new KeyframeView(0, this); m_keyframeView = new KeyframeView(0, this);
// Zone in / out // Zone in / out
m_inPoint = new PositionEdit(i18n("In"), srcInfo.cropStart.frames(tc.fps()), srcInfo.cropStart.frames(tc.fps()), (srcInfo.cropStart + srcInfo.cropDuration).frames(tc.fps()), tc, this); ItemInfo reference;
if (srcInfo.isValid())
reference = srcInfo;
else
reference = dstInfo;
m_inPoint = new PositionEdit(i18n("In"), reference.cropStart.frames(tc.fps()), reference.cropStart.frames(tc.fps()), (reference.cropStart + reference.cropDuration).frames(tc.fps()), tc, this);
connect(m_inPoint, SIGNAL(parameterChanged(int)), this, SLOT(updateDisplay())); connect(m_inPoint, SIGNAL(parameterChanged(int)), this, SLOT(updateDisplay()));
lay->addWidget(m_inPoint); lay->addWidget(m_inPoint);
m_outPoint = new PositionEdit(i18n("Out"), (srcInfo.cropStart + srcInfo.cropDuration).frames(tc.fps()), srcInfo.cropStart.frames(tc.fps()), (srcInfo.cropStart + srcInfo.cropDuration).frames(tc.fps()), tc, this); m_outPoint = new PositionEdit(i18n("Out"), (reference.cropStart + reference.cropDuration).frames(tc.fps()), reference.cropStart.frames(tc.fps()), (reference.cropStart + reference.cropDuration).frames(tc.fps()), tc, this);
connect(m_outPoint, SIGNAL(parameterChanged(int)), this, SLOT(updateDisplay())); connect(m_outPoint, SIGNAL(parameterChanged(int)), this, SLOT(updateDisplay()));
lay->addWidget(m_outPoint); lay->addWidget(m_outPoint);
...@@ -100,6 +105,9 @@ KeyframeImport::KeyframeImport(ItemInfo srcInfo, ItemInfo dstInfo, QMap<QString, ...@@ -100,6 +105,9 @@ KeyframeImport::KeyframeImport(ItemInfo srcInfo, ItemInfo dstInfo, QMap<QString,
m_sourceCombo->insertItem(ix, i18n("Geometry")); m_sourceCombo->insertItem(ix, i18n("Geometry"));
m_sourceCombo->setItemData(ix, QString::number(10), Qt::UserRole); m_sourceCombo->setItemData(ix, QString::number(10), Qt::UserRole);
ix++; ix++;
m_sourceCombo->insertItem(ix, i18n("Position"));
m_sourceCombo->setItemData(ix, QString::number(11), Qt::UserRole);
ix++;
} }
if (!m_simpleTargets.isEmpty()) { if (!m_simpleTargets.isEmpty()) {
m_sourceCombo->insertItem(ix, i18n("X")); m_sourceCombo->insertItem(ix, i18n("X"));
...@@ -381,7 +389,8 @@ QString KeyframeImport::selectedData() const ...@@ -381,7 +389,8 @@ QString KeyframeImport::selectedData() const
return m_keyframeView->getSingleAnimation(ix, m_inPoint->getPosition(), m_outPoint->getPosition(), m_offsetPoint->getPosition(), m_limitKeyframes->isChecked() ? m_limitNumber->value() : 0, maximas, m_destMin.value(), m_destMax.value()); return m_keyframeView->getSingleAnimation(ix, m_inPoint->getPosition(), m_outPoint->getPosition(), m_offsetPoint->getPosition(), m_limitKeyframes->isChecked() ? m_limitNumber->value() : 0, maximas, m_destMin.value(), m_destMax.value());
} }
// Geometry target // Geometry target
return m_keyframeView->getOffsetAnimation(m_inPoint->getPosition(), m_outPoint->getPosition(), m_offsetPoint->getPosition(), m_limitKeyframes->isChecked() ? m_limitNumber->value() : 0, m_profile, m_supportsAnim); int pos = m_sourceCombo->currentData().toInt();
return m_keyframeView->getOffsetAnimation(m_inPoint->getPosition(), m_outPoint->getPosition(), m_offsetPoint->getPosition(), m_limitKeyframes->isChecked() ? m_limitNumber->value() : 0, m_profile, m_supportsAnim, pos == 11);
} }
QString KeyframeImport::selectedTarget() const QString KeyframeImport::selectedTarget() const
......
...@@ -421,7 +421,7 @@ QString KeyframeView::getSingleAnimation(int ix, int in, int out, int offset, in ...@@ -421,7 +421,7 @@ QString KeyframeView::getSingleAnimation(int ix, int in, int out, int offset, in
return result; return result;
} }
QString KeyframeView::getOffsetAnimation(int in, int out, int offset, int limitKeyframes, ProfileInfo profile, bool allowAnimation) QString KeyframeView::getOffsetAnimation(int in, int out, int offset, int limitKeyframes, ProfileInfo profile, bool allowAnimation, bool positionOnly)
{ {
m_keyProperties.set("kdenlive_import", ""); m_keyProperties.set("kdenlive_import", "");
int newduration = out - in + offset; int newduration = out - in + offset;
...@@ -437,28 +437,32 @@ QString KeyframeView::getOffsetAnimation(int in, int out, int offset, int limitK ...@@ -437,28 +437,32 @@ QString KeyframeView::getOffsetAnimation(int in, int out, int offset, int limitK
rect.h = pHeight; rect.h = pHeight;
rect.o = 100; rect.o = 100;
m_keyProperties.anim_set("kdenlive_import", rect, offset, newduration, kftype); m_keyProperties.anim_set("kdenlive_import", rect, offset, newduration, kftype);
if (limitKeyframes > 0) { if (limitKeyframes > 0 && m_keyAnim.key_count() > limitKeyframes) {
int step = (out - in) / limitKeyframes; int step = (out - in) / limitKeyframes;
for (int i = step; i < out; i+= step) { for (int i = step; i < out; i+= step) {
rect = m_keyProperties.anim_get_rect(m_inTimeline.toUtf8().constData(), in + i, duration); rect = m_keyProperties.anim_get_rect(m_inTimeline.toUtf8().constData(), in + i, duration);
rect.x = (int) rect.x; rect.x = (int) rect.x;
rect.y = (int) rect.y; rect.y = (int) rect.y;
rect.w = pWidth; if (positionOnly) {
rect.h = pHeight; rect.w = pWidth;
rect.o = 100; rect.h = pHeight;
rect.o = 100;
}
m_keyProperties.anim_set("kdenlive_import", rect, offset + i, newduration, kftype); m_keyProperties.anim_set("kdenlive_import", rect, offset + i, newduration, kftype);
} }
} else { } else {
int next = m_keyAnim.next_key(in + 1); int pos;
while (next < out && next > 0) { for(int i = 0; i < m_keyAnim.key_count(); ++i) {
rect = m_keyProperties.anim_get_rect(m_inTimeline.toUtf8().constData(), next, duration); m_keyAnim.key_get(i, pos, kftype);
rect = m_keyProperties.anim_get_rect(m_inTimeline.toUtf8().constData(), pos, duration);
rect.x = (int) rect.x; rect.x = (int) rect.x;
rect.y = (int) rect.y; rect.y = (int) rect.y;
rect.w = pWidth; if (positionOnly) {
rect.h = pHeight; rect.w = pWidth;
rect.o = 100; rect.h = pHeight;
m_keyProperties.anim_set("kdenlive_import", rect, offset + next - in, newduration, mlt_keyframe_linear); rect.o = 100;
next = m_keyAnim.next_key(next + 1); }
m_keyProperties.anim_set("kdenlive_import", rect, offset + pos - in, newduration, kftype);
} }
} }
QString result = anim.serialize_cut(); QString result = anim.serialize_cut();
...@@ -722,8 +726,8 @@ const QString KeyframeView::serialize(const QString &name, bool rectAnimation) ...@@ -722,8 +726,8 @@ const QString KeyframeView::serialize(const QString &name, bool rectAnimation)
QString key; QString key;
QLocale locale; QLocale locale;
QStringList result; QStringList result;
int pos;
for(int i = 0; i < m_keyAnim.key_count(); ++i) { for(int i = 0; i < m_keyAnim.key_count(); ++i) {
int pos = m_keyAnim.key_get_frame(i);
m_keyAnim.key_get(i, pos, type); m_keyAnim.key_get(i, pos, type);
double val = m_keyProperties.anim_get_double(m_inTimeline.toUtf8().constData(), pos, duration - m_offset); double val = m_keyProperties.anim_get_double(m_inTimeline.toUtf8().constData(), pos, duration - m_offset);
if (pos >= attachToEnd) { if (pos >= attachToEnd) {
......
...@@ -102,7 +102,7 @@ public: ...@@ -102,7 +102,7 @@ public:
/** @brief Returns a copy of the original anim, with a crop zone (in/out), frame offset, max number of keyframes, and value mapping */ /** @brief Returns a copy of the original anim, with a crop zone (in/out), frame offset, max number of keyframes, and value mapping */
QString getSingleAnimation(int ix, int in, int out, int offset, int limitKeyframes, QPoint maximas, double min, double max); QString getSingleAnimation(int ix, int in, int out, int offset, int limitKeyframes, QPoint maximas, double min, double max);
/** @brief Returns a copy of the original anim, with a crop zone (in/out) and frame offset */ /** @brief Returns a copy of the original anim, with a crop zone (in/out) and frame offset */
QString getOffsetAnimation(int in, int out, int offset, int limitKeyframes, ProfileInfo profile, bool allowAnimation); QString getOffsetAnimation(int in, int out, int offset, int limitKeyframes, ProfileInfo profile, bool allowAnimation, bool positionOnly);
private: private:
Mlt::Properties m_keyProperties; Mlt::Properties m_keyProperties;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment