From: Jean-Baptiste Mardelle Date: Sun, 21 Oct 2012 11:37:35 +0000 (+0200) Subject: Prepare importing of keyframes from clip analysis X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=17a4a5bf6c8ab0cb1554a010a002a2e208d988c9;p=kdenlive Prepare importing of keyframes from clip analysis --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 74c44596..0aef0bbb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -263,6 +263,7 @@ kde4_add_ui_files(kdenlive_UIS widgets/fontval_ui.ui widgets/cutjobdialog_ui.ui widgets/scenecutdialog_ui.ui + widgets/importkeyframesdialog_ui.ui ) if(OPENGL_FOUND) diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 45834e5d..029f004c 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -52,6 +52,7 @@ #include "commands/changeeffectstatecommand.h" #include "commands/movegroupcommand.h" #include "ui_addtrack_ui.h" +#include "ui_importkeyframesdialog_ui.h" #include "initeffects.h" #include "commands/locktrackcommand.h" #include "commands/groupclipscommand.h" @@ -7514,3 +7515,69 @@ void CustomTrackView::slotGotFilterJobResults(const QString &/*id*/, int startPo } +void CustomTrackView::slotImportClipKeyframes(GRAPHICSRECTITEM type) +{ + if (!m_selectionGroup) { + emit displayMessage(i18n("You need to select one clip and one transition"), ErrorMessage); + return; + } + // Make sure there is no collision + QList children = m_selectionGroup->childItems(); + ClipItem *item; + for (int i = 0; i < children.count(); i++) { + if (children.at(i)->type() == AVWIDGET) { + item = (ClipItem*) children.at(i); + break; + } + } + QMap data = item->baseClip()->analysisData(); + if (data.isEmpty()) { + emit displayMessage(i18n("No keyframe data found in clip"), ErrorMessage); + return; + } + QPointer d = new QDialog(this); + Ui::ImportKeyframesDialog_UI ui; + ui.setupUi(d); + + // Set up data + int ix = 0; + QMap::const_iterator i = data.constBegin(); + while (i != data.constEnd()) { + ui.data_list->insertItem(ix, i.key()); + ui.data_list->setItemData(ix, i.value(), Qt::UserRole); + ++i; + ix++; + } + + if (d->exec() != QDialog::Accepted) { + delete d; + return; + } + QString keyframeData = ui.data_list->itemData(ui.data_list->currentIndex()).toString(); + QStringList keyframeList = keyframeData.split(';', QString::SkipEmptyParts); + QString result; + if (ui.import_position->isChecked()) { + if (ui.import_size->isChecked()) { + foreach(QString key, keyframeList) { + if (key.count(':') > 1) result.append(key.section(':', 0, 1)); + else result.append(key); + result.append(';'); + } + } + else { + foreach(QString key, keyframeList) { + result.append(key.section(':', 0, 0)); + result.append(';'); + } + } + } + else if (ui.import_size->isChecked()) { + foreach(QString key, keyframeList) { + result.append(key.section(':', 1, 1)); + result.append(';'); + } + } + emit importKeyframes(type, result); + delete d; +} + diff --git a/src/customtrackview.h b/src/customtrackview.h index 0c950b54..240d5f19 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -300,6 +300,7 @@ public slots: void updateSnapPoints(AbstractClipItem *selected, QList offsetList = QList (), bool skipSelectedItems = false); void slotAddEffect(ClipItem *clip, QDomElement effect); + void slotImportClipKeyframes(GRAPHICSRECTITEM type); protected: virtual void drawBackground(QPainter * painter, const QRectF & rect); @@ -525,6 +526,8 @@ signals: void updateTrackEffectState(int); /** @brief Cursor position changed, repaint ruler.*/ void updateRuler(); + /** @brief Send data from a clip to be imported as keyframes for effect / transition.*/ + void importKeyframes(GRAPHICSRECTITEM type, const QString&); }; #endif diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 693e4ecc..d278eeca 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -73,6 +73,12 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin } } + if (xml.hasAttribute("analysisdata")) { + QStringList adata = xml.attribute("analysisdata").split('#', QString::SkipEmptyParts); + for (int i = 0; i < adata.count(); i++) + m_analysisdata.insert(adata.at(i).section('?', 0, 0), adata.at(i).section('?', 1, 1)); + } + KUrl url = KUrl(xml.attribute("resource")); if (!m_properties.contains("file_hash") && !url.isEmpty()) getFileHash(url.path()); @@ -255,6 +261,16 @@ QDomElement DocClipBase::toXML(bool hideTemporaryProperties) const } clip.setAttribute("cutzones", cuts.join(";")); } + QString adata; + if (!m_analysisdata.isEmpty()) { + QMapIterator i(m_analysisdata); + while (i.hasNext()) { + i.next(); + //WARNING: a ? and # separator is not a good idea + adata.append(i.key() + "?" + i.value() + "#"); + } + } + clip.setAttribute("analysisdata", adata); //kDebug() << "/// CLIP XML: " << doc.toString(); return doc.documentElement(); } diff --git a/src/effectstack/collapsibleeffect.cpp b/src/effectstack/collapsibleeffect.cpp index 5d953f19..7ca82375 100644 --- a/src/effectstack/collapsibleeffect.cpp +++ b/src/effectstack/collapsibleeffect.cpp @@ -460,6 +460,7 @@ void CollapsibleEffect::setupWidget(ItemInfo info, EffectMetaInfo *metaInfo) connect (this, SIGNAL(syncEffectsPos(int)), m_paramWidget, SIGNAL(syncEffectsPos(int))); connect (m_paramWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int))); connect (m_paramWidget, SIGNAL(seekTimeline(int)), this, SIGNAL(seekTimeline(int))); + connect(m_paramWidget, SIGNAL(importClipKeyframes()), this, SIGNAL(importClipKeyframes())); } diff --git a/src/effectstack/collapsibleeffect.h b/src/effectstack/collapsibleeffect.h index 45398f27..54daa70b 100644 --- a/src/effectstack/collapsibleeffect.h +++ b/src/effectstack/collapsibleeffect.h @@ -137,6 +137,7 @@ signals: void unGroup(CollapsibleEffect *); void createRegion(int, KUrl); void deleteGroup(QDomDocument); + void importClipKeyframes(); }; diff --git a/src/effectstack/effectstackview2.cpp b/src/effectstack/effectstackview2.cpp index f33ecc6c..7366b753 100644 --- a/src/effectstack/effectstackview2.cpp +++ b/src/effectstack/effectstackview2.cpp @@ -284,6 +284,7 @@ void EffectStackView2::connectEffect(CollapsibleEffect *currentEffect) connect(currentEffect, SIGNAL(addEffect(QDomElement)), this , SLOT(slotAddEffect(QDomElement))); connect(currentEffect, SIGNAL(createRegion(int,KUrl)), this, SLOT(slotCreateRegion(int,KUrl))); connect(currentEffect, SIGNAL(deleteGroup(QDomDocument)), this , SLOT(slotDeleteGroup(QDomDocument))); + connect(currentEffect, SIGNAL(importClipKeyframes()), this, SIGNAL(importClipKeyframes())); } void EffectStackView2::slotCheckWheelEventFilter() diff --git a/src/effectstack/effectstackview2.h b/src/effectstack/effectstackview2.h index 4ce9580f..6c878505 100644 --- a/src/effectstack/effectstackview2.h +++ b/src/effectstack/effectstackview2.h @@ -225,6 +225,7 @@ signals: void showComments(bool show); void startFilterJob(ItemInfo info, const QString &clipId, const QString &filterName, const QString &filterParams, const QString&finalFilterName, const QString &consumer, const QString &consumerParams, const QStringList &extraParams); void addEffect(ClipItem*,QDomElement); + void importClipKeyframes(GRAPHICSRECTITEM = AVWIDGET); }; #endif diff --git a/src/effectstack/parametercontainer.cpp b/src/effectstack/parametercontainer.cpp index 9aaf36c1..9dd041f0 100644 --- a/src/effectstack/parametercontainer.cpp +++ b/src/effectstack/parametercontainer.cpp @@ -226,6 +226,7 @@ ParameterContainer::ParameterContainer(QDomElement effect, ItemInfo info, Effect m_vbox->addWidget(m_geometryWidget); m_valueItems[paramName+"geometry"] = m_geometryWidget; connect(m_geometryWidget, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int))); + connect(m_geometryWidget, SIGNAL(importClipKeyframes()), this, SIGNAL(importClipKeyframes())); connect(this, SIGNAL(syncEffectsPos(int)), m_geometryWidget, SLOT(slotSyncPosition(int))); } else { Geometryval *geo = new Geometryval(m_metaInfo->profile, m_metaInfo->timecode, m_metaInfo->frameSize, 0); @@ -844,3 +845,14 @@ bool ParameterContainer::needsMonitorEffectScene() const { return m_needsMonitorEffectScene; } + +void ParameterContainer::setKeyframes(const QString &data) +{ + if (!m_geometryWidget) { + kDebug()<<" / / NO GEOMETRY WIDGET FOUND FOR IMPORTING DATA"; + return; + } + m_geometryWidget->importKeyframes(data); + +} + diff --git a/src/effectstack/parametercontainer.h b/src/effectstack/parametercontainer.h index ae286af8..178180dc 100644 --- a/src/effectstack/parametercontainer.h +++ b/src/effectstack/parametercontainer.h @@ -66,6 +66,8 @@ public: void updateParameter(const QString &key, const QString &value); /** @brief Returns true of this effect requires an on monitor adjustable effect scene. */ bool needsMonitorEffectScene() const; + /** @brief Set keyframes for this param. */ + void setKeyframes(const QString &data); private slots: void slotCollectAllParameters(); @@ -103,7 +105,8 @@ signals: void showComments(bool); /** @brief Start an MLT filter job on this clip. */ void startFilterJob(QString filterName, QString filterParams, QString finalFilterName, QString consumer, QString consumerParams, QStringList extra); - + /** @brief Request import of keyframes from clip data. */ + void importClipKeyframes(); }; #endif diff --git a/src/effectstackedit.cpp b/src/effectstackedit.cpp index 2dec16e1..cc4212fd 100644 --- a/src/effectstackedit.cpp +++ b/src/effectstackedit.cpp @@ -152,11 +152,12 @@ void EffectStackEdit::transferParamDesc(const QDomElement &d, ItemInfo info, boo m_paramWidget = new ParameterContainer(d, info, &m_metaInfo, m_baseWidget); connect (m_paramWidget, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int))); - connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QString,QStringList)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QString,QStringList))); + connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList))); connect (this, SIGNAL(syncEffectsPos(int)), m_paramWidget, SIGNAL(syncEffectsPos(int))); connect (m_paramWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int))); connect (m_paramWidget, SIGNAL(seekTimeline(int)), this, SIGNAL(seekTimeline(int))); + connect (m_paramWidget, SIGNAL(importClipKeyframes()), this, SIGNAL(importClipKeyframes())); Q_FOREACH( QSpinBox * sp, m_baseWidget->findChildren() ) { sp->installEventFilter( this ); @@ -183,4 +184,9 @@ bool EffectStackEdit::needsMonitorEffectScene() const return m_paramWidget->needsMonitorEffectScene(); } +void EffectStackEdit::setKeyframes(const QString &data) +{ + if (!m_paramWidget) return; + m_paramWidget->setKeyframes(data); +} diff --git a/src/effectstackedit.h b/src/effectstackedit.h index a4e74ff2..3ef8aaa9 100644 --- a/src/effectstackedit.h +++ b/src/effectstackedit.h @@ -56,6 +56,8 @@ public: virtual bool eventFilter( QObject * o, QEvent * e ); /** @brief Returns true if this transition requires an on monitor scene. */ bool needsMonitorEffectScene() const; + /** @brief Set keyframes for this transition. */ + void setKeyframes(const QString &data); private: Monitor *m_monitor; @@ -79,7 +81,8 @@ signals: void showComments(bool show); void effectStateChanged(bool enabled); /** @brief Start an MLT filter job on this clip. */ - void startFilterJob(const QString &filterName, const QString &filterParams, const QString &finalFilterName, const QString &consumer, const QString &consumerParams, const QString &properties, const QStringList&extraParams); + void startFilterJob(const QString &filterName, const QString &filterParams, const QString &finalFilterName, const QString &consumer, const QString &consumerParams, const QStringList&extraParams); + void importClipKeyframes(GRAPHICSRECTITEM = AVWIDGET); }; #endif diff --git a/src/geometrywidget.cpp b/src/geometrywidget.cpp index 0dbd932c..55a23404 100644 --- a/src/geometrywidget.cpp +++ b/src/geometrywidget.cpp @@ -123,7 +123,10 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos, connect(fitToHeight, SIGNAL(triggered()), this, SLOT(slotFitToHeight())); menu->addAction(fitToHeight); menu->addSeparator(); - + QAction *importKeyframes = new QAction(i18n("Import keyframes from clip"), this); + connect(importKeyframes, SIGNAL(triggered()), this, SIGNAL(importClipKeyframes())); + menu->addAction(importKeyframes); + menu->addSeparator(); QAction *alignleft = new QAction(KIcon("kdenlive-align-left"), i18n("Align left"), this); connect(alignleft, SIGNAL(triggered()), this, SLOT(slotMoveLeft())); menu->addAction(alignleft); @@ -731,4 +734,41 @@ void GeometryWidget::slotFitToHeight() updateMonitorGeometry(); } +void GeometryWidget::importKeyframes(const QString &data) +{ + QStringList list = data.split(';', QString::SkipEmptyParts); + QPoint screenSize = m_frameSize; + if (screenSize == QPoint() || screenSize.x() == 0 || screenSize.y() == 0) { + screenSize = QPoint(m_monitor->render->frameRenderWidth(), m_monitor->render->renderHeight()); + } + for (int i = 0; i < list.count(); i++) { + Mlt::GeometryItem item; + QString geom = list.at(i); + if (geom.contains('=')) { + item.frame(geom.section('=', 0, 0).toInt()); + } + geom = geom.section('=', 1); + if (geom.contains('/')) { + item.x(geom.section('/', 0, 0).toDouble()); + item.y(geom.section('/', 1, 1).section(':', 0, 0).toDouble()); + } + else { + item.x(0); + item.y(0); + } + if (geom.contains('x')) { + item.w(geom.section('x', 0, 0).section(':', 1, 1).toDouble()); + item.h(geom.section('x', 1, 1).section(':', 0, 0).toDouble()); + } + else { + item.w(screenSize.x()); + item.h(screenSize.y()); + } + //TODO: opacity + item.mix(100); + m_geometry->insert(item); + } + emit parameterChanged(); +} + #include "geometrywidget.moc" diff --git a/src/geometrywidget.h b/src/geometrywidget.h index 64cb02aa..df26b9c4 100644 --- a/src/geometrywidget.h +++ b/src/geometrywidget.h @@ -56,8 +56,8 @@ public: void updateTimecodeFormat(); /** @brief Sets the size of the original clip. */ void setFrameSize(QPoint size); - void addParameter(const QDomElement elem); + void importKeyframes(const QString &data); public slots: /** @brief Sets up the rect and the geometry object. @@ -172,6 +172,7 @@ private slots: signals: void parameterChanged(); void seekToPos(int); + void importClipKeyframes(); }; #endif diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8f2e0829..31d181f5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2538,6 +2538,8 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); disconnect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), m_activeTimeline->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement))); disconnect(m_transitionConfig, SIGNAL(seekTimeline(int)), m_activeTimeline->projectView() , SLOT(setCursorPos(int))); + disconnect(m_transitionConfig, SIGNAL(importClipKeyframes(GRAPHICSRECTITEM)), m_activeTimeline->projectView() , SLOT(slotImportClipKeyframes(GRAPHICSRECTITEM))); + disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor())); disconnect(m_activeTimeline, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int))); disconnect(m_projectList, SIGNAL(loadingIsOver()), m_activeTimeline->projectView(), SLOT(slotUpdateAllThumbs())); @@ -2564,6 +2566,9 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(trackView, SIGNAL(updateTracksInfo()), this, SLOT(slotUpdateTrackInfo())); connect(trackView, SIGNAL(mousePosition(int)), this, SLOT(slotUpdateMousePosition(int))); connect(trackView->projectView(), SIGNAL(forceClipProcessing(const QString &)), m_projectList, SLOT(slotForceProcessing(const QString &))); + + connect(trackView->projectView(), SIGNAL(importKeyframes(GRAPHICSRECTITEM, const QString&)), this, SLOT(slotProcessImportKeyframes(GRAPHICSRECTITEM, const QString&))); + connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int))); connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), trackView, SLOT(slotSetZone(QPoint))); connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), doc, SLOT(setModified())); @@ -2611,13 +2616,16 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_effectStack, SIGNAL(addEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotAddEffect(ClipItem*, QDomElement))); connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, QList , bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, QList , bool))); connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, QList , int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, QList , int))); + connect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*))); - connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(seekCursorPos(int))); + connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView(), SLOT(seekCursorPos(int))); + connect(m_effectStack, SIGNAL(importClipKeyframes(GRAPHICSRECTITEM)), trackView->projectView(), SLOT(slotImportClipKeyframes(GRAPHICSRECTITEM))); connect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects())); connect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); // Transition config signals connect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement))); + connect(m_transitionConfig, SIGNAL(importClipKeyframes(GRAPHICSRECTITEM)), trackView->projectView() , SLOT(slotImportClipKeyframes(GRAPHICSRECTITEM))); connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(seekCursorPos(int))); connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor())); @@ -4557,6 +4565,20 @@ void MainWindow::slotSaveTimelineClip() } } +void MainWindow::slotProcessImportKeyframes(GRAPHICSRECTITEM type, const QString& data) +{ + if (type == AVWIDGET) { + // This data should be sent to the effect stack + } + else if (type == TRANSITIONWIDGET) { + // This data should be sent to the transition stack + m_transitionConfig->setKeyframes(data); + } + else { + // Error + } +} + #include "mainwindow.moc" diff --git a/src/mainwindow.h b/src/mainwindow.h index c7c6c83b..4833d77b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -566,6 +566,8 @@ private slots: void slotChangePalette(); /** @brief Save current timeline clip as mlt playlist. */ void slotSaveTimelineClip(); + /** @brief Process keyframe data sent from a clip to effect / transition stack. */ + void slotProcessImportKeyframes(GRAPHICSRECTITEM type, const QString& data); signals: Q_SCRIPTABLE void abortRenderJob(const QString &url); diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 319a1524..8bc65c36 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -3489,7 +3489,7 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c // We want to cut scenes extraParams << "cutscenes"; } - + delete d; processClipJob(ids, QString(), false, jobParams, i18n("Auto split"), extraParams); } else { @@ -3612,14 +3612,15 @@ void ProjectList::slotGotFilterJobResults(QString id, int , int , QString filter } } if (returnKey.isEmpty()) { - emit displayMessage(i18n("No data returned from clip analysis"), 2); + emit displayMessage(i18n("No data returned from clip analysis"), ErrorMessage); return; } QStringList returnData = results.value(returnKey).split(';', QString::SkipEmptyParts); if (returnData.isEmpty()) { - emit displayMessage(i18n("No data returned from clip analysis"), 2); + emit displayMessage(i18n("No data returned from clip analysis"), ErrorMessage); return; } + emit displayMessage(i18n("Processing data analysis"), InformationMessage); bool dataProcessed = false; if (extra.contains("cutscenes")) { // Check if we want to cut scenes from returned data diff --git a/src/transitionsettings.cpp b/src/transitionsettings.cpp index 6a6fe3b7..2f3b9eda 100644 --- a/src/transitionsettings.cpp +++ b/src/transitionsettings.cpp @@ -41,6 +41,8 @@ TransitionSettings::TransitionSettings(Monitor *monitor, QWidget* parent) : vbox1->addWidget(m_effectEdit); frame->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(m_effectEdit, SIGNAL(seekTimeline(int)), this, SLOT(slotSeekTimeline(int))); + connect(m_effectEdit, SIGNAL(importClipKeyframes()), this, SIGNAL(importClipKeyframes())); + setEnabled(false); QList transitionsList; @@ -241,5 +243,9 @@ void TransitionSettings::slotCheckMonitorPosition(int renderPos) } } +void TransitionSettings::setKeyframes(const QString data) +{ + m_effectEdit->setKeyframes(data); +} #include "transitionsettings.moc" diff --git a/src/transitionsettings.h b/src/transitionsettings.h index 0fc869fa..46e6eef0 100644 --- a/src/transitionsettings.h +++ b/src/transitionsettings.h @@ -37,6 +37,7 @@ public: void raiseWindow(QWidget*); void updateProjectFormat(MltVideoProfile profile, Timecode t, const QList info); void updateTimecodeFormat(); + void setKeyframes(const QString data); private: EffectStackEdit *m_effectEdit; @@ -63,6 +64,7 @@ private slots: signals: void transitionUpdated(Transition *, QDomElement); void seekTimeline(int); + void importClipKeyframes(GRAPHICSRECTITEM = TRANSITIONWIDGET); }; #endif diff --git a/src/widgets/importkeyframesdialog_ui.ui b/src/widgets/importkeyframesdialog_ui.ui new file mode 100644 index 00000000..dd057f8f --- /dev/null +++ b/src/widgets/importkeyframesdialog_ui.ui @@ -0,0 +1,111 @@ + + + ImportKeyframesDialog_UI + + + + 0 + 0 + 255 + 115 + + + + Scene Cut + + + + + + Data to import + + + + + + + + 0 + 0 + + + + + + + + Position + + + true + + + + + + + Size + + + + + + + Qt::Vertical + + + + 218 + 2 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + ImportKeyframesDialog_UI + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ImportKeyframesDialog_UI + reject() + + + 316 + 260 + + + 286 + 274 + + + + +