citra_qt: Split options into 'Specific' and 'Generic'

For easier usage. Also made the option list sortable.
This commit is contained in:
zhupengfei 2020-02-28 18:26:20 +08:00
parent f3e9780d10
commit a50ba7192b
No known key found for this signature in database
GPG key ID: DD129E108BD09378
7 changed files with 76 additions and 34 deletions

View file

@ -15,6 +15,9 @@ DumpingDialog::DumpingDialog(QWidget* parent)
ui->setupUi(this); ui->setupUi(this);
format_generic_options = VideoDumper::GetFormatGenericOptions();
encoder_generic_options = VideoDumper::GetEncoderGenericOptions();
connect(ui->pathExplore, &QToolButton::clicked, this, &DumpingDialog::OnToolButtonClicked); connect(ui->pathExplore, &QToolButton::clicked, this, &DumpingDialog::OnToolButtonClicked);
connect(ui->buttonBox, &QDialogButtonBox::accepted, [this] { connect(ui->buttonBox, &QDialogButtonBox::accepted, [this] {
if (ui->pathLineEdit->text().isEmpty()) { if (ui->pathLineEdit->text().isEmpty()) {
@ -27,17 +30,17 @@ DumpingDialog::DumpingDialog(QWidget* parent)
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &DumpingDialog::reject); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &DumpingDialog::reject);
connect(ui->formatOptionsButton, &QToolButton::clicked, [this] { connect(ui->formatOptionsButton, &QToolButton::clicked, [this] {
OpenOptionsDialog(formats.at(ui->formatComboBox->currentData().toUInt()).options, OpenOptionsDialog(formats.at(ui->formatComboBox->currentData().toUInt()).options,
ui->formatOptionsLineEdit); format_generic_options, ui->formatOptionsLineEdit);
}); });
connect(ui->videoEncoderOptionsButton, &QToolButton::clicked, [this] { connect(ui->videoEncoderOptionsButton, &QToolButton::clicked, [this] {
OpenOptionsDialog( OpenOptionsDialog(
video_encoders.at(ui->videoEncoderComboBox->currentData().toUInt()).options, video_encoders.at(ui->videoEncoderComboBox->currentData().toUInt()).options,
ui->videoEncoderOptionsLineEdit); encoder_generic_options, ui->videoEncoderOptionsLineEdit);
}); });
connect(ui->audioEncoderOptionsButton, &QToolButton::clicked, [this] { connect(ui->audioEncoderOptionsButton, &QToolButton::clicked, [this] {
OpenOptionsDialog( OpenOptionsDialog(
audio_encoders.at(ui->audioEncoderComboBox->currentData().toUInt()).options, audio_encoders.at(ui->audioEncoderComboBox->currentData().toUInt()).options,
ui->audioEncoderOptionsLineEdit); encoder_generic_options, ui->audioEncoderOptionsLineEdit);
}); });
SetConfiguration(); SetConfiguration();
@ -177,9 +180,10 @@ void DumpingDialog::OnToolButtonClicked() {
} }
} }
void DumpingDialog::OpenOptionsDialog(const std::vector<VideoDumper::OptionInfo>& options, void DumpingDialog::OpenOptionsDialog(const std::vector<VideoDumper::OptionInfo>& specific_options,
const std::vector<VideoDumper::OptionInfo>& generic_options,
QLineEdit* line_edit) { QLineEdit* line_edit) {
OptionsDialog dialog(this, options, line_edit->text().toStdString()); OptionsDialog dialog(this, specific_options, generic_options, line_edit->text().toStdString());
if (dialog.exec() != QDialog::DialogCode::Accepted) { if (dialog.exec() != QDialog::DialogCode::Accepted) {
return; return;
} }

View file

@ -27,7 +27,8 @@ private:
void PopulateEncoders(); void PopulateEncoders();
void SetConfiguration(); void SetConfiguration();
void OnToolButtonClicked(); void OnToolButtonClicked();
void OpenOptionsDialog(const std::vector<VideoDumper::OptionInfo>& options, void OpenOptionsDialog(const std::vector<VideoDumper::OptionInfo>& specific_options,
const std::vector<VideoDumper::OptionInfo>& generic_options,
QLineEdit* line_edit); QLineEdit* line_edit);
std::unique_ptr<Ui::DumpingDialog> ui; std::unique_ptr<Ui::DumpingDialog> ui;
@ -35,6 +36,8 @@ private:
QString last_path; QString last_path;
std::vector<VideoDumper::FormatInfo> formats; std::vector<VideoDumper::FormatInfo> formats;
std::vector<VideoDumper::OptionInfo> format_generic_options;
std::vector<VideoDumper::EncoderInfo> video_encoders; std::vector<VideoDumper::EncoderInfo> video_encoders;
std::vector<VideoDumper::EncoderInfo> audio_encoders; std::vector<VideoDumper::EncoderInfo> audio_encoders;
std::vector<VideoDumper::OptionInfo> encoder_generic_options;
}; };

View file

@ -9,7 +9,10 @@
constexpr char UNSET_TEXT[] = QT_TR_NOOP("[not set]"); constexpr char UNSET_TEXT[] = QT_TR_NOOP("[not set]");
void OptionsDialog::PopulateOptions(const std::string& current_value) { void OptionsDialog::PopulateOptions() {
const auto& options = ui->specificRadioButton->isChecked() ? specific_options : generic_options;
ui->main->clear();
ui->main->setSortingEnabled(false);
for (std::size_t i = 0; i < options.size(); ++i) { for (std::size_t i = 0; i < options.size(); ++i) {
const auto& option = options.at(i); const auto& option = options.at(i);
auto* item = new QTreeWidgetItem( auto* item = new QTreeWidgetItem(
@ -18,9 +21,13 @@ void OptionsDialog::PopulateOptions(const std::string& current_value) {
item->setData(1, Qt::UserRole, static_cast<unsigned long long>(i)); // ID item->setData(1, Qt::UserRole, static_cast<unsigned long long>(i)); // ID
ui->main->addTopLevelItem(item); ui->main->addTopLevelItem(item);
} }
ui->main->setSortingEnabled(true);
ui->main->sortItems(0, Qt::AscendingOrder);
} }
void OptionsDialog::OnSetOptionValue(int id) { void OptionsDialog::OnSetOptionValue(QTreeWidgetItem* item) {
const auto& options = ui->specificRadioButton->isChecked() ? specific_options : generic_options;
const int id = item->data(1, Qt::UserRole).toInt();
OptionSetDialog dialog(this, options[id], OptionSetDialog dialog(this, options[id],
current_values.Get(options[id].name, options[id].default_value)); current_values.Get(options[id].name, options[id].default_value));
if (dialog.exec() != QDialog::DialogCode::Accepted) { if (dialog.exec() != QDialog::DialogCode::Accepted) {
@ -33,27 +40,29 @@ void OptionsDialog::OnSetOptionValue(int id) {
} else { } else {
current_values.Erase(options[id].name); current_values.Erase(options[id].name);
} }
ui->main->invisibleRootItem()->child(id)->setText(1, is_set ? QString::fromStdString(value) item->setText(1, is_set ? QString::fromStdString(value) : tr(UNSET_TEXT));
: tr(UNSET_TEXT));
} }
std::string OptionsDialog::GetCurrentValue() const { std::string OptionsDialog::GetCurrentValue() const {
return current_values.Serialize(); return current_values.Serialize();
} }
OptionsDialog::OptionsDialog(QWidget* parent, std::vector<VideoDumper::OptionInfo> options_, OptionsDialog::OptionsDialog(QWidget* parent,
std::vector<VideoDumper::OptionInfo> specific_options_,
std::vector<VideoDumper::OptionInfo> generic_options_,
const std::string& current_value) const std::string& current_value)
: QDialog(parent), ui(std::make_unique<Ui::OptionsDialog>()), options(std::move(options_)), : QDialog(parent), ui(std::make_unique<Ui::OptionsDialog>()),
specific_options(std::move(specific_options_)), generic_options(std::move(generic_options_)),
current_values(current_value) { current_values(current_value) {
ui->setupUi(this); ui->setupUi(this);
PopulateOptions(current_value); PopulateOptions();
connect(ui->main, &QTreeWidget::itemDoubleClicked, [this](QTreeWidgetItem* item, int column) { connect(ui->main, &QTreeWidget::itemDoubleClicked,
OnSetOptionValue(item->data(1, Qt::UserRole).toInt()); [this](QTreeWidgetItem* item, int column) { OnSetOptionValue(item); });
});
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &OptionsDialog::accept); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &OptionsDialog::accept);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &OptionsDialog::reject); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &OptionsDialog::reject);
connect(ui->specificRadioButton, &QRadioButton::toggled, this, &OptionsDialog::PopulateOptions);
} }
OptionsDialog::~OptionsDialog() = default; OptionsDialog::~OptionsDialog() = default;

View file

@ -8,6 +8,8 @@
#include "common/param_package.h" #include "common/param_package.h"
#include "core/dumping/ffmpeg_backend.h" #include "core/dumping/ffmpeg_backend.h"
class QTreeWidgetItem;
namespace Ui { namespace Ui {
class OptionsDialog; class OptionsDialog;
} }
@ -16,17 +18,19 @@ class OptionsDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit OptionsDialog(QWidget* parent, std::vector<VideoDumper::OptionInfo> options, explicit OptionsDialog(QWidget* parent, std::vector<VideoDumper::OptionInfo> specific_options,
std::vector<VideoDumper::OptionInfo> generic_options,
const std::string& current_value); const std::string& current_value);
~OptionsDialog() override; ~OptionsDialog() override;
std::string GetCurrentValue() const; std::string GetCurrentValue() const;
private: private:
void PopulateOptions(const std::string& current_value); void PopulateOptions();
void OnSetOptionValue(int id); void OnSetOptionValue(QTreeWidgetItem* item);
std::unique_ptr<Ui::OptionsDialog> ui; std::unique_ptr<Ui::OptionsDialog> ui;
std::vector<VideoDumper::OptionInfo> options; std::vector<VideoDumper::OptionInfo> specific_options;
std::vector<VideoDumper::OptionInfo> generic_options;
Common::ParamPackage current_values; Common::ParamPackage current_values;
}; };

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>600</width> <width>650</width>
<height>300</height> <height>350</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -24,6 +24,27 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QRadioButton" name="specificRadioButton">
<property name="text">
<string>Specific</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="genericRadioButton">
<property name="text">
<string>Generic</string>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QTreeWidget" name="main"> <widget class="QTreeWidget" name="main">
<column> <column>

