Warning, file /multimedia/kdenlive/src/timeline2/view/dialogs/speeddialog.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2020 Jean-Baptiste Mardelle
0003     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #include "speeddialog.h"
0007 #include "core.h"
0008 #include "effects/effectsrepository.hpp"
0009 #include "ui_clipspeed_ui.h"
0010 #include "widgets/timecodedisplay.h"
0011 
0012 #include <KMessageWidget>
0013 #include <QDebug>
0014 #include <QPushButton>
0015 #include <QtMath>
0016 
0017 SpeedDialog::SpeedDialog(QWidget *parent, double speed, int duration, double minSpeed, double maxSpeed, bool reversed, bool pitch_compensate,
0018                          ClipType::ProducerType clipType)
0019     : QDialog(parent)
0020     , ui(new Ui::ClipSpeed_UI)
0021     , m_durationDisplay(nullptr)
0022     , m_duration(duration)
0023 {
0024     ui->setupUi(this);
0025     setWindowTitle(i18n("Clip Speed"));
0026     ui->speedSpin->setDecimals(2);
0027     ui->speedSpin->setMinimum(minSpeed);
0028     ui->speedSpin->setMaximum(maxSpeed);
0029     ui->speedSlider->setMinimum(0);
0030     ui->speedSlider->setMaximum(100);
0031     ui->speedSlider->setTickInterval(10);
0032     ui->label_dest->setVisible(false);
0033     ui->kurlrequester->setVisible(false);
0034     if (reversed) {
0035         ui->checkBox->setChecked(true);
0036     }
0037     ui->speedSpin->setValue(speed);
0038     ui->speedSlider->setValue(int(qLn(speed) * 12));
0039     ui->pitchCompensate->setChecked(pitch_compensate);
0040     if (!EffectsRepository::get()->exists(QStringLiteral("rbpitch"))) {
0041         ui->pitchCompensate->setEnabled(false);
0042         ui->pitchCompensate->setToolTip(i18n("MLT must be compiled with rubberband library to enable pitch correction"));
0043     }
0044 
0045     // Info widget
0046     if (clipType == ClipType::Playlist || clipType == ClipType::Timeline) {
0047         ui->infoMessage->setText(i18n("Speed effect will render better when used on single high fps clips"));
0048         ui->infoMessage->show();
0049     } else {
0050         ui->infoMessage->hide();
0051     }
0052     ui->speedSpin->setFocus();
0053     ui->speedSpin->selectAll();
0054     if (m_duration > 0) {
0055         ui->durationLayout->addWidget(new QLabel(i18n("Duration"), this));
0056         m_durationDisplay = new TimecodeDisplay(this);
0057         m_durationDisplay->setValue(m_duration);
0058         ui->durationLayout->addWidget(m_durationDisplay);
0059         connect(m_durationDisplay, &TimecodeDisplay::timeCodeEditingFinished, this, [this, speed, minSpeed](int value) {
0060             if (value < 1) {
0061                 value = 1;
0062                 m_durationDisplay->setValue(value);
0063             } else if (value > m_duration * speed / minSpeed) {
0064                 value = int(m_duration * speed / minSpeed);
0065                 m_durationDisplay->setValue(value);
0066             }
0067             double updatedSpeed = speed * m_duration / value;
0068             QSignalBlocker bk(ui->speedSlider);
0069             ui->speedSlider->setValue(int(qLn(updatedSpeed) * 12));
0070             QSignalBlocker bk2(ui->speedSpin);
0071             ui->speedSpin->setValue(updatedSpeed);
0072             checkSpeed(updatedSpeed);
0073         });
0074     }
0075 
0076     connect(ui->speedSpin, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, [&, speed](double value) {
0077         QSignalBlocker bk(ui->speedSlider);
0078         ui->speedSlider->setValue(int(qLn(value) * 12));
0079         if (m_durationDisplay) {
0080             QSignalBlocker bk2(m_durationDisplay);
0081             int dur = qRound(m_duration * std::fabs(speed / value));
0082             qDebug() << "==== CALCULATED SPEED DIALOG DURATION: " << dur;
0083             m_durationDisplay->setValue(dur);
0084         }
0085         ui->buttonBox->button((QDialogButtonBox::Ok))->setEnabled(!qFuzzyIsNull(value));
0086     });
0087     connect(ui->speedSlider, &QSlider::valueChanged, this, [this, speed](int value) {
0088         double res = qExp(value / 12.);
0089         QSignalBlocker bk(ui->speedSpin);
0090         checkSpeed(res);
0091         ui->speedSpin->setValue(res);
0092         if (m_durationDisplay) {
0093             QSignalBlocker bk2(m_durationDisplay);
0094             m_durationDisplay->setValue(qRound(m_duration * std::fabs(speed / res)));
0095         }
0096         ui->buttonBox->button((QDialogButtonBox::Ok))->setEnabled(!qFuzzyIsNull(ui->speedSpin->value()));
0097     });
0098 }
0099 
0100 void SpeedDialog::checkSpeed(double res)
0101 {
0102     if (res < ui->speedSpin->minimum() || res > ui->speedSpin->maximum()) {
0103         ui->infoMessage->setText(res < ui->speedSpin->minimum() ? i18n("Minimum speed is %1", ui->speedSpin->minimum())
0104                                                                 : i18n("Maximum speed is %1", ui->speedSpin->maximum()));
0105         ui->infoMessage->setCloseButtonVisible(true);
0106         ui->infoMessage->setMessageType(KMessageWidget::Warning);
0107         ui->infoMessage->animatedShow();
0108     }
0109 }
0110 
0111 SpeedDialog::~SpeedDialog()
0112 {
0113     delete ui;
0114 }
0115 
0116 double SpeedDialog::getValue() const
0117 {
0118     double val = ui->speedSpin->value();
0119     if (ui->checkBox->checkState() == Qt::Checked) {
0120         val *= -1;
0121     }
0122     return val;
0123 }
0124 
0125 bool SpeedDialog::getPitchCompensate() const
0126 {
0127     return ui->pitchCompensate->isChecked();
0128 }