Commit cee1588f authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Update "Reverse Clip" Bin job to handle any speed

CCBUG: 368681
parent 6a6ad374
......@@ -205,6 +205,7 @@ ki18n_wrap_ui(kdenlive_UIS
ui/scenecutdialog_ui.ui
ui/gradientedit_ui.ui
ui/selectivecolor_ui.ui
ui/clipspeed_ui.ui
)
if(BUILD_JogShuttle)
......
......@@ -3057,7 +3057,7 @@ void MainWindow::buildDynamicActions()
delete filter;
}
if (KdenliveSettings::producerslist().contains(QStringLiteral("timewarp"))) {
QAction *action = new QAction(i18n("Reverse clip"), m_extraFactory->actionCollection());
QAction *action = new QAction(i18n("Duplicate clip with speed change"), m_extraFactory->actionCollection());
QStringList stabJob;
stabJob << QString::number((int) AbstractClipJob::FILTERCLIPJOB) << QStringLiteral("timewarp");
action->setData(stabJob);
......
......@@ -7,5 +7,6 @@ set(kdenlive_SRCS
project/dialogs/slideshowclip.cpp
project/dialogs/temporarydata.cpp
project/dialogs/profilewidget.cpp
project/dialogs/clipspeed.cpp
PARENT_SCOPE)
/***************************************************************************
* Copyright (C) 2016 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "clipspeed.h"
#include "kdenlivesettings.h"
#include "utils/KoIconUtils.h"
#include <klocalizedstring.h>
#include <QFontDatabase>
#include <QStandardPaths>
#include <KUrlRequester>
#include <QMenu>
ClipSpeed::ClipSpeed(const QUrl &destination, bool isDirectory, QWidget * parent) :
QDialog(parent)
{
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
m_view.setupUi(this);
setWindowTitle(i18n("Create clip with speed"));
if (isDirectory) {
m_view.kurlrequester->setMode(KFile::Directory);
} else {
m_view.kurlrequester->setMode(KFile::File);
}
m_view.kurlrequester->setUrl(destination);
m_view.toolButton->setIcon(KoIconUtils::themedIcon("kdenlive-menu"));
QMenu *settingsMenu = new QMenu(this);
m_view.toolButton->setMenu(settingsMenu);
QAction *a = settingsMenu->addAction(i18n("Reverse clip"));
a->setData(-100);
a = settingsMenu->addAction(i18n("25%"));
a->setData(25);
a = settingsMenu->addAction(i18n("50%"));
a->setData(50);
a = settingsMenu->addAction(i18n("200%"));
a->setData(200);
a = settingsMenu->addAction(i18n("400%"));
a->setData(400);
connect(settingsMenu, &QMenu::triggered, this, &ClipSpeed::adjustSpeed);
connect(m_view.speedSlider, &QSlider::valueChanged, this, &ClipSpeed::slotUpdateSpeed);
connect(m_view.speedSpin, SIGNAL(valueChanged(double)), this, SLOT(slotUpdateSlider(double)));
}
void ClipSpeed::slotUpdateSlider(double speed)
{
m_view.speedSlider->blockSignals(true);
m_view.speedSlider->setValue((int) speed);
m_view.speedSlider->blockSignals(false);
m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(speed != 0.0);
}
void ClipSpeed::slotUpdateSpeed(int speed)
{
m_view.speedSpin->blockSignals(true);
m_view.speedSpin->setValue((double) speed);
m_view.speedSpin->blockSignals(false);
}
QUrl ClipSpeed::selectedUrl() const
{
return m_view.kurlrequester->url();
}
void ClipSpeed::adjustSpeed(QAction *a)
{
if (!a)
return;
int speed = a->data().toInt();
m_view.speedSlider->blockSignals(true);
m_view.speedSpin->blockSignals(true);
m_view.speedSpin->setValue((double) speed);
m_view.speedSlider->setValue(speed);
m_view.speedSlider->blockSignals(false);
m_view.speedSpin->blockSignals(false);
}
double ClipSpeed::speed() const
{
return m_view.speedSpin->value();
}
/***************************************************************************
* Copyright (C) 2016 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef CLIPSPEED_H
#define CLIPSPEED_H
#include "ui_clipspeed_ui.h"
#include <QDialog>
/**
* @class ClipSpeed
* @brief A dialog allowing to set a destination and a new speed to create an MLT file from a clip.
*/
class ClipSpeed : public QDialog
{
Q_OBJECT
public:
explicit ClipSpeed(const QUrl &destination, bool isDirectory, QWidget * parent = 0);
QUrl selectedUrl() const;
double speed() const;
private slots:
void slotUpdateSlider(double);
void slotUpdateSpeed(int);
void adjustSpeed(QAction *a);
private:
Ui::ClipSpeed_UI m_view;
};
#endif
......@@ -38,8 +38,8 @@ SlideshowClip::SlideshowClip(const Timecode &tc, QString clipFolder, ProjectClip
m_thumbJob(NULL)
{
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
setWindowTitle(i18n("Add Slideshow Clip"));
m_view.setupUi(this);
setWindowTitle(i18n("Add Slideshow Clip"));
if (clip) {
m_view.clip_name->setText(clip->name());
m_view.groupBox->setHidden(true);
......
......@@ -24,12 +24,13 @@
#include "doc/kdenlivedoc.h"
#include "bin/projectclip.h"
#include "project/clipstabilize.h"
#include "project/dialogs/clipspeed.h"
#include "ui_scenecutdialog_ui.h"
#include <QDebug>
#include <QUrl>
#include <klocalizedstring.h>
#include <KMessageBox>
#include <mlt++/Mlt.h>
// static
......@@ -75,16 +76,36 @@ QHash <ProjectClip *, AbstractClipJob *> FilterJob::prepareJob(QList <ProjectCli
extraParams.insert(QStringLiteral("projecttreefilter"), QStringLiteral("1"));
// Reverse clip using project profile since playlists can only be included with same fps
// extraParams.insert(QStringLiteral("producer_profile"), QStringLiteral("1"));
bool multipleSelection = clips.count() > 1;
QPointer<ClipSpeed> d = new ClipSpeed(clips.count() == 1 ? QUrl::fromLocalFile(sources.first() + QStringLiteral(".mlt")) : QUrl::fromLocalFile(sources.first()).adjusted(QUrl::RemoveFilename), multipleSelection, QApplication::activeWindow());
if (d->exec() == QDialog::Accepted) {
QLocale locale;
QString speedString = QString("timewarp:%1:").arg(locale.toString(d->speed()/100));
QDir destFolder;
if (multipleSelection) {
destFolder = QDir(d->selectedUrl().path());
}
for (int i = 0; i < clips.count(); i++) {
QString prodstring = QString("timewarp:-1:" + sources.at(i));
QString prodstring = speedString + sources.at(i);
producerParams.insert(QStringLiteral("producer"), prodstring);
consumerParams.insert(QStringLiteral("consumer"), "xml:" + sources.at(i) + ".mlt");
QString destination;
if (multipleSelection) {
destination = destFolder.absoluteFilePath(QUrl::fromLocalFile(sources.at(i)).fileName());
} else {
destination = d->selectedUrl().path();
}
if (QFile::exists(destination)) {
if (KMessageBox::questionYesNo(QApplication::activeWindow(), i18n("File %1 already exists.\nDo you want to overwrite it?", destination)) != KMessageBox::Yes) continue;
}
consumerParams.insert(QStringLiteral("consumer"), "xml:" + destination);
ProjectClip *clip = clips.at(i);
MeltJob *job = new MeltJob(clip->clipType(), clip->clipId(), producerParams, filterParams, consumerParams, extraParams);
job->description = i18n("Reverse clip");
job->setAddClipToProject(true);
jobs.insert(clip, job);
}
}
delete d;
return jobs;
} else if (filterName == QLatin1String("motion_est")) {
// Show config dialog
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ClipSpeed_UI</class>
<widget class="QDialog" name="ClipSpeed_UI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>498</width>
<height>158</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_dest">
<property name="text">
<string>Destination</string>
</property>
</widget>
</item>
<item>
<widget class="KUrlRequester" name="kurlrequester">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Speed</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="speedSlider">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="sliderPosition">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>50</number>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="speedSpin">
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<double>-20000.000000000000000</double>
</property>
<property name="maximum">
<double>20000.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string>...</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KUrlRequester</class>
<extends>QWidget</extends>
<header>kurlrequester.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ClipSpeed_UI</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ClipSpeed_UI</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Supports Markdown
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