View file

@ -754,8 +754,6 @@ std::vector<OptionInfo> GetOptionList(const AVClass* av_class, bool search_child
std::vector<EncoderInfo> ListEncoders(AVMediaType type) { std::vector<EncoderInfo> ListEncoders(AVMediaType type) {
InitializeFFmpegLibraries(); InitializeFFmpegLibraries();
const auto general_options = GetOptionList(avcodec_get_class(), false);
std::vector<EncoderInfo> out; std::vector<EncoderInfo> out;
const AVCodec* current = nullptr; const AVCodec* current = nullptr;
@ -768,19 +766,19 @@ std::vector<EncoderInfo> ListEncoders(AVMediaType type) {
if (!av_codec_is_encoder(current) || current->type != type) { if (!av_codec_is_encoder(current) || current->type != type) {
continue; continue;
} }
auto options = GetOptionList(current->priv_class, true); out.push_back({current->name, ToStdString(current->long_name), current->id,
options.insert(options.end(), general_options.begin(), general_options.end()); GetOptionList(current->priv_class, true)});
out.push_back(
{current->name, ToStdString(current->long_name), current->id, std::move(options)});
} }
return out; return out;
} }
std::vector<OptionInfo> GetEncoderGenericOptions() {
return GetOptionList(avcodec_get_class(), false);
}
std::vector<FormatInfo> ListFormats() { std::vector<FormatInfo> ListFormats() {
InitializeFFmpegLibraries(); InitializeFFmpegLibraries();
const auto general_options = GetOptionList(avformat_get_class(), false);
std::vector<FormatInfo> out; std::vector<FormatInfo> out;
const AVOutputFormat* current = nullptr; const AVOutputFormat* current = nullptr;
@ -790,9 +788,6 @@ std::vector<FormatInfo> ListFormats() {
void* data = nullptr; // For libavformat to save the iteration state void* data = nullptr; // For libavformat to save the iteration state
while ((current = av_muxer_iterate(&data))) { while ((current = av_muxer_iterate(&data))) {
#endif #endif
auto options = GetOptionList(current->priv_class, true);
options.insert(options.end(), general_options.begin(), general_options.end());
std::vector<std::string> extensions; std::vector<std::string> extensions;
Common::SplitString(ToStdString(current->extensions), ',', extensions); Common::SplitString(ToStdString(current->extensions), ',', extensions);
@ -816,9 +811,13 @@ std::vector<FormatInfo> ListFormats() {
out.push_back({current->name, ToStdString(current->long_name), std::move(extensions), out.push_back({current->name, ToStdString(current->long_name), std::move(extensions),
std::move(supported_video_codecs), std::move(supported_audio_codecs), std::move(supported_video_codecs), std::move(supported_audio_codecs),
std::move(options)}); GetOptionList(current->priv_class, true)});
} }
return out; return out;
} }
std::vector<OptionInfo> GetFormatGenericOptions() {
return GetOptionList(avformat_get_class(), false);
}
} // namespace VideoDumper } // namespace VideoDumper

View file

@ -227,6 +227,8 @@ struct FormatInfo {
}; };
std::vector<EncoderInfo> ListEncoders(AVMediaType type); std::vector<EncoderInfo> ListEncoders(AVMediaType type);
std::vector<OptionInfo> GetEncoderGenericOptions();
std::vector<FormatInfo> ListFormats(); std::vector<FormatInfo> ListFormats();
std::vector<OptionInfo> GetFormatGenericOptions();
} // namespace VideoDumper } // namespace VideoDumper