mirror of
https://invent.kde.org/multimedia/kdenlive
synced 2025-12-06 08:20:01 +01:00
Update "Reverse Clip" Bin job to handle any speed
CCBUG: 368681
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
98
src/project/dialogs/clipspeed.cpp
Normal file
98
src/project/dialogs/clipspeed.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/***************************************************************************
|
||||
* 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();
|
||||
}
|
||||
|
||||
52
src/project/dialogs/clipspeed.h
Normal file
52
src/project/dialogs/clipspeed.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/***************************************************************************
|
||||
* 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
|
||||
|
||||
164
src/ui/clipspeed_ui.ui
Normal file
164
src/ui/clipspeed_ui.ui
Normal file
@@ -0,0 +1,164 @@
|
||||
<?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>
|
||||
Reference in New Issue
Block a user