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
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") {
}
}
+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;
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
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();
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");
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);
}
}
}
QList<QGraphicsItem *> itemList;
QUndoCommand *effectCommand = new QUndoCommand();
QString effectName;
+
+ int offset = effect.attribute("clipstart").toInt();
if (effect.tagName() == "effectgroup") {
effectName = effect.attribute("name");
} else {
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) {
} 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
}
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);
}
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);
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());
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);
}
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"));