return;
}
QString keyframeData = ui.data_list->itemData(ui.data_list->currentIndex()).toString();
- QStringList keyframeList = keyframeData.split(';', QString::SkipEmptyParts);
+
+ int offset = item->cropStart().frames(m_document->fps());
+ Mlt::Geometry geometry(keyframeData.toUtf8().data(), item->baseClip()->maxDuration().frames(m_document->fps()), m_document->mltProfile().width, m_document->mltProfile().height);
+ Mlt::Geometry newGeometry(QString().toUtf8().data(), item->baseClip()->maxDuration().frames(m_document->fps()), m_document->mltProfile().width, m_document->mltProfile().height);
+ Mlt::GeometryItem gitem;
+ geometry.fetch(&gitem, offset);
+ gitem.frame(0);
+ newGeometry.insert(gitem);
+ int pos = offset + 1;
+ while (!geometry.next_key(&gitem, pos)) {
+ pos = gitem.frame();
+ gitem.frame(pos - offset);
+ pos++;
+ newGeometry.insert(gitem);
+ }
+ QStringList keyframeList = QString(newGeometry.serialise()).split(';', QString::SkipEmptyParts);
+
QString result;
if (ui.import_position->isChecked()) {
if (ui.import_size->isChecked()) {
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
MonitorEditWidget *edit = monitor->getEffectEdit();
edit->removeCustomControls();
+ edit->addCustomButton(KIcon("draw-path"), i18n("Show path"), this, SLOT(slotShowPath(bool)), true, KdenliveSettings::onmonitoreffects_geometryshowpath());
edit->addCustomButton(KIcon("transform-crop"), i18n("Show previous keyframe"), this, SLOT(slotShowPreviousKeyFrame(bool)), true, KdenliveSettings::onmonitoreffects_geometryshowprevious());
m_scene = edit->getScene();
m_scene->cleanup();
QAction *importKeyframes = new QAction(i18n("Import keyframes from clip"), this);
connect(importKeyframes, SIGNAL(triggered()), this, SIGNAL(importClipKeyframes()));
menu->addAction(importKeyframes);
- QAction *resetKeyframes = new QAction(i18n("Reset keyframes"), this);
+ QAction *resetKeyframes = new QAction(i18n("Reset all keyframes"), this);
connect(resetKeyframes, SIGNAL(triggered()), this, SLOT(slotResetKeyframes()));
menu->addAction(resetKeyframes);
+
+ QAction *resetNextKeyframes = new QAction(i18n("Reset keyframes after cursor"), this);
+ connect(resetNextKeyframes, SIGNAL(triggered()), this, SLOT(slotResetNextKeyframes()));
+ menu->addAction(resetNextKeyframes);
+ QAction *resetPreviousKeyframes = new QAction(i18n("Reset keyframes before cursor"), this);
+ connect(resetPreviousKeyframes, SIGNAL(triggered()), this, SLOT(slotResetPreviousKeyframes()));
+ menu->addAction(resetPreviousKeyframes);
menu->addSeparator();
QAction *syncTimeline = new QAction(KIcon("insert-link"), i18n("Synchronize with timeline cursor"), this);
slotPositionChanged(-1, false);
}
+void GeometryWidget::slotShowPath(bool show)
+{
+ KdenliveSettings::setOnmonitoreffects_geometryshowpath(show);
+ if (m_geomPath) {
+ if (show) m_scene->addItem(m_geomPath);
+ else m_scene->removeItem(m_geomPath);
+ }
+ slotPositionChanged(-1, false);
+}
+
void GeometryWidget::updateTimecodeFormat()
{
m_timePos->slotUpdateTimeCodeFormat();
connect(m_geomPath, SIGNAL(changed()), this, SLOT(slotUpdatePath()));
m_geomPath->setPen(QPen(Qt::red));
m_geomPath->setPoints(m_geometry);
- m_scene->addItem(m_geomPath);
+ if (KdenliveSettings::onmonitoreffects_geometryshowpath())
+ m_scene->addItem(m_geomPath);
m_scene->centerView();
slotPositionChanged(0, false);
}
}
m_timeline->update();
- if (m_geomPath) {
+ if (m_geomPath && KdenliveSettings::onmonitoreffects_geometryshowpath()) {
m_scene->removeItem(m_geomPath);
m_geomPath->setPoints(m_geometry);
m_scene->addItem(m_geomPath);
geom->insert(item2);
}
}
- if (m_geomPath) {
+ if (m_geomPath && KdenliveSettings::onmonitoreffects_geometryshowpath()) {
m_scene->removeItem(m_geomPath);
m_geomPath->setPoints(m_geometry);
m_scene->addItem(m_geomPath);
item.mix(100);
m_geometry->insert(item);
m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
- if (m_geomPath) {
+ if (m_geomPath && KdenliveSettings::onmonitoreffects_geometryshowpath()) {
+ m_scene->removeItem(m_geomPath);
+ m_geomPath->setPoints(m_geometry);
+ m_scene->addItem(m_geomPath);
+ }
+ slotPositionChanged(-1, false);
+ emit parameterChanged();
+}
+
+void GeometryWidget::slotResetNextKeyframes()
+{
+ // Delete keyframes after cursor pos
+ Mlt::GeometryItem item;
+ int pos = m_timePos->getValue();
+ while (!m_geometry->next_key(&item, pos)) {
+ m_geometry->remove(item.frame());
+ }
+
+ // Make sure we have at least one keyframe
+ if (m_geometry->next_key(&item, 0)) {
+ item.frame(0);
+ item.x(0);
+ item.y(0);
+ item.w(m_monitor->render->frameRenderWidth());
+ item.h(m_monitor->render->renderHeight());
+ item.mix(100);
+ m_geometry->insert(item);
+ }
+ m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
+ if (m_geomPath && KdenliveSettings::onmonitoreffects_geometryshowpath()) {
+ m_scene->removeItem(m_geomPath);
+ m_geomPath->setPoints(m_geometry);
+ m_scene->addItem(m_geomPath);
+ }
+ slotPositionChanged(-1, false);
+ emit parameterChanged();
+}
+
+void GeometryWidget::slotResetPreviousKeyframes()
+{
+ // Delete keyframes before cursor pos
+ Mlt::GeometryItem item;
+ int pos = 0;
+ while (!m_geometry->next_key(&item, pos) && pos < m_timePos->getValue()) {
+ pos = item.frame() + 1;
+ m_geometry->remove(item.frame());
+ }
+
+ // Make sure we have at least one keyframe
+ if (!m_geometry->next_key(&item, 0)) {
+ item.frame(0);
+ /*item.x(0);
+ item.y(0);
+ item.w(m_monitor->render->frameRenderWidth());
+ item.h(m_monitor->render->renderHeight());
+ item.mix(100);*/
+ m_geometry->insert(item);
+ }
+ else {
+ item.frame(0);
+ item.x(0);
+ item.y(0);
+ item.w(m_monitor->render->frameRenderWidth());
+ item.h(m_monitor->render->renderHeight());
+ item.mix(100);
+ m_geometry->insert(item);
+ }
+ m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
+ if (m_geomPath && KdenliveSettings::onmonitoreffects_geometryshowpath()) {
m_scene->removeItem(m_geomPath);
m_geomPath->setPoints(m_geometry);
m_scene->addItem(m_geomPath);
}
slotPositionChanged(-1, false);
emit parameterChanged();
-
}
void GeometryWidget::importKeyframes(const QString &data, int maximum)
m_geometry->insert(item);
}
m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
- if (m_geomPath) {
+ if (m_geomPath && KdenliveSettings::onmonitoreffects_geometryshowpath()) {
m_scene->removeItem(m_geomPath);
m_geomPath->setPoints(m_geometry);
m_scene->addItem(m_geomPath);
/** @brief Updates position of the local timeline to @param relTimelinePos. */
void slotSyncPosition(int relTimelinePos);
void slotResetKeyframes();
+ void slotResetNextKeyframes();
+ void slotResetPreviousKeyframes();
void slotUpdateRange(int inPoint, int outPoint);
private:
void slotFitToHeight();
/** @brief Show / hide previous keyframe in monitor scene. */
void slotShowPreviousKeyFrame(bool show);
+ /** @brief Show / hide keyframe path in monitor scene. */
+ void slotShowPath(bool show);
signals:
void parameterChanged();
<default>false</default>
</entry>
+ <entry name="onmonitoreffects_geometryshowpath" type="Bool">
+ <label>Show keyframe path in monitor.</label>
+ <default>true</default>
+ </entry>
+
<entry name="onmonitoreffects_cornersshowcontrols" type="Bool">
<label>Show additional controls in the c0rners on-monitor widget.</label>
<default>false</default>
extraParams.insert("projecttreefilter", "1");
QString keyword("%count");
extraParams.insert("resultmessage", i18n("Found %1 scenes.", keyword));
+ if (ui.store_data->isChecked()) {
+ // We want to save result as clip metadata
+ extraParams.insert("storedata", "1");
+ }
+ if (ui.zone_only->isChecked()) {
+ // We want to analyze only clip zone
+ extraParams.insert("zoneonly", "1");
+ }
if (ui.add_markers->isChecked()) {
// We want to create markers
extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex()));
ProjectItem *item = getItemById(id);
if (!item) continue;
QStringList jobArgs;
+ if (extraParams.contains("zoneonly")) {
+ // Analyse clip zone only, remove in / out and replace with zone
+ preParams.takeFirst();
+ preParams.takeFirst();
+ QPoint zone = item->referencedClip()->zone();
+ jobArgs << QString::number(zone.x()) << QString::number(zone.y());
+ }
jobArgs << preParams;
if (ids.count() == 1) {
jobArgs << consumer + ':' + destination;
}
bool dataProcessed = false;
QString key = filterInfo.value("key");
+ int offset = filterInfo.value("offset").toInt();
QStringList value = results.value(key).split(';', QString::SkipEmptyParts);
kDebug()<<"// RESULT; "<<key<<" = "<<value;
if (filterInfo.contains("resultmessage")) {
int newPos = pos.section("=", 0, 0).toInt();
// Don't use scenes shorter than 1 second
if (newPos - cutPos < 24) continue;
- (void) new AddClipCutCommand(this, id, cutPos, newPos, QString(), true, false, command);
+ (void) new AddClipCutCommand(this, id, cutPos + offset, newPos + offset, QString(), true, false, command);
cutPos = newPos;
}
if (command->childCount() == 0)
int newPos = pos.section("=", 0, 0).toInt();
// Don't use scenes shorter than 1 second
if (newPos - cutPos < 24) continue;
- CommentedTime m(GenTime(newPos, m_fps), QString::number(index), markersType);
+ CommentedTime m(GenTime(newPos + offset, m_fps), QString::number(index), markersType);
markersList << m;
index++;
cutPos = newPos;
return;
}
int in = m_params.takeFirst().toInt();
+ if (in > 0 && !m_extra.contains("offset")) m_extra.insert("offset", QString::number(in));
int out = m_params.takeFirst().toInt();
QString producerParams =m_params.takeFirst();
QString filter = m_params.takeFirst();
}
if (out == -1) {
prod = new Mlt::Producer(*m_profile, m_url.toUtf8().constData());
+ m_length = prod->get_length();
}
else {
Mlt::Producer *tmp = new Mlt::Producer(*m_profile, m_url.toUtf8().constData());
prod = tmp->cut(in, out);
delete tmp;
+ m_length = prod->get_playtime();
}
if (m_extra.contains("producer_profile")) {
m_profile->from_producer(*prod);
Mlt::Playlist playlist;
playlist.append(*prod);
tractor.set_track(playlist, 0);
- m_length = prod->get_length();
m_consumer->connect(tractor);
prod->set_speed(0);
prod->seek(0);
m_effectEdit->transferParamDesc(e, m_usedTransition->info(), false);
} else {
// Same transition, we just want to update the parameters value
- slotUpdateEffectParams(e, e);
- if (m_usedTransition->hasGeometry())
- m_effectEdit->transferParamDesc(m_usedTransition->toXML(), m_usedTransition->info(), false);
+ int ix = transitionList->findData(m_usedTransition->transitionInfo(), Qt::UserRole, Qt::MatchExactly);
+ if (ix != transitionList->currentIndex()) {
+ // Transition type changed, reload params
+ transitionList->blockSignals(true);
+ transitionList->setCurrentIndex(ix);
+ transitionList->blockSignals(false);
+ m_effectEdit->transferParamDesc(e, m_usedTransition->info(), false);
+ }
+ else {
+ slotUpdateEffectParams(e, e);
+ if (m_usedTransition->hasGeometry())
+ m_effectEdit->transferParamDesc(m_usedTransition->toXML(), m_usedTransition->info(), false);
+ }
+ if (m_effectEdit->needsMonitorEffectScene())
+ connect(m_effectEdit->monitor(), SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
}
slotCheckMonitorPosition(m_effectEdit->monitor()->render->seekFramePosition());
}
m_effectEdit->setFrameSize(p);
m_autoTrackTransition = nextTrack;
disconnect(m_effectEdit->monitor(), SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
- if (t == m_usedTransition) {
+ if (t == m_usedTransition) {
if (t == NULL) return;
if (update) {
transitionTrack->blockSignals(true);
<rect>
<x>0</x>
<y>0</y>
- <width>352</width>
- <height>90</height>
+ <width>282</width>
+ <height>115</height>
</rect>
</property>
<property name="windowTitle">
<string>Scene Cut</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="3" column="0" colspan="3">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <item row="0" column="1" colspan="2">
+ <widget class="QComboBox" name="marker_type"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="add_markers">
+ <property name="text">
+ <string>Add clip markers</string>
</property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <widget class="QCheckBox" name="zone_only">
+ <property name="text">
+ <string>Analyse only selected zone</string>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>218</width>
- <height>2</height>
+ <width>20</width>
+ <height>40</height>
</size>
</property>
</spacer>
</item>
- <item row="0" column="0">
- <widget class="QCheckBox" name="add_markers">
- <property name="text">
- <string>Add clip markers</string>
+ <item row="5" column="0" colspan="3">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="checked">
- <bool>true</bool>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
- <item row="0" column="1" colspan="2">
- <widget class="QComboBox" name="marker_type"/>
- </item>
<item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="cut_scenes">
<property name="text">
</property>
</widget>
</item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QCheckBox" name="store_data">
+ <property name="text">
+ <string>Save result in clip metadata</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<resources/>