#include "configurationEditDialog.h" #include "configuration.h" #include "mandatoryLineEdit.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ui_configuration_edit_dialog.h" constexpr char SETTINGS_CFG_DIALOG[] = "ConfigurationEditDialog"; constexpr char SETTINGS_CFG_LAST_GEOMETRY[] = "geometry"; constexpr int GLOBAL_SETTINGS_GAME_DIRS_MIN_WIDTH = 560; const QStringList CONSOLE_LANGUAGE_NAMES = { "Japanese", "English (United States)", "French (France)", "Spanish (Spain)", "German", "Italian", "Dutch", "Portuguese (Portugal)", "Russian", "Korean", "Chinese (Traditional)", "Chinese (Simplified)", "Finnish", "Swedish", "Danish", "Norwegian", "Polish", "Portuguese (Brazil)", "English (United Kingdom)", "Turkish", "Spanish (Latin America)", "Arabic", "French (Canada)", "Czech", "Hungarian", "Greek", "Romanian", "Thai", "Vietnamese", "Indonesian", }; static QString NormalizeGameDirectory(const QString& dir) { const auto trimmed = dir.trimmed(); if (trimmed.isEmpty()) { return {}; } return QDir::cleanPath(QDir(trimmed).absolutePath()); } static QString GameDirectoryKey(const QString& dir) { const auto normalized = NormalizeGameDirectory(dir); if (normalized.isEmpty()) { return {}; } auto canonical = QFileInfo(normalized).canonicalFilePath(); if (canonical.isEmpty()) { canonical = normalized; } canonical = QDir::cleanPath(canonical); #ifdef __linux__ return canonical; #else return canonical.toCaseFolded(); #endif } ConfigurationEditDialog::ConfigurationEditDialog(Configuration& info, QWidget* parent) : QDialog(parent, Qt::WindowCloseButtonHint), m_ui(new Ui::ConfigurationEditDialog), m_info(info) { m_ui->setupUi(this); InitGameDirectories(); connect(m_ui->ok_button, &QPushButton::clicked, this, &ConfigurationEditDialog::save); connect(m_ui->clear_button, &QPushButton::clicked, this, &ConfigurationEditDialog::clear); connect(m_ui->comboBox_shader_log_direction, &QComboBox::currentTextChanged, this, [this](const QString& text) { auto log = TextToEnum(text); m_ui->lineEdit_shader_log_folder->setEnabled( log == Configuration::ShaderLogDirection::File); }); connect(m_ui->checkBox_cmd_dump, &QCheckBox::toggled, this, [this](bool flag) { m_ui->lineEdit_cmd_dump_folder->setEnabled(flag); }); connect(m_ui->comboBox_printf_direction, &QComboBox::currentTextChanged, this, [this](const QString& text) { auto log = TextToEnum(text); m_ui->lineEdit_printf_file->setEnabled(log == Configuration::LogDirection::File); }); layout()->setSizeConstraint(QLayout::SetFixedSize); restoreGeometry(g_last_geometry); Init(info); } QByteArray ConfigurationEditDialog::g_last_geometry; ConfigurationEditDialog::~ConfigurationEditDialog() { delete m_ui; } void ConfigurationEditDialog::WriteSettings(QSettings& s) { s.beginGroup(SETTINGS_CFG_DIALOG); if (!g_last_geometry.isEmpty()) { s.setValue(SETTINGS_CFG_LAST_GEOMETRY, g_last_geometry); } s.endGroup(); } void ConfigurationEditDialog::ReadSettings(QSettings& s) { s.beginGroup(SETTINGS_CFG_DIALOG); g_last_geometry = s.value(SETTINGS_CFG_LAST_GEOMETRY, g_last_geometry).toByteArray(); s.endGroup(); } template static void ListInit(QComboBox* combo, T value) { combo->clear(); combo->addItems(EnumToList()); combo->setCurrentText(EnumToText(value)); } void ConfigurationEditDialog::Init(const Configuration& info) { ListInit(m_ui->comboBox_screen_resolution, info.screen_resolution); m_ui->checkBox_fullscreen->setChecked(info.fullscreen_enabled); m_ui->spinBox_vblank_frequency->setValue(info.vblank_frequency); m_ui->comboBox_console_language->clear(); m_ui->comboBox_console_language->addItems(CONSOLE_LANGUAGE_NAMES); m_ui->comboBox_console_language->setCurrentIndex( info.console_language >= 0 && info.console_language < CONSOLE_LANGUAGE_NAMES.size() ? info.console_language : Configuration::DEFAULT_CONSOLE_LANGUAGE); m_ui->checkBox_shader_validation->setChecked(info.shader_validation_enabled); m_ui->checkBox_vulkan_validation->setChecked(info.vulkan_validation_enabled); m_ui->checkBox_renderdoc_capture->setChecked(info.renderdoc_enabled); #if defined(_WIN32) m_ui->checkBox_red_zone_protection->setChecked(info.red_zone_protection_enabled); #else m_ui->checkBox_red_zone_protection->setVisible(false); #endif ListInit(m_ui->comboBox_shader_optimization_type, info.shader_optimization_type); ListInit(m_ui->comboBox_shader_log_direction, info.shader_log_direction); m_ui->lineEdit_shader_log_folder->setText(info.shader_log_folder); m_ui->lineEdit_shader_log_folder->setEnabled(info.shader_log_direction == Configuration::ShaderLogDirection::File); m_ui->checkBox_cmd_dump->setChecked(info.command_buffer_dump_enabled); m_ui->lineEdit_cmd_dump_folder->setText(info.command_buffer_dump_folder); m_ui->lineEdit_cmd_dump_folder->setEnabled(info.command_buffer_dump_enabled); ListInit(m_ui->comboBox_printf_direction, info.printf_direction); m_ui->lineEdit_printf_file->setText(info.printf_output_file); m_ui->lineEdit_printf_file->setEnabled(info.printf_direction == Configuration::LogDirection::File); ListInit(m_ui->comboBox_profiler_direction, info.profiler_direction); } void ConfigurationEditDialog::InitGameDirectories() { m_game_dirs_group = new QGroupBox(tr("Game folders"), this); auto* group_layout = new QVBoxLayout(m_game_dirs_group); group_layout->setContentsMargins(8, 8, 8, 8); group_layout->setSpacing(6); m_game_dirs_list = new QListWidget(m_game_dirs_group); m_game_dirs_list->setMinimumHeight(120); m_game_dirs_list->setSelectionMode(QAbstractItemView::ExtendedSelection); group_layout->addWidget(m_game_dirs_list); auto* button_layout = new QHBoxLayout; button_layout->setContentsMargins(0, 0, 0, 0); button_layout->setSpacing(4); auto* add_button = new QToolButton(m_game_dirs_group); add_button->setIcon(style()->standardIcon(QStyle::SP_DirOpenIcon)); add_button->setToolTip(tr("Add game folder")); add_button->setAutoRaise(true); button_layout->addWidget(add_button); m_remove_game_dir_button = new QToolButton(m_game_dirs_group); m_remove_game_dir_button->setIcon(style()->standardIcon(QStyle::SP_DialogDiscardButton)); m_remove_game_dir_button->setToolTip(tr("Remove selected game folders")); m_remove_game_dir_button->setAutoRaise(true); button_layout->addWidget(m_remove_game_dir_button); button_layout->addStretch(1); group_layout->addLayout(button_layout); m_ui->gridLayout->addWidget(m_game_dirs_group, 1, 0, 1, 1); m_game_dirs_group->setVisible(false); connect(add_button, &QToolButton::clicked, this, &ConfigurationEditDialog::add_game_directory); connect(m_remove_game_dir_button, &QToolButton::clicked, this, &ConfigurationEditDialog::remove_selected_game_directories); connect(m_game_dirs_list, &QListWidget::itemSelectionChanged, this, &ConfigurationEditDialog::update_game_directory_buttons); update_game_directory_buttons(); } void ConfigurationEditDialog::SetTitle(const QString& str) { setWindowTitle(str); } void ConfigurationEditDialog::SetGameDirectories(const QStringList& dirs) { m_show_game_dirs = true; m_game_dirs_list->clear(); m_game_dirs_group->setMinimumWidth(GLOBAL_SETTINGS_GAME_DIRS_MIN_WIDTH); for (const auto& dir: dirs) { AddGameDirectoryItem(dir); } m_game_dirs_group->setVisible(true); update_game_directory_buttons(); adjustSize(); } QStringList ConfigurationEditDialog::GetGameDirectories() const { QStringList dirs; if (!m_show_game_dirs) { return dirs; } for (int index = 0; index < m_game_dirs_list->count(); index++) { auto* item = m_game_dirs_list->item(index); dirs.append(item->text()); } return dirs; } void ConfigurationEditDialog::AddGameDirectoryItem(const QString& dir) { const auto normalized = NormalizeGameDirectory(dir); const auto key = GameDirectoryKey(normalized); if (normalized.isEmpty() || key.isEmpty()) { return; } for (int index = 0; index < m_game_dirs_list->count(); index++) { auto* item = m_game_dirs_list->item(index); if (GameDirectoryKey(item->text()) == key) { return; } } auto* item = new QListWidgetItem(normalized, m_game_dirs_list); item->setToolTip(normalized); } void ConfigurationEditDialog::moveEvent(QMoveEvent* event) { QDialog::moveEvent(event); g_last_geometry = saveGeometry(); } static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui) { info.screen_resolution = TextToEnum(ui.comboBox_screen_resolution->currentText()); info.fullscreen_enabled = ui.checkBox_fullscreen->isChecked(); info.vblank_frequency = ui.spinBox_vblank_frequency->value(); info.console_language = ui.comboBox_console_language->currentIndex(); info.vulkan_validation_enabled = ui.checkBox_vulkan_validation->isChecked(); info.shader_validation_enabled = ui.checkBox_shader_validation->isChecked(); info.renderdoc_enabled = ui.checkBox_renderdoc_capture->isChecked(); #if defined(_WIN32) info.red_zone_protection_enabled = ui.checkBox_red_zone_protection->isChecked(); #endif info.shader_optimization_type = TextToEnum( ui.comboBox_shader_optimization_type->currentText()); info.shader_log_direction = TextToEnum( ui.comboBox_shader_log_direction->currentText()); info.shader_log_folder = ui.lineEdit_shader_log_folder->text(); info.command_buffer_dump_enabled = ui.checkBox_cmd_dump->isChecked(); info.command_buffer_dump_folder = ui.lineEdit_cmd_dump_folder->text(); info.printf_direction = TextToEnum(ui.comboBox_printf_direction->currentText()); info.printf_output_file = ui.lineEdit_printf_file->text(); info.profiler_direction = TextToEnum(ui.comboBox_profiler_direction->currentText()); } void ConfigurationEditDialog::update_info() { UpdateInfo(m_info, *m_ui); } void ConfigurationEditDialog::adjust_size() { this->adjustSize(); } void ConfigurationEditDialog::save() { if (MandatoryLineEdit::FindEmpty(this)) { QMessageBox::critical(this, tr("Save failed"), tr("Please fill all mandatory fields")); return; } update_info(); emit accept(); } void ConfigurationEditDialog::clear() { Configuration default_info; Init(default_info); if (m_show_game_dirs) { m_game_dirs_list->clear(); update_game_directory_buttons(); } } void ConfigurationEditDialog::add_game_directory() { QString start_dir = QDir::homePath(); if (m_game_dirs_list->count() > 0) { start_dir = m_game_dirs_list->item(m_game_dirs_list->count() - 1)->text(); } QFileDialog dialog(this, tr("Select game folders"), start_dir); dialog.setFileMode(QFileDialog::Directory); dialog.setOption(QFileDialog::ShowDirsOnly, true); dialog.setOption(QFileDialog::DontUseNativeDialog, true); dialog.setLabelText(QFileDialog::Accept, tr("Add")); auto* list_view = dialog.findChild(QStringLiteral("listView")); if (list_view != nullptr) { list_view->setSelectionMode(QAbstractItemView::ExtendedSelection); } auto* tree_view = dialog.findChild(QStringLiteral("treeView")); if (tree_view != nullptr) { tree_view->setSelectionMode(QAbstractItemView::ExtendedSelection); } if (dialog.exec() != QDialog::Accepted) { return; } for (const auto& dir: dialog.selectedFiles()) { AddGameDirectoryItem(dir); } update_game_directory_buttons(); } void ConfigurationEditDialog::remove_selected_game_directories() { qDeleteAll(m_game_dirs_list->selectedItems()); update_game_directory_buttons(); } void ConfigurationEditDialog::update_game_directory_buttons() { m_remove_game_dir_button->setEnabled(!m_game_dirs_list->selectedItems().isEmpty()); }