citra_qt: Split options into 'Specific' and 'Generic'
For easier usage. Also made the option list sortable.
This commit is contained in:
parent
f3e9780d10
commit
a50ba7192b
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in New Issue