diff --git a/app/widget/standardcombos/frameratecombobox.h b/app/widget/standardcombos/frameratecombobox.h index b3633655e..fdb6e51ef 100644 --- a/app/widget/standardcombos/frameratecombobox.h +++ b/app/widget/standardcombos/frameratecombobox.h @@ -22,39 +22,172 @@ #define FRAMERATECOMBOBOX_H #include +#include +#include +#include +#include #include "common/rational.h" #include "render/videoparams.h" namespace olive { -class FrameRateComboBox : public QComboBox +class FrameRateComboBox : public QWidget { Q_OBJECT public: FrameRateComboBox(QWidget* parent = nullptr) : - QComboBox(parent) + QWidget(parent) { - foreach (const rational& fr, VideoParams::kSupportedFrameRates) { - this->addItem(VideoParams::FrameRateToString(fr), QVariant::fromValue(fr)); - } + inner_ = new QComboBox(); + + QHBoxLayout* layout = new QHBoxLayout(this); + layout->setSpacing(0); + layout->setMargin(0); + layout->addWidget(inner_); + + RepopulateList(); + + old_index_ = 0; + + connect(inner_, static_cast(&QComboBox::currentIndexChanged), this, &FrameRateComboBox::IndexChanged); } rational GetFrameRate() const { - return this->currentData().value(); + if (inner_->currentIndex() == inner_->count() - 1) { + return custom_rate_; + } else { + return inner_->currentData().value(); + } } void SetFrameRate(const rational& r) { - for (int i=0; icount(); i++) { - if (this->itemData(i).value() == r) { - this->setCurrentIndex(i); - break; + int standard_rates = inner_->count() - 1; + for (int i=0; iitemData(i).value() == r) { + // Set standard frame rate + old_index_ = i; + SetInnerIndexWithoutSignal(i); + return; } } + + // If we're here, set a custom rate + custom_rate_ = r; + old_index_ = inner_->count()-1; + SetInnerIndexWithoutSignal(old_index_); + RepopulateList(); } +signals: + void FrameRateChanged(const rational& frame_rate); + +protected: + virtual void changeEvent(QEvent* event) override + { + QWidget::changeEvent(event); + + if (event->type() == QEvent::LanguageChange) { + RepopulateList(); + } + } + +private slots: + void IndexChanged(int index) + { + if (index == inner_->count() - 1) { + // Custom + QString s; + bool ok; + + if (!custom_rate_.isNull()) { + s = QString::number(custom_rate_.toDouble()); + } + + while (true) { + s = QInputDialog::getText(this, tr("Custom Frame Rate"), tr("Enter custom frame rate:"), + QLineEdit::Normal, s, &ok); + + if (ok) { + rational r; + + // Try converting to double, assuming most users will input frame rates this way + double d = s.toDouble(&ok); + + if (ok) { + // Try converting from double + r = rational::fromDouble(d, &ok); + } else { + // Try converting to rational in case someone formatted that way + r = rational::fromString(s, &ok); + } + + if (ok) { + + custom_rate_ = r; + emit FrameRateChanged(r); + old_index_ = index; + RepopulateList(); + break; + + } else { + // Show message and continue loop + QMessageBox::critical(this, tr("Invalid Input"), tr("Failed to convert \"%1\" to a frame rate.").arg(s)); + } + + } else { + + // User cancelled, revert to original value + SetInnerIndexWithoutSignal(old_index_); + break; + + } + } + } else { + old_index_ = index; + emit FrameRateChanged(GetFrameRate()); + } + } + +private: + void RepopulateList() + { + int temp_index = inner_->currentIndex(); + + inner_->blockSignals(true); + + inner_->clear(); + + foreach (const rational& fr, VideoParams::kSupportedFrameRates) { + inner_->addItem(VideoParams::FrameRateToString(fr), QVariant::fromValue(fr)); + } + + if (custom_rate_.isNull()) { + inner_->addItem(tr("Custom...")); + } else { + inner_->addItem(tr("Custom (%1)").arg(VideoParams::FrameRateToString(custom_rate_))); + } + + inner_->setCurrentIndex(temp_index); + + inner_->blockSignals(false); + } + + void SetInnerIndexWithoutSignal(int index) + { + inner_->blockSignals(true); + inner_->setCurrentIndex(index); + inner_->blockSignals(false); + } + + QComboBox* inner_; + + rational custom_rate_; + + int old_index_; + }; } diff --git a/app/widget/videoparamedit/videoparamedit.cpp b/app/widget/videoparamedit/videoparamedit.cpp index 83f669333..13ddfc825 100644 --- a/app/widget/videoparamedit/videoparamedit.cpp +++ b/app/widget/videoparamedit/videoparamedit.cpp @@ -94,7 +94,7 @@ VideoParamEdit::VideoParamEdit(QWidget* parent) : layout->addWidget(frame_rate_lbl_, row, 0); frame_rate_combobox_ = new FrameRateComboBox(); - connect(frame_rate_combobox_, static_cast(&FrameRateComboBox::currentIndexChanged), this, &VideoParamEdit::Changed); + connect(frame_rate_combobox_, &FrameRateComboBox::FrameRateChanged, this, &VideoParamEdit::Changed); layout->addWidget(frame_rate_combobox_, row, 1); frame_rate_slider_ = new RationalSlider();