// Copyright 2020 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include #include #include "citra_qt/dumping/dumping_dialog.h" #include "citra_qt/dumping/options_dialog.h" #include "citra_qt/uisettings.h" #include "core/settings.h" #include "ui_dumping_dialog.h" DumpingDialog::DumpingDialog(QWidget* parent) : QDialog(parent), ui(std::make_unique()) { ui->setupUi(this); connect(ui->pathExplore, &QToolButton::clicked, this, &DumpingDialog::OnToolButtonClicked); connect(ui->buttonBox, &QDialogButtonBox::accepted, [this] { ApplyConfiguration(); accept(); }); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &DumpingDialog::reject); connect(ui->formatOptionsButton, &QPushButton::clicked, [this] { OpenOptionsDialog(formats.at(ui->formatComboBox->currentData().toUInt()).options, format_options); }); connect(ui->videoEncoderOptionsButton, &QPushButton::clicked, [this] { OpenOptionsDialog( video_encoders.at(ui->videoEncoderComboBox->currentData().toUInt()).options, video_encoder_options); }); connect(ui->audioEncoderOptionsButton, &QPushButton::clicked, [this] { OpenOptionsDialog( audio_encoders.at(ui->audioEncoderComboBox->currentData().toUInt()).options, audio_encoder_options); }); SetConfiguration(); connect(ui->formatComboBox, qOverload(&QComboBox::currentIndexChanged), [this] { ui->pathLineEdit->setText(QString{}); format_options.clear(); PopulateEncoders(); }); connect(ui->videoEncoderComboBox, qOverload(&QComboBox::currentIndexChanged), [this] { video_encoder_options.clear(); }); connect(ui->audioEncoderComboBox, qOverload(&QComboBox::currentIndexChanged), [this] { audio_encoder_options.clear(); }); } DumpingDialog::~DumpingDialog() = default; QString DumpingDialog::GetFilePath() const { return ui->pathLineEdit->text(); } void DumpingDialog::Populate() { formats = VideoDumper::ListFormats(); video_encoders = VideoDumper::ListEncoders(AVMEDIA_TYPE_VIDEO); audio_encoders = VideoDumper::ListEncoders(AVMEDIA_TYPE_AUDIO); // Check that these are not empty QString missing; if (formats.empty()) { missing = tr("output formats"); } if (video_encoders.empty()) { missing = tr("video encoders"); } if (audio_encoders.empty()) { missing = tr("audio encoders"); } if (!missing.isEmpty()) { QMessageBox::critical(this, tr("Citra"), tr("Could not find any available %1.\nPlease check your FFmpeg " "installation used for compilation.") .arg(missing)); reject(); return; } // Populate formats for (std::size_t i = 0; i < formats.size(); ++i) { const auto& format = formats[i]; // Check format: only formats that have video encoders and audio encoders are displayed bool has_video = false; for (const auto& video_encoder : video_encoders) { if (format.supported_video_codecs.count(video_encoder.codec)) { has_video = true; break; } } if (!has_video) continue; bool has_audio = false; for (const auto& audio_encoder : audio_encoders) { if (format.supported_audio_codecs.count(audio_encoder.codec)) { has_audio = true; break; } } if (!has_audio) continue; ui->formatComboBox->addItem(tr("%1 (%2)").arg(QString::fromStdString(format.long_name), QString::fromStdString(format.name)), static_cast(i)); if (format.name == Settings::values.output_format) { ui->formatComboBox->setCurrentIndex(ui->formatComboBox->count() - 1); } } PopulateEncoders(); } void DumpingDialog::PopulateEncoders() { const auto& format = formats.at(ui->formatComboBox->currentData().toUInt()); ui->videoEncoderComboBox->clear(); for (std::size_t i = 0; i < video_encoders.size(); ++i) { const auto& video_encoder = video_encoders[i]; if (!format.supported_video_codecs.count(video_encoder.codec)) { continue; } ui->videoEncoderComboBox->addItem( tr("%1 (%2)").arg(QString::fromStdString(video_encoder.long_name), QString::fromStdString(video_encoder.name)), static_cast(i)); if (video_encoder.name == Settings::values.video_encoder) { ui->videoEncoderComboBox->setCurrentIndex(ui->videoEncoderComboBox->count() - 1); } } ui->audioEncoderComboBox->clear(); for (std::size_t i = 0; i < audio_encoders.size(); ++i) { const auto& audio_encoder = audio_encoders[i]; if (!format.supported_audio_codecs.count(audio_encoder.codec)) { continue; } ui->audioEncoderComboBox->addItem( tr("%1 (%2)").arg(QString::fromStdString(audio_encoder.long_name), QString::fromStdString(audio_encoder.name)), static_cast(i)); if (audio_encoder.name == Settings::values.audio_encoder) { ui->audioEncoderComboBox->setCurrentIndex(ui->audioEncoderComboBox->count() - 1); } } } void DumpingDialog::OnToolButtonClicked() { const auto& format = formats.at(ui->formatComboBox->currentData().toUInt()); QString extensions; for (const auto& ext : format.extensions) { if (!extensions.isEmpty()) { extensions.append(QLatin1Char{' '}); } extensions.append(QStringLiteral("*.%1").arg(QString::fromStdString(ext))); } const auto path = QFileDialog::getSaveFileName( this, tr("Select Video Output Path"), last_path, tr("%1 (%2)").arg(QString::fromStdString(format.long_name), extensions)); if (!path.isEmpty()) { last_path = QFileInfo(ui->pathLineEdit->text()).path(); ui->pathLineEdit->setText(path); } } void DumpingDialog::OpenOptionsDialog(const std::vector& options, std::string& current_value) { OptionsDialog dialog(this, options, current_value); if (dialog.exec() != QDialog::DialogCode::Accepted) { return; } current_value = dialog.GetCurrentValue(); } void DumpingDialog::SetConfiguration() { Populate(); format_options = Settings::values.format_options; video_encoder_options = Settings::values.video_encoder_options; audio_encoder_options = Settings::values.audio_encoder_options; last_path = UISettings::values.video_dumping_path; ui->videoBitrateSpinBox->setValue(static_cast(Settings::values.video_bitrate)); ui->audioBitrateSpinBox->setValue(static_cast(Settings::values.audio_bitrate)); } void DumpingDialog::ApplyConfiguration() { Settings::values.output_format = formats.at(ui->formatComboBox->currentData().toUInt()).name; Settings::values.format_options = format_options; Settings::values.video_encoder = video_encoders.at(ui->videoEncoderComboBox->currentData().toUInt()).name; Settings::values.video_encoder_options = video_encoder_options; Settings::values.video_bitrate = ui->videoBitrateSpinBox->value(); Settings::values.audio_encoder = audio_encoders.at(ui->audioEncoderComboBox->currentData().toUInt()).name; Settings::values.audio_encoder_options = audio_encoder_options; Settings::values.audio_bitrate = ui->audioBitrateSpinBox->value(); UISettings::values.video_dumping_path = last_path; Settings::Apply(); }