diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/alignment.h | 1 | ||||
| -rw-r--r-- | src/yuzu/CMakeLists.txt | 33 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_dialog.cpp | 9 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_dialog.h | 6 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_ui.cpp | 31 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_ui.h | 7 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_ui.ui | 188 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 42 | ||||
| -rw-r--r-- | src/yuzu/main.h | 5 | ||||
| -rw-r--r-- | src/yuzu/uisettings.h | 1 |
11 files changed, 241 insertions, 84 deletions
diff --git a/src/common/alignment.h b/src/common/alignment.h index 4025ba651..ef4d6f896 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #pragma once | 3 | #pragma once |
| 4 | 4 | ||
| 5 | #include <cstddef> | 5 | #include <cstddef> |
| 6 | #include <new> | ||
| 6 | #include <type_traits> | 7 | #include <type_traits> |
| 7 | 8 | ||
| 8 | namespace Common { | 9 | namespace Common { |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index a862b2610..656096c9f 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -133,11 +133,44 @@ file(GLOB COMPAT_LIST | |||
| 133 | file(GLOB_RECURSE ICONS ${PROJECT_SOURCE_DIR}/dist/icons/*) | 133 | file(GLOB_RECURSE ICONS ${PROJECT_SOURCE_DIR}/dist/icons/*) |
| 134 | file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*) | 134 | file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*) |
| 135 | 135 | ||
| 136 | if (ENABLE_QT_TRANSLATION) | ||
| 137 | set(YUZU_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend") | ||
| 138 | option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF) | ||
| 139 | |||
| 140 | # Update source TS file if enabled | ||
| 141 | if (GENERATE_QT_TRANSLATION) | ||
| 142 | get_target_property(SRCS yuzu SOURCES) | ||
| 143 | qt5_create_translation(QM_FILES ${SRCS} ${UIS} ${YUZU_QT_LANGUAGES}/en.ts) | ||
| 144 | add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts) | ||
| 145 | endif() | ||
| 146 | |||
| 147 | # Find all TS files except en.ts | ||
| 148 | file(GLOB_RECURSE LANGUAGES_TS ${YUZU_QT_LANGUAGES}/*.ts) | ||
| 149 | list(REMOVE_ITEM LANGUAGES_TS ${YUZU_QT_LANGUAGES}/en.ts) | ||
| 150 | |||
| 151 | # Compile TS files to QM files | ||
| 152 | qt5_add_translation(LANGUAGES_QM ${LANGUAGES_TS}) | ||
| 153 | |||
| 154 | # Build a QRC file from the QM file list | ||
| 155 | set(LANGUAGES_QRC ${CMAKE_CURRENT_BINARY_DIR}/languages.qrc) | ||
| 156 | file(WRITE ${LANGUAGES_QRC} "<RCC><qresource prefix=\"languages\">\n") | ||
| 157 | foreach (QM ${LANGUAGES_QM}) | ||
| 158 | get_filename_component(QM_FILE ${QM} NAME) | ||
| 159 | file(APPEND ${LANGUAGES_QRC} "<file>${QM_FILE}</file>\n") | ||
| 160 | endforeach (QM) | ||
| 161 | file(APPEND ${LANGUAGES_QRC} "</qresource></RCC>") | ||
| 162 | |||
| 163 | # Add the QRC file to package in all QM files | ||
| 164 | qt5_add_resources(LANGUAGES ${LANGUAGES_QRC}) | ||
| 165 | else() | ||
| 166 | set(LANGUAGES) | ||
| 167 | endif() | ||
| 136 | 168 | ||
| 137 | target_sources(yuzu | 169 | target_sources(yuzu |
| 138 | PRIVATE | 170 | PRIVATE |
| 139 | ${COMPAT_LIST} | 171 | ${COMPAT_LIST} |
| 140 | ${ICONS} | 172 | ${ICONS} |
| 173 | ${LANGUAGES} | ||
| 141 | ${THEMES} | 174 | ${THEMES} |
| 142 | ) | 175 | ) |
| 143 | 176 | ||
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 805bb954b..59a193edd 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -611,6 +611,7 @@ void Config::ReadPathValues() { | |||
| 611 | } | 611 | } |
| 612 | } | 612 | } |
| 613 | UISettings::values.recent_files = ReadSetting(QStringLiteral("recentFiles")).toStringList(); | 613 | UISettings::values.recent_files = ReadSetting(QStringLiteral("recentFiles")).toStringList(); |
| 614 | UISettings::values.language = ReadSetting(QStringLiteral("language"), QString{}).toString(); | ||
| 614 | 615 | ||
| 615 | qt_config->endGroup(); | 616 | qt_config->endGroup(); |
| 616 | } | 617 | } |
| @@ -1095,6 +1096,7 @@ void Config::SavePathValues() { | |||
| 1095 | } | 1096 | } |
| 1096 | qt_config->endArray(); | 1097 | qt_config->endArray(); |
| 1097 | WriteSetting(QStringLiteral("recentFiles"), UISettings::values.recent_files); | 1098 | WriteSetting(QStringLiteral("recentFiles"), UISettings::values.recent_files); |
| 1099 | WriteSetting(QStringLiteral("language"), UISettings::values.language, QString{}); | ||
| 1098 | 1100 | ||
| 1099 | qt_config->endGroup(); | 1101 | qt_config->endGroup(); |
| 1100 | } | 1102 | } |
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index a5afb354f..4e30dc51e 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp | |||
| @@ -23,6 +23,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry) | |||
| 23 | SetConfiguration(); | 23 | SetConfiguration(); |
| 24 | PopulateSelectionList(); | 24 | PopulateSelectionList(); |
| 25 | 25 | ||
| 26 | connect(ui->uiTab, &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged); | ||
| 26 | connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, | 27 | connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, |
| 27 | &ConfigureDialog::UpdateVisibleTabs); | 28 | &ConfigureDialog::UpdateVisibleTabs); |
| 28 | 29 | ||
| @@ -98,6 +99,14 @@ void ConfigureDialog::PopulateSelectionList() { | |||
| 98 | } | 99 | } |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 102 | void ConfigureDialog::OnLanguageChanged(const QString& locale) { | ||
| 103 | emit LanguageChanged(locale); | ||
| 104 | // first apply the configuration, and then restore the display | ||
| 105 | ApplyConfiguration(); | ||
| 106 | RetranslateUI(); | ||
| 107 | SetConfiguration(); | ||
| 108 | } | ||
| 109 | |||
| 101 | void ConfigureDialog::UpdateVisibleTabs() { | 110 | void ConfigureDialog::UpdateVisibleTabs() { |
| 102 | const auto items = ui->selectorList->selectedItems(); | 111 | const auto items = ui->selectorList->selectedItems(); |
| 103 | if (items.isEmpty()) { | 112 | if (items.isEmpty()) { |
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 2d3bfc2da..4289bc225 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h | |||
| @@ -22,6 +22,12 @@ public: | |||
| 22 | 22 | ||
| 23 | void ApplyConfiguration(); | 23 | void ApplyConfiguration(); |
| 24 | 24 | ||
| 25 | private slots: | ||
| 26 | void OnLanguageChanged(const QString& locale); | ||
| 27 | |||
| 28 | signals: | ||
| 29 | void LanguageChanged(const QString& locale); | ||
| 30 | |||
| 25 | private: | 31 | private: |
| 26 | void changeEvent(QEvent* event) override; | 32 | void changeEvent(QEvent* event) override; |
| 27 | 33 | ||
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index 94424ee44..24b6c5b72 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <utility> | 6 | #include <utility> |
| 7 | 7 | ||
| 8 | #include <QDirIterator> | ||
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "core/settings.h" | 10 | #include "core/settings.h" |
| 10 | #include "ui_configure_ui.h" | 11 | #include "ui_configure_ui.h" |
| @@ -29,6 +30,8 @@ constexpr std::array row_text_names{ | |||
| 29 | ConfigureUi::ConfigureUi(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureUi) { | 30 | ConfigureUi::ConfigureUi(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureUi) { |
| 30 | ui->setupUi(this); | 31 | ui->setupUi(this); |
| 31 | 32 | ||
| 33 | InitializeLanguageComboBox(); | ||
| 34 | |||
| 32 | for (const auto& theme : UISettings::themes) { | 35 | for (const auto& theme : UISettings::themes) { |
| 33 | ui->theme_combobox->addItem(QString::fromUtf8(theme.first), | 36 | ui->theme_combobox->addItem(QString::fromUtf8(theme.first), |
| 34 | QString::fromUtf8(theme.second)); | 37 | QString::fromUtf8(theme.second)); |
| @@ -72,6 +75,8 @@ void ConfigureUi::RequestGameListUpdate() { | |||
| 72 | 75 | ||
| 73 | void ConfigureUi::SetConfiguration() { | 76 | void ConfigureUi::SetConfiguration() { |
| 74 | ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme)); | 77 | ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme)); |
| 78 | ui->language_combobox->setCurrentIndex( | ||
| 79 | ui->language_combobox->findData(UISettings::values.language)); | ||
| 75 | ui->show_add_ons->setChecked(UISettings::values.show_add_ons); | 80 | ui->show_add_ons->setChecked(UISettings::values.show_add_ons); |
| 76 | ui->icon_size_combobox->setCurrentIndex( | 81 | ui->icon_size_combobox->setCurrentIndex( |
| 77 | ui->icon_size_combobox->findData(UISettings::values.icon_size)); | 82 | ui->icon_size_combobox->findData(UISettings::values.icon_size)); |
| @@ -100,6 +105,25 @@ void ConfigureUi::RetranslateUI() { | |||
| 100 | } | 105 | } |
| 101 | } | 106 | } |
| 102 | 107 | ||
| 108 | void ConfigureUi::InitializeLanguageComboBox() { | ||
| 109 | ui->language_combobox->addItem(tr("<System>"), QString{}); | ||
| 110 | ui->language_combobox->addItem(tr("English"), QStringLiteral("en")); | ||
| 111 | QDirIterator it(QStringLiteral(":/languages"), QDirIterator::NoIteratorFlags); | ||
| 112 | while (it.hasNext()) { | ||
| 113 | QString locale = it.next(); | ||
| 114 | locale.truncate(locale.lastIndexOf(QLatin1Char{'.'})); | ||
| 115 | locale.remove(0, locale.lastIndexOf(QLatin1Char{'/'}) + 1); | ||
| 116 | const QString lang = QLocale::languageToString(QLocale(locale).language()); | ||
| 117 | ui->language_combobox->addItem(lang, locale); | ||
| 118 | } | ||
| 119 | |||
| 120 | // Unlike other configuration changes, interface language changes need to be reflected on the | ||
| 121 | // interface immediately. This is done by passing a signal to the main window, and then | ||
| 122 | // retranslating when passing back. | ||
| 123 | connect(ui->language_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, | ||
| 124 | &ConfigureUi::OnLanguageChanged); | ||
| 125 | } | ||
| 126 | |||
| 103 | void ConfigureUi::InitializeIconSizeComboBox() { | 127 | void ConfigureUi::InitializeIconSizeComboBox() { |
| 104 | for (const auto& size : default_icon_sizes) { | 128 | for (const auto& size : default_icon_sizes) { |
| 105 | ui->icon_size_combobox->addItem(QString::fromUtf8(size.second), size.first); | 129 | ui->icon_size_combobox->addItem(QString::fromUtf8(size.second), size.first); |
| @@ -147,3 +171,10 @@ void ConfigureUi::UpdateSecondRowComboBox(bool init) { | |||
| 147 | ui->row_2_text_combobox->removeItem( | 171 | ui->row_2_text_combobox->removeItem( |
| 148 | ui->row_2_text_combobox->findData(ui->row_1_text_combobox->currentData())); | 172 | ui->row_2_text_combobox->findData(ui->row_1_text_combobox->currentData())); |
| 149 | } | 173 | } |
| 174 | |||
| 175 | void ConfigureUi::OnLanguageChanged(int index) { | ||
| 176 | if (index == -1) | ||
| 177 | return; | ||
| 178 | |||
| 179 | emit LanguageChanged(ui->language_combobox->itemData(index).toString()); | ||
| 180 | } | ||
diff --git a/src/yuzu/configuration/configure_ui.h b/src/yuzu/configuration/configure_ui.h index d471afe99..c30bcf6ff 100644 --- a/src/yuzu/configuration/configure_ui.h +++ b/src/yuzu/configuration/configure_ui.h | |||
| @@ -20,6 +20,12 @@ public: | |||
| 20 | 20 | ||
| 21 | void ApplyConfiguration(); | 21 | void ApplyConfiguration(); |
| 22 | 22 | ||
| 23 | private slots: | ||
| 24 | void OnLanguageChanged(int index); | ||
| 25 | |||
| 26 | signals: | ||
| 27 | void LanguageChanged(const QString& locale); | ||
| 28 | |||
| 23 | private: | 29 | private: |
| 24 | void RequestGameListUpdate(); | 30 | void RequestGameListUpdate(); |
| 25 | 31 | ||
| @@ -28,6 +34,7 @@ private: | |||
| 28 | void changeEvent(QEvent*) override; | 34 | void changeEvent(QEvent*) override; |
| 29 | void RetranslateUI(); | 35 | void RetranslateUI(); |
| 30 | 36 | ||
| 37 | void InitializeLanguageComboBox(); | ||
| 31 | void InitializeIconSizeComboBox(); | 38 | void InitializeIconSizeComboBox(); |
| 32 | void InitializeRowComboBoxes(); | 39 | void InitializeRowComboBoxes(); |
| 33 | 40 | ||
diff --git a/src/yuzu/configuration/configure_ui.ui b/src/yuzu/configuration/configure_ui.ui index bd5c5d3c2..0b81747d7 100644 --- a/src/yuzu/configuration/configure_ui.ui +++ b/src/yuzu/configuration/configure_ui.ui | |||
| @@ -13,112 +13,132 @@ | |||
| 13 | <property name="windowTitle"> | 13 | <property name="windowTitle"> |
| 14 | <string>Form</string> | 14 | <string>Form</string> |
| 15 | </property> | 15 | </property> |
| 16 | <layout class="QHBoxLayout" name="HorizontalLayout"> | 16 | <layout class="QVBoxLayout" name="verticalLayout"> |
| 17 | <item> | 17 | <item> |
| 18 | <layout class="QVBoxLayout" name="VerticalLayout"> | 18 | <widget class="QGroupBox" name="general_groupBox"> |
| 19 | <item> | 19 | <property name="title"> |
| 20 | <widget class="QGroupBox" name="GeneralGroupBox"> | 20 | <string>General</string> |
| 21 | <property name="title"> | 21 | </property> |
| 22 | <string>General</string> | 22 | <layout class="QHBoxLayout" name="horizontalLayout"> |
| 23 | </property> | 23 | <item> |
| 24 | <layout class="QHBoxLayout" name="horizontalLayout"> | 24 | <layout class="QVBoxLayout" name="verticalLayout_2"> |
| 25 | <item> | 25 | <item> |
| 26 | <layout class="QVBoxLayout" name="verticalLayout"> | 26 | <widget class="QLabel" name="label_change_language_info"> |
| 27 | <property name="text"> | ||
| 28 | <string>Note: Changing language will apply your configuration.</string> | ||
| 29 | </property> | ||
| 30 | <property name="wordWrap"> | ||
| 31 | <bool>true</bool> | ||
| 32 | </property> | ||
| 33 | </widget> | ||
| 34 | </item> | ||
| 35 | <item> | ||
| 36 | <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||
| 37 | <item> | ||
| 38 | <widget class="QLabel" name="language_label"> | ||
| 39 | <property name="text"> | ||
| 40 | <string>Interface language:</string> | ||
| 41 | </property> | ||
| 42 | </widget> | ||
| 43 | </item> | ||
| 44 | <item> | ||
| 45 | <widget class="QComboBox" name="language_combobox"/> | ||
| 46 | </item> | ||
| 47 | </layout> | ||
| 48 | </item> | ||
| 49 | <item> | ||
| 50 | <layout class="QHBoxLayout" name="horizontalLayout_3"> | ||
| 51 | <item> | ||
| 52 | <widget class="QLabel" name="theme_label"> | ||
| 53 | <property name="text"> | ||
| 54 | <string>Theme:</string> | ||
| 55 | </property> | ||
| 56 | </widget> | ||
| 57 | </item> | ||
| 27 | <item> | 58 | <item> |
| 28 | <layout class="QHBoxLayout" name="horizontalLayout_3"> | 59 | <widget class="QComboBox" name="theme_combobox"/> |
| 29 | <item> | ||
| 30 | <widget class="QLabel" name="theme_label"> | ||
| 31 | <property name="text"> | ||
| 32 | <string>Theme:</string> | ||
| 33 | </property> | ||
| 34 | </widget> | ||
| 35 | </item> | ||
| 36 | <item> | ||
| 37 | <widget class="QComboBox" name="theme_combobox"/> | ||
| 38 | </item> | ||
| 39 | </layout> | ||
| 40 | </item> | 60 | </item> |
| 41 | </layout> | 61 | </layout> |
| 42 | </item> | 62 | </item> |
| 43 | </layout> | 63 | </layout> |
| 44 | </widget> | 64 | </item> |
| 45 | </item> | 65 | </layout> |
| 46 | <item> | 66 | </widget> |
| 47 | <widget class="QGroupBox" name="GameListGroupBox"> | 67 | </item> |
| 48 | <property name="title"> | 68 | <item> |
| 49 | <string>Game List</string> | 69 | <widget class="QGroupBox" name="GameListGroupBox"> |
| 50 | </property> | 70 | <property name="title"> |
| 51 | <layout class="QHBoxLayout" name="GameListHorizontalLayout"> | 71 | <string>Game List</string> |
| 72 | </property> | ||
| 73 | <layout class="QHBoxLayout" name="GameListHorizontalLayout"> | ||
| 74 | <item> | ||
| 75 | <layout class="QVBoxLayout" name="GeneralVerticalLayout"> | ||
| 52 | <item> | 76 | <item> |
| 53 | <layout class="QVBoxLayout" name="GeneralVerticalLayout"> | 77 | <widget class="QCheckBox" name="show_add_ons"> |
| 78 | <property name="text"> | ||
| 79 | <string>Show Add-Ons Column</string> | ||
| 80 | </property> | ||
| 81 | </widget> | ||
| 82 | </item> | ||
| 83 | <item> | ||
| 84 | <layout class="QHBoxLayout" name="icon_size_qhbox_layout_2"> | ||
| 54 | <item> | 85 | <item> |
| 55 | <widget class="QCheckBox" name="show_add_ons"> | 86 | <widget class="QLabel" name="icon_size_label"> |
| 56 | <property name="text"> | 87 | <property name="text"> |
| 57 | <string>Show Add-Ons Column</string> | 88 | <string>Icon Size:</string> |
| 58 | </property> | 89 | </property> |
| 59 | </widget> | 90 | </widget> |
| 60 | </item> | 91 | </item> |
| 61 | <item> | 92 | <item> |
| 62 | <layout class="QHBoxLayout" name="icon_size_qhbox_layout_2"> | 93 | <widget class="QComboBox" name="icon_size_combobox"/> |
| 63 | <item> | ||
| 64 | <widget class="QLabel" name="icon_size_label"> | ||
| 65 | <property name="text"> | ||
| 66 | <string>Icon Size:</string> | ||
| 67 | </property> | ||
| 68 | </widget> | ||
| 69 | </item> | ||
| 70 | <item> | ||
| 71 | <widget class="QComboBox" name="icon_size_combobox"/> | ||
| 72 | </item> | ||
| 73 | </layout> | ||
| 74 | </item> | 94 | </item> |
| 95 | </layout> | ||
| 96 | </item> | ||
| 97 | <item> | ||
| 98 | <layout class="QHBoxLayout" name="row_1_qhbox_layout"> | ||
| 75 | <item> | 99 | <item> |
| 76 | <layout class="QHBoxLayout" name="row_1_qhbox_layout"> | 100 | <widget class="QLabel" name="row_1_label"> |
| 77 | <item> | 101 | <property name="text"> |
| 78 | <widget class="QLabel" name="row_1_label"> | 102 | <string>Row 1 Text:</string> |
| 79 | <property name="text"> | 103 | </property> |
| 80 | <string>Row 1 Text:</string> | 104 | </widget> |
| 81 | </property> | ||
| 82 | </widget> | ||
| 83 | </item> | ||
| 84 | <item> | ||
| 85 | <widget class="QComboBox" name="row_1_text_combobox"/> | ||
| 86 | </item> | ||
| 87 | </layout> | ||
| 88 | </item> | 105 | </item> |
| 89 | <item> | 106 | <item> |
| 90 | <layout class="QHBoxLayout" name="row_2_qhbox_layout"> | 107 | <widget class="QComboBox" name="row_1_text_combobox"/> |
| 91 | <item> | 108 | </item> |
| 92 | <widget class="QLabel" name="row_2_label"> | 109 | </layout> |
| 93 | <property name="text"> | 110 | </item> |
| 94 | <string>Row 2 Text:</string> | 111 | <item> |
| 95 | </property> | 112 | <layout class="QHBoxLayout" name="row_2_qhbox_layout"> |
| 96 | </widget> | 113 | <item> |
| 97 | </item> | 114 | <widget class="QLabel" name="row_2_label"> |
| 98 | <item> | 115 | <property name="text"> |
| 99 | <widget class="QComboBox" name="row_2_text_combobox"/> | 116 | <string>Row 2 Text:</string> |
| 100 | </item> | 117 | </property> |
| 101 | </layout> | 118 | </widget> |
| 119 | </item> | ||
| 120 | <item> | ||
| 121 | <widget class="QComboBox" name="row_2_text_combobox"/> | ||
| 102 | </item> | 122 | </item> |
| 103 | </layout> | 123 | </layout> |
| 104 | </item> | 124 | </item> |
| 105 | </layout> | 125 | </layout> |
| 106 | </widget> | 126 | </item> |
| 107 | </item> | 127 | </layout> |
| 108 | <item> | 128 | </widget> |
| 109 | <spacer name="verticalSpacer"> | 129 | </item> |
| 110 | <property name="orientation"> | 130 | <item> |
| 111 | <enum>Qt::Vertical</enum> | 131 | <spacer name="verticalSpacer"> |
| 112 | </property> | 132 | <property name="orientation"> |
| 113 | <property name="sizeHint" stdset="0"> | 133 | <enum>Qt::Vertical</enum> |
| 114 | <size> | 134 | </property> |
| 115 | <width>20</width> | 135 | <property name="sizeHint" stdset="0"> |
| 116 | <height>40</height> | 136 | <size> |
| 117 | </size> | 137 | <width>20</width> |
| 118 | </property> | 138 | <height>40</height> |
| 119 | </spacer> | 139 | </size> |
| 120 | </item> | 140 | </property> |
| 121 | </layout> | 141 | </spacer> |
| 122 | </item> | 142 | </item> |
| 123 | </layout> | 143 | </layout> |
| 124 | </widget> | 144 | </widget> |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6909d65d0..31a635176 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -191,6 +191,8 @@ GMainWindow::GMainWindow() | |||
| 191 | provider(std::make_unique<FileSys::ManualContentProvider>()) { | 191 | provider(std::make_unique<FileSys::ManualContentProvider>()) { |
| 192 | InitializeLogging(); | 192 | InitializeLogging(); |
| 193 | 193 | ||
| 194 | LoadTranslation(); | ||
| 195 | |||
| 194 | setAcceptDrops(true); | 196 | setAcceptDrops(true); |
| 195 | ui.setupUi(this); | 197 | ui.setupUi(this); |
| 196 | statusBar()->hide(); | 198 | statusBar()->hide(); |
| @@ -2048,6 +2050,9 @@ void GMainWindow::OnConfigure() { | |||
| 2048 | const bool old_discord_presence = UISettings::values.enable_discord_presence; | 2050 | const bool old_discord_presence = UISettings::values.enable_discord_presence; |
| 2049 | 2051 | ||
| 2050 | ConfigureDialog configure_dialog(this, hotkey_registry); | 2052 | ConfigureDialog configure_dialog(this, hotkey_registry); |
| 2053 | connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this, | ||
| 2054 | &GMainWindow::OnLanguageChanged); | ||
| 2055 | |||
| 2051 | const auto result = configure_dialog.exec(); | 2056 | const auto result = configure_dialog.exec(); |
| 2052 | if (result != QDialog::Accepted) { | 2057 | if (result != QDialog::Accepted) { |
| 2053 | return; | 2058 | return; |
| @@ -2620,6 +2625,43 @@ void GMainWindow::UpdateUITheme() { | |||
| 2620 | QIcon::setThemeSearchPaths(theme_paths); | 2625 | QIcon::setThemeSearchPaths(theme_paths); |
| 2621 | } | 2626 | } |
| 2622 | 2627 | ||
| 2628 | void GMainWindow::LoadTranslation() { | ||
| 2629 | // If the selected language is English, no need to install any translation | ||
| 2630 | if (UISettings::values.language == QStringLiteral("en")) { | ||
| 2631 | return; | ||
| 2632 | } | ||
| 2633 | |||
| 2634 | bool loaded; | ||
| 2635 | |||
| 2636 | if (UISettings::values.language.isEmpty()) { | ||
| 2637 | // If the selected language is empty, use system locale | ||
| 2638 | loaded = translator.load(QLocale(), {}, {}, QStringLiteral(":/languages/")); | ||
| 2639 | } else { | ||
| 2640 | // Otherwise load from the specified file | ||
| 2641 | loaded = translator.load(UISettings::values.language, QStringLiteral(":/languages/")); | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | if (loaded) { | ||
| 2645 | qApp->installTranslator(&translator); | ||
| 2646 | } else { | ||
| 2647 | UISettings::values.language = QStringLiteral("en"); | ||
| 2648 | } | ||
| 2649 | } | ||
| 2650 | |||
| 2651 | void GMainWindow::OnLanguageChanged(const QString& locale) { | ||
| 2652 | if (UISettings::values.language != QStringLiteral("en")) { | ||
| 2653 | qApp->removeTranslator(&translator); | ||
| 2654 | } | ||
| 2655 | |||
| 2656 | UISettings::values.language = locale; | ||
| 2657 | LoadTranslation(); | ||
| 2658 | ui.retranslateUi(this); | ||
| 2659 | UpdateWindowTitle(); | ||
| 2660 | |||
| 2661 | if (emulation_running) | ||
| 2662 | ui.action_Start->setText(tr("Continue")); | ||
| 2663 | } | ||
| 2664 | |||
| 2623 | void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { | 2665 | void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { |
| 2624 | #ifdef USE_DISCORD_PRESENCE | 2666 | #ifdef USE_DISCORD_PRESENCE |
| 2625 | if (state) { | 2667 | if (state) { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 59d9073ae..db573d606 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include <QMainWindow> | 11 | #include <QMainWindow> |
| 12 | #include <QTimer> | 12 | #include <QTimer> |
| 13 | #include <QTranslator> | ||
| 13 | 14 | ||
| 14 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| 15 | #include "core/core.h" | 16 | #include "core/core.h" |
| @@ -225,6 +226,7 @@ private slots: | |||
| 225 | void OnCaptureScreenshot(); | 226 | void OnCaptureScreenshot(); |
| 226 | void OnCoreError(Core::System::ResultStatus, std::string); | 227 | void OnCoreError(Core::System::ResultStatus, std::string); |
| 227 | void OnReinitializeKeys(ReinitializeKeyBehavior behavior); | 228 | void OnReinitializeKeys(ReinitializeKeyBehavior behavior); |
| 229 | void OnLanguageChanged(const QString& locale); | ||
| 228 | 230 | ||
| 229 | private: | 231 | private: |
| 230 | std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); | 232 | std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); |
| @@ -237,6 +239,7 @@ private: | |||
| 237 | void HideMouseCursor(); | 239 | void HideMouseCursor(); |
| 238 | void ShowMouseCursor(); | 240 | void ShowMouseCursor(); |
| 239 | void OpenURL(const QUrl& url); | 241 | void OpenURL(const QUrl& url); |
| 242 | void LoadTranslation(); | ||
| 240 | 243 | ||
| 241 | Ui::MainWindow ui; | 244 | Ui::MainWindow ui; |
| 242 | 245 | ||
| @@ -285,6 +288,8 @@ private: | |||
| 285 | 288 | ||
| 286 | HotkeyRegistry hotkey_registry; | 289 | HotkeyRegistry hotkey_registry; |
| 287 | 290 | ||
| 291 | QTranslator translator; | ||
| 292 | |||
| 288 | // Install progress dialog | 293 | // Install progress dialog |
| 289 | QProgressDialog* install_progress; | 294 | QProgressDialog* install_progress; |
| 290 | 295 | ||
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 830932d45..6cc65736d 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h | |||
| @@ -75,6 +75,7 @@ struct Values { | |||
| 75 | bool game_dir_deprecated_deepscan; | 75 | bool game_dir_deprecated_deepscan; |
| 76 | QVector<UISettings::GameDir> game_dirs; | 76 | QVector<UISettings::GameDir> game_dirs; |
| 77 | QStringList recent_files; | 77 | QStringList recent_files; |
| 78 | QString language; | ||
| 78 | 79 | ||
| 79 | QString theme; | 80 | QString theme; |
| 80 | 81 | ||