setPos(info.startPos.frames(fps), (double)(info.track * KdenliveSettings::trackheight()) + 1);
// set speed independant info
- if (m_speed <= 0 && m_speed > -1) m_speed = 1.0;
+ if (m_speed <= 0 && m_speed > -1)
+ m_speed = -1.0;
m_speedIndependantInfo = m_info;
m_speedIndependantInfo.cropStart = GenTime((int)(m_info.cropStart.frames(m_fps) * qAbs(m_speed)), m_fps);
m_speedIndependantInfo.cropDuration = GenTime((int)(m_info.cropDuration.frames(m_fps) * qAbs(m_speed)), m_fps);
m_videoPix = KIcon("kdenlive-show-video").pixmap(QSize(16, 16));
m_audioPix = KIcon("kdenlive-show-audio").pixmap(QSize(16, 16));
- if (m_speed == 1.0) m_clipName = m_clip->name();
- else {
+ if (m_speed == 1.0)
+ m_clipName = m_clip->name();
+ else
m_clipName = m_clip->name() + " - " + QString::number(m_speed * 100, 'f', 0) + '%';
- }
+
m_producer = m_clip->getId();
m_clipType = m_clip->clipType();
//m_cropStart = info.cropStart;
QString def = e.attribute("default");
// Effect has a keyframe type parameter, we need to set the values
if (e.attribute("keyframes").isEmpty()) {
- e.setAttribute("keyframes", QString::number(cropStart().frames(m_fps)) + ':' + def + ';' + QString::number((cropStart() + cropDuration()).frames(m_fps) - 1) + ':' + def);
+ e.setAttribute("keyframes", QString::number(cropStart().frames(m_fps)) + ':' + def);
kDebug() << "///// EFFECT KEYFRAMES INITED: " << e.attribute("keyframes");
//break;
}
}
if (effect.attribute("tag") == "volume" || effect.attribute("tag") == "brightness") {
if (effect.attribute("id") == "fadeout" || effect.attribute("id") == "fade_to_black") {
- int end = (cropDuration() + cropStart()).frames(m_fps);
+ int end = (cropDuration() + cropStart()).frames(m_fps) - 1;
int start = end;
if (effect.attribute("id") == "fadeout") {
if (m_effectList.hasEffect(QString(), "fade_to_black") == -1) {
int keyframeParams = 0;
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
- if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe")) {
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") && e.attribute("intimeline") == "1") {
e.setAttribute("keyframes", keyframes.at(keyframeParams));
if (ix == m_selectedEffect && keyframeParams == 0) {
m_keyframes.clear();
+ m_visibleParam = i;
double max = e.attribute("max").toDouble();
double min = e.attribute("min").toDouble();
m_keyframeFactor = 100.0 / (max - min);
+ m_keyframeOffset = min;
m_keyframeDefault = e.attribute("default").toDouble();
m_selectedKeyframe = 0;
// parse keyframes
if (effect.attribute("disable") != "1")
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
- if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe")) {
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") && e.attribute("intimeline") == "1") {
m_keyframes.clear();
+ m_visibleParam = i;
double max = e.attribute("max").toDouble();
double min = e.attribute("min").toDouble();
m_keyframeFactor = 100.0 / (max - min);
+ m_keyframeOffset = min;
m_keyframeDefault = e.attribute("default").toDouble();
m_selectedKeyframe = 0;
QDomElement effect = getEffectAt(m_selectedEffect);
if (effect.attribute("disable") == "1") return;
QDomNodeList params = effect.elementsByTagName("parameter");
-
- for (int i = 0; i < params.count(); i++) {
- QDomElement e = params.item(i).toElement();
- if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe")) {
- QString keyframes;
- if (m_keyframes.count() > 0) {
- QMap<int, int>::const_iterator i = m_keyframes.constBegin();
- while (i != m_keyframes.constEnd()) {
- keyframes.append(QString::number(i.key()) + ':' + QString::number(i.value()) + ';');
- ++i;
- }
+ QDomElement e = params.item(m_visibleParam).toElement();
+
+ if (!e.isNull()) {
+ QString keyframes;
+ if (m_keyframes.count() > 0) {
+ QMap<int, int>::const_iterator i = m_keyframes.constBegin();
+ while (i != m_keyframes.constEnd()) {
+ keyframes.append(QString::number(i.key()) + ':' + QString::number(i.value()) + ';');
+ ++i;
}
- // Effect has a keyframe type parameter, we need to set the values
- //kDebug() << "::::::::::::::: SETTING EFFECT KEYFRAMES: " << keyframes;
- e.setAttribute("keyframes", keyframes);
- break;
}
+ // Effect has a keyframe type parameter, we need to set the values
+ e.setAttribute("keyframes", keyframes);
}
}
}
-void ClipItem::refreshClip(bool checkDuration)
+void ClipItem::refreshClip(bool checkDuration, bool forceResetThumbs)
{
if (checkDuration && (m_maxDuration != m_clip->maxDuration())) {
m_maxDuration = m_clip->maxDuration();
QString colour = m_clip->getProperty("colour");
colour = colour.replace(0, 2, "#");
m_baseColor = QColor(colour.left(7));
- } else resetThumbs(checkDuration);
+ update();
+ } else resetThumbs(forceResetThumbs);
}
void ClipItem::slotFetchThumbs()
if (rect.height() < 30) addtransitionOffset = 0;
if (qAbs((int)(pos.x() - (rect.x() + m_startFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
- if (m_startFade == 0) setToolTip(i18n("Add audio fade"));
- // xgettext:no-c-format
- else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_startFade, m_fps).seconds()));
return FADEIN;
} else if (pos.x() - rect.x() < maximumOffset && (rect.bottom() - pos.y() > addtransitionOffset)) {
- // xgettext:no-c-format
- setToolTip(i18n("Crop from start: %1s", cropStart().seconds()));
return RESIZESTART;
} else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - m_endFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
- if (m_endFade == 0) setToolTip(i18n("Add audio fade"));
- // xgettext:no-c-format
- else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_endFade, m_fps).seconds()));
return FADEOUT;
} else if ((rect.right() - pos.x() < maximumOffset) && (rect.bottom() - pos.y() > addtransitionOffset)) {
- // xgettext:no-c-format
- setToolTip(i18n("Clip duration: %1s", cropDuration().seconds()));
return RESIZEEND;
} else if ((pos.x() - rect.x() < 16 / scale) && (rect.bottom() - pos.y() <= addtransitionOffset)) {
- setToolTip(i18n("Add transition"));
return TRANSITIONSTART;
} else if ((rect.right() - pos.x() < 16 / scale) && (rect.bottom() - pos.y() <= addtransitionOffset)) {
- setToolTip(i18n("Add transition"));
return TRANSITIONEND;
}
- QString tooltip = "<b>" + m_clipName + "</b>";
- if (!baseClip()->fileURL().isEmpty())
- tooltip.append("<br />" + baseClip()->fileURL().path());
- if (!baseClip()->description().isEmpty())
- tooltip.append("<br />" + baseClip()->description());
- setToolTip(tooltip);
+
return MOVE;
}
for (int j = 0; j < params.count(); j++) {
bool modified = false;
QDomElement e = params.item(j).toElement();
- if (e.isNull())
- continue;
- if (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") {
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe")) {
// parse keyframes and adjust values
const QStringList keyframes = e.attribute("keyframes").split(';', QString::SkipEmptyParts);
QMap <int, double> kfr;
}
e.setAttribute("keyframes", newkfr);
}
- } else if (e.attribute("type") == "geometry" && !e.hasAttribute("fixed")) {
- char *tmp = (char *) qstrdup(e.attribute("value").toUtf8().data());
- Mlt::Geometry geometry(tmp, cropDuration().frames(fps()));
- delete[] tmp;
-
- Mlt::GeometryItem item;
- while (!geometry.next_key(&item, cropDuration().frames(fps()))) {
- geometry.remove(item.frame());
- modified = true;
- }
-
- e.setAttribute("value", geometry.serialise());
}
}
}
// special case: the affine effect needs in / out points
if (effectId == "pan_zoom") {
- int start = cropStart().frames(m_fps);
- int end = (cropStart() + cropDuration()).frames(m_fps);
- if (start < 0) {
- end -= start;
- start = 0;
- }
- parameters.addParam("in", QString::number(start));
- parameters.addParam("out", QString::number(end));
+ parameters.addParam("in", QString::number(cropStart().frames(m_fps)));
+ parameters.addParam("out", QString::number((cropStart() + cropDuration()).frames(m_fps)));
}
QDomNodeList params = effect.elementsByTagName("parameter");
double factor = e.attribute("factor", "1").toDouble();
if (factor != 1) {
for (int j = 0; j < values.count(); j++) {
- QString pos = values.at(j).section(":", 0, 0);
- double val = values.at(j).section(":", 1, 1).toDouble() / factor;
+ QString pos = values.at(j).section(':', 0, 0);
+ double val = values.at(j).section(':', 1, 1).toDouble() / factor;
values[j] = pos + "=" + QString::number(val);
}
}
{
m_speed = speed;
if (m_speed <= 0 && m_speed > -1)
- m_speed = 1.0;
+ m_speed = -1.0;
m_strobe = strobe;
if (m_speed == 1.0) m_clipName = baseClip()->name();
else m_clipName = baseClip()->name() + " - " + QString::number(speed * 100, 'f', 0) + '%';
//virtual
void ClipItem::dropEvent(QGraphicsSceneDragDropEvent * event)
{
- const QString effects = QString(event->mimeData()->data("kdenlive/effectslist"));
+ const QString effects = QString::fromUtf8(event->mimeData()->data("kdenlive/effectslist"));
QDomDocument doc;
doc.setContent(effects, true);
const QDomElement e = doc.documentElement();
QDomNodeList params = effect.elementsByTagName("parameter");
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
- QString kfr = e.attribute("keyframes");
- const QStringList keyframes = kfr.split(';', QString::SkipEmptyParts);
- QStringList newkfr;
- bool added = false;
- foreach(const QString &str, keyframes) {
- int kpos = str.section(':', 0, 0).toInt();
- double newval = str.section(':', 1, 1).toDouble();
- if (kpos < pos) {
- newkfr.append(str);
- } else if (!added) {
- if (i == 0) newkfr.append(QString::number(pos) + ":" + QString::number(val));
- else newkfr.append(QString::number(pos) + ":" + QString::number(newval));
- if (kpos > pos) newkfr.append(str);
- added = true;
- } else newkfr.append(str);
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe")) {
+ QString kfr = e.attribute("keyframes");
+ const QStringList keyframes = kfr.split(';', QString::SkipEmptyParts);
+ QStringList newkfr;
+ bool added = false;
+ foreach(const QString &str, keyframes) {
+ int kpos = str.section(':', 0, 0).toInt();
+ double newval = str.section(':', 1, 1).toDouble();
+ if (kpos < pos) {
+ newkfr.append(str);
+ } else if (!added) {
+ if (i == m_visibleParam)
+ newkfr.append(QString::number(pos) + ":" + QString::number(val));
+ else
+ newkfr.append(QString::number(pos) + ":" + QString::number(newval));
+ if (kpos > pos) newkfr.append(str);
+ added = true;
+ } else newkfr.append(str);
+ }
+ if (!added) {
+ if (i == m_visibleParam)
+ newkfr.append(QString::number(pos) + ":" + QString::number(val));
+ else
+ newkfr.append(QString::number(pos) + ":" + e.attribute("default"));
+ }
+ e.setAttribute("keyframes", newkfr.join(";"));
}
- if (!added) newkfr.append(QString::number(pos) + ":" + QString::number(val));
- e.setAttribute("keyframes", newkfr.join(";"));
}
}
int end = (cropStart() + cropDuration()).frames(m_fps) - 1;
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
- QString kfr = e.attribute("keyframes");
- const QStringList keyframes = kfr.split(';', QString::SkipEmptyParts);
- QStringList newkfr;
- foreach(const QString &str, keyframes) {
- if (str.section(':', 0, 0).toInt() != oldpos) {
- newkfr.append(str);
- } else if (newpos != -1) {
- newpos = qMax(newpos, start);
- newpos = qMin(newpos, end);
- if (i == 0) newkfr.append(QString::number(newpos) + ":" + QString::number(value));
- else newkfr.append(QString::number(newpos) + ":" + str.section(':', 1, 1));
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe")) {
+ QString kfr = e.attribute("keyframes");
+ const QStringList keyframes = kfr.split(';', QString::SkipEmptyParts);
+ QStringList newkfr;
+ foreach(const QString &str, keyframes) {
+ if (str.section(':', 0, 0).toInt() != oldpos) {
+ newkfr.append(str);
+ } else if (newpos != -1) {
+ newpos = qMax(newpos, start);
+ newpos = qMin(newpos, end);
+ if (i == m_visibleParam)
+ newkfr.append(QString::number(newpos) + ":" + QString::number(value));
+ else
+ newkfr.append(QString::number(newpos) + ":" + str.section(':', 1, 1));
+ }
}
+ e.setAttribute("keyframes", newkfr.join(";"));
}
- e.setAttribute("keyframes", newkfr.join(";"));
}
updateKeyframes(effect);
m_keyframes.clear();
// parse keyframes
QDomNodeList params = effect.elementsByTagName("parameter");
- QDomElement e = params.item(0).toElement();
+ QDomElement e = params.item(m_visibleParam).toElement();
+ if (e.attribute("intimeline") != "1") {
+ setSelectedEffect(m_selectedEffect);
+ return;
+ }
const QStringList keyframes = e.attribute("keyframes").split(';', QString::SkipEmptyParts);
foreach(const QString &str, keyframes) {
int pos = str.section(':', 0, 0).toInt();
}
}
+QList <int> ClipItem::updatePanZoom(int width, int height, int cut)
+{
+ QList <int> effectPositions;
+ for (int i = 0; i < m_effectList.count(); i++) {
+ QDomElement effect = m_effectList.at(i);
+ QDomNodeList params = effect.elementsByTagName("parameter");
+ for (int j = 0; j < params.count(); j++) {
+ QDomElement e = params.item(j).toElement();
+ if (e.isNull())
+ continue;
+ if (e.attribute("type") == "geometry" && !e.hasAttribute("fixed")) {
+ effectPositions << i;
+
+ int in = cropStart().frames(fps());
+ int out = in + cropDuration().frames(fps());
+ int dur = out - in - 1;
+
+ effect.setAttribute("in", in);
+ effect.setAttribute("out", out);
+
+ Mlt::Geometry geometry(e.attribute("value").toUtf8().data(), dur, width, height);
+ Mlt::GeometryItem item;
+ bool endFrameAdded = false;
+ if (cut == 0) {
+ while (!geometry.next_key(&item, dur)) {
+ if (!endFrameAdded) {
+ // add keyframe at the end with interpolated value
+
+ // but only once ;)
+ endFrameAdded = true;
+
+ Mlt::GeometryItem endItem;
+ Mlt::GeometryItem interp;
+ geometry.fetch(&interp, dur - 1);
+ endItem.frame(dur - 1);
+ endItem.x(interp.x());
+ endItem.y(interp.y());
+ endItem.w(interp.w());
+ endItem.h(interp.h());
+ endItem.mix(interp.mix());
+ geometry.insert(&endItem);
+ }
+ geometry.remove(item.frame());
+ }
+ } else {
+ Mlt::Geometry origGeometry(e.attribute("value").toUtf8().data(), dur, width, height);
+ // remove keyframes before cut point
+ while (!geometry.prev_key(&item, cut - 1) && item.frame() < cut)
+ geometry.remove(item.frame());
+
+ // add a keyframe at new pos 0
+ origGeometry.fetch(&item, cut);
+ item.frame(0);
+ geometry.insert(&item);
+
+ // move exisiting keyframes by -cut
+ while (!origGeometry.next_key(&item, cut)) {
+ geometry.remove(item.frame());
+ origGeometry.remove(item.frame());
+ item.frame(item.frame() - cut);
+ geometry.insert(&item);
+ }
+
+ }
+
+ e.setAttribute("value", geometry.serialise());
+ }
+ }
+ }
+
+ return effectPositions;
+}
+
+Mlt::Producer *ClipItem::getProducer(int track, bool trackSpecific)
+{
+ if (isAudioOnly())
+ return m_clip->audioProducer(track);
+ else if (isVideoOnly())
+ return m_clip->videoProducer();
+ else
+ return m_clip->producer(trackSpecific ? track : -1);
+}
#include "clipitem.moc"