mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-18 04:59:59 +00:00
yuzu: Port translation support from Citra
Co-Authored-By: Weiyi Wang <wwylele@gmail.com>
This commit is contained in:
parent
4a8cb9a706
commit
347b50ad43
17 changed files with 261 additions and 92 deletions
|
@ -5,7 +5,7 @@ cd /yuzu
|
||||||
ccache -s
|
ccache -s
|
||||||
|
|
||||||
mkdir build || true && cd build
|
mkdir build || true && cd build
|
||||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON
|
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON
|
||||||
|
|
||||||
ninja
|
ninja
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ cd /yuzu
|
||||||
ccache -s
|
ccache -s
|
||||||
|
|
||||||
mkdir build || true && cd build
|
mkdir build || true && cd build
|
||||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DYUZU_USE_BUNDLED_UNICORN=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release
|
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DYUZU_USE_BUNDLED_UNICORN=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON
|
||||||
ninja
|
ninja
|
||||||
|
|
||||||
ccache -s
|
ccache -s
|
||||||
|
|
|
@ -13,6 +13,7 @@ project(yuzu)
|
||||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||||
|
|
||||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||||
|
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
||||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_QT;MSVC" OFF)
|
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_QT;MSVC" OFF)
|
||||||
|
|
||||||
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
||||||
|
@ -224,6 +225,10 @@ if(ENABLE_QT)
|
||||||
if (YUZU_USE_QT_WEB_ENGINE)
|
if (YUZU_USE_QT_WEB_ENGINE)
|
||||||
find_package(Qt5 COMPONENTS WebEngineCore WebEngineWidgets)
|
find_package(Qt5 COMPONENTS WebEngineCore WebEngineWidgets)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_QT_TRANSLATION)
|
||||||
|
find_package(Qt5 REQUIRED COMPONENTS LinguistTools ${QT_PREFIX_HINT})
|
||||||
|
endif()
|
||||||
if (NOT Qt5_FOUND)
|
if (NOT Qt5_FOUND)
|
||||||
list(APPEND CONAN_REQUIRED_LIBS "qt/5.14.1@bincrafters/stable")
|
list(APPEND CONAN_REQUIRED_LIBS "qt/5.14.1@bincrafters/stable")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -24,6 +24,8 @@ Most of the development happens on GitHub. It's also where [our central reposito
|
||||||
|
|
||||||
If you want to contribute please take a look at the [Contributor's Guide](https://github.com/yuzu-emu/yuzu/wiki/Contributing) and [Developer Information](https://github.com/yuzu-emu/yuzu/wiki/Developer-Information). You should also contact any of the developers on Discord in order to know about the current state of the emulator.
|
If you want to contribute please take a look at the [Contributor's Guide](https://github.com/yuzu-emu/yuzu/wiki/Contributing) and [Developer Information](https://github.com/yuzu-emu/yuzu/wiki/Developer-Information). You should also contact any of the developers on Discord in order to know about the current state of the emulator.
|
||||||
|
|
||||||
|
If you want to contribute to the user interface translation, please checkout [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu). We centralize the translation work there, and periodically upstream translation.
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
* __Windows__: [Windows Build](https://github.com/yuzu-emu/yuzu/wiki/Building-For-Windows)
|
* __Windows__: [Windows Build](https://github.com/yuzu-emu/yuzu/wiki/Building-For-Windows)
|
||||||
|
|
2
dist/languages/.gitignore
vendored
Normal file
2
dist/languages/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Ignore the source language file
|
||||||
|
en.ts
|
8
dist/languages/.tx/config
vendored
Normal file
8
dist/languages/.tx/config
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[main]
|
||||||
|
host = https://www.transifex.com
|
||||||
|
|
||||||
|
[yuzu.emulator]
|
||||||
|
file_filter = <lang>.ts
|
||||||
|
source_file = en.ts
|
||||||
|
source_lang = en
|
||||||
|
type = QT
|
1
dist/languages/README.md
vendored
Normal file
1
dist/languages/README.md
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This directory stores translation patches (TS files) for yuzu Qt frontend. This directory is linked with [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu), so you can update the translation by executing `tx pull -a`. If you want to contribute to the translation, please go the transifex link and submit your translation there. This directory on the main repo will be synchronized with transifex periodically. Do not directly open PRs on github to modify the translation.
|
|
@ -133,12 +133,45 @@ file(GLOB COMPAT_LIST
|
||||||
file(GLOB_RECURSE ICONS ${PROJECT_SOURCE_DIR}/dist/icons/*)
|
file(GLOB_RECURSE ICONS ${PROJECT_SOURCE_DIR}/dist/icons/*)
|
||||||
file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*)
|
file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*)
|
||||||
|
|
||||||
|
if (ENABLE_QT_TRANSLATION)
|
||||||
|
set(YUZU_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend")
|
||||||
|
option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF)
|
||||||
|
|
||||||
|
# Update source TS file if enabled
|
||||||
|
if (GENERATE_QT_TRANSLATION)
|
||||||
|
get_target_property(SRCS yuzu SOURCES)
|
||||||
|
qt5_create_translation(QM_FILES ${SRCS} ${UIS} ${YUZU_QT_LANGUAGES}/en.ts)
|
||||||
|
add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Find all TS files except en.ts
|
||||||
|
file(GLOB_RECURSE LANGUAGES_TS ${YUZU_QT_LANGUAGES}/*.ts)
|
||||||
|
list(REMOVE_ITEM LANGUAGES_TS ${YUZU_QT_LANGUAGES}/en.ts)
|
||||||
|
|
||||||
|
# Compile TS files to QM files
|
||||||
|
qt5_add_translation(LANGUAGES_QM ${LANGUAGES_TS})
|
||||||
|
|
||||||
|
# Build a QRC file from the QM file list
|
||||||
|
set(LANGUAGES_QRC ${CMAKE_CURRENT_BINARY_DIR}/languages.qrc)
|
||||||
|
file(WRITE ${LANGUAGES_QRC} "<RCC><qresource prefix=\"languages\">\n")
|
||||||
|
foreach (QM ${LANGUAGES_QM})
|
||||||
|
get_filename_component(QM_FILE ${QM} NAME)
|
||||||
|
file(APPEND ${LANGUAGES_QRC} "<file>${QM_FILE}</file>\n")
|
||||||
|
endforeach (QM)
|
||||||
|
file(APPEND ${LANGUAGES_QRC} "</qresource></RCC>")
|
||||||
|
|
||||||
|
# Add the QRC file to package in all QM files
|
||||||
|
qt5_add_resources(LANGUAGES ${LANGUAGES_QRC})
|
||||||
|
else()
|
||||||
|
set(LANGUAGES)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_sources(yuzu
|
target_sources(yuzu
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${COMPAT_LIST}
|
${COMPAT_LIST}
|
||||||
${ICONS}
|
${ICONS}
|
||||||
${THEMES}
|
${THEMES}
|
||||||
|
${LANGUAGES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
|
|
@ -611,6 +611,7 @@ void Config::ReadPathValues() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UISettings::values.recent_files = ReadSetting(QStringLiteral("recentFiles")).toStringList();
|
UISettings::values.recent_files = ReadSetting(QStringLiteral("recentFiles")).toStringList();
|
||||||
|
UISettings::values.language = ReadSetting(QStringLiteral("language"), QString{}).toString();
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
@ -1095,6 +1096,7 @@ void Config::SavePathValues() {
|
||||||
}
|
}
|
||||||
qt_config->endArray();
|
qt_config->endArray();
|
||||||
WriteSetting(QStringLiteral("recentFiles"), UISettings::values.recent_files);
|
WriteSetting(QStringLiteral("recentFiles"), UISettings::values.recent_files);
|
||||||
|
WriteSetting(QStringLiteral("language"), UISettings::values.language, QString{});
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry)
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
PopulateSelectionList();
|
PopulateSelectionList();
|
||||||
|
|
||||||
|
connect(ui->uiTab, &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
|
||||||
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
|
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
|
||||||
&ConfigureDialog::UpdateVisibleTabs);
|
&ConfigureDialog::UpdateVisibleTabs);
|
||||||
|
|
||||||
|
@ -98,6 +99,14 @@ void ConfigureDialog::PopulateSelectionList() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureDialog::OnLanguageChanged(const QString& locale) {
|
||||||
|
emit LanguageChanged(locale);
|
||||||
|
// first apply the configuration, and then restore the display
|
||||||
|
ApplyConfiguration();
|
||||||
|
RetranslateUI();
|
||||||
|
SetConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigureDialog::UpdateVisibleTabs() {
|
void ConfigureDialog::UpdateVisibleTabs() {
|
||||||
const auto items = ui->selectorList->selectedItems();
|
const auto items = ui->selectorList->selectedItems();
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
|
|
|
@ -22,6 +22,12 @@ public:
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void OnLanguageChanged(const QString& locale);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void LanguageChanged(const QString& locale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <QDirIterator>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "ui_configure_ui.h"
|
#include "ui_configure_ui.h"
|
||||||
|
@ -28,6 +29,23 @@ constexpr std::array row_text_names{
|
||||||
|
|
||||||
ConfigureUi::ConfigureUi(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureUi) {
|
ConfigureUi::ConfigureUi(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureUi) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
ui->language_combobox->addItem(tr("<System>"), QString{});
|
||||||
|
ui->language_combobox->addItem(tr("English"), QStringLiteral("en"));
|
||||||
|
QDirIterator it(QStringLiteral(":/languages"), QDirIterator::NoIteratorFlags);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
QString locale = it.next();
|
||||||
|
locale.truncate(locale.lastIndexOf(QLatin1Char{'.'}));
|
||||||
|
locale.remove(0, locale.lastIndexOf(QLatin1Char{'/'}) + 1);
|
||||||
|
QString lang = QLocale::languageToString(QLocale(locale).language());
|
||||||
|
ui->language_combobox->addItem(lang, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlike other configuration changes, interface language changes need to be reflected on the
|
||||||
|
// interface immediately. This is done by passing a signal to the main window, and then
|
||||||
|
// retranslating when passing back.
|
||||||
|
connect(ui->language_combobox,
|
||||||
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||||
|
&ConfigureUi::OnLanguageChanged);
|
||||||
|
|
||||||
for (const auto& theme : UISettings::themes) {
|
for (const auto& theme : UISettings::themes) {
|
||||||
ui->theme_combobox->addItem(QString::fromUtf8(theme.first),
|
ui->theme_combobox->addItem(QString::fromUtf8(theme.first),
|
||||||
|
@ -72,6 +90,8 @@ void ConfigureUi::RequestGameListUpdate() {
|
||||||
|
|
||||||
void ConfigureUi::SetConfiguration() {
|
void ConfigureUi::SetConfiguration() {
|
||||||
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
|
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
|
||||||
|
ui->language_combobox->setCurrentIndex(
|
||||||
|
ui->language_combobox->findData(UISettings::values.language));
|
||||||
ui->show_add_ons->setChecked(UISettings::values.show_add_ons);
|
ui->show_add_ons->setChecked(UISettings::values.show_add_ons);
|
||||||
ui->icon_size_combobox->setCurrentIndex(
|
ui->icon_size_combobox->setCurrentIndex(
|
||||||
ui->icon_size_combobox->findData(UISettings::values.icon_size));
|
ui->icon_size_combobox->findData(UISettings::values.icon_size));
|
||||||
|
@ -147,3 +167,10 @@ void ConfigureUi::UpdateSecondRowComboBox(bool init) {
|
||||||
ui->row_2_text_combobox->removeItem(
|
ui->row_2_text_combobox->removeItem(
|
||||||
ui->row_2_text_combobox->findData(ui->row_1_text_combobox->currentData()));
|
ui->row_2_text_combobox->findData(ui->row_1_text_combobox->currentData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureUi::OnLanguageChanged(int index) {
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit LanguageChanged(ui->language_combobox->itemData(index).toString());
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,12 @@ public:
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void OnLanguageChanged(int index);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void LanguageChanged(const QString& locale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RequestGameListUpdate();
|
void RequestGameListUpdate();
|
||||||
|
|
||||||
|
|
|
@ -13,112 +13,132 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="HorizontalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="VerticalLayout">
|
<widget class="QGroupBox" name="general_groupBox">
|
||||||
<item>
|
<property name="title">
|
||||||
<widget class="QGroupBox" name="GeneralGroupBox">
|
<string>General</string>
|
||||||
<property name="title">
|
</property>
|
||||||
<string>General</string>
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
</property>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<widget class="QLabel" name="label_change_language_info">
|
||||||
<item>
|
<property name="text">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<string>Note: Changing language will apply your configuration.</string>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QLabel" name="theme_label">
|
<property name="wordWrap">
|
||||||
<property name="text">
|
<bool>true</bool>
|
||||||
<string>Theme:</string>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="theme_combobox"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="GameListGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Game List</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="GameListHorizontalLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="GeneralVerticalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="show_add_ons">
|
<widget class="QLabel" name="language_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show Add-Ons Column</string>
|
<string>Interface language:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="icon_size_qhbox_layout_2">
|
<widget class="QComboBox" name="language_combobox"/>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QLabel" name="icon_size_label">
|
</layout>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>Icon Size:</string>
|
<item>
|
||||||
</property>
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QLabel" name="theme_label">
|
||||||
<item>
|
<property name="text">
|
||||||
<widget class="QComboBox" name="icon_size_combobox"/>
|
<string>Theme:</string>
|
||||||
</item>
|
</property>
|
||||||
</layout>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="row_1_qhbox_layout">
|
<widget class="QComboBox" name="theme_combobox"/>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="row_1_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Row 1 Text:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="row_1_text_combobox"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="row_2_qhbox_layout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="row_2_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Row 2 Text:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="row_2_text_combobox"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
</layout>
|
||||||
<item>
|
</widget>
|
||||||
<spacer name="verticalSpacer">
|
</item>
|
||||||
<property name="orientation">
|
<item>
|
||||||
<enum>Qt::Vertical</enum>
|
<widget class="QGroupBox" name="GameListGroupBox">
|
||||||
</property>
|
<property name="title">
|
||||||
<property name="sizeHint" stdset="0">
|
<string>Game List</string>
|
||||||
<size>
|
</property>
|
||||||
<width>20</width>
|
<layout class="QHBoxLayout" name="GameListHorizontalLayout">
|
||||||
<height>40</height>
|
<item>
|
||||||
</size>
|
<layout class="QVBoxLayout" name="GeneralVerticalLayout">
|
||||||
</property>
|
<item>
|
||||||
</spacer>
|
<widget class="QCheckBox" name="show_add_ons">
|
||||||
</item>
|
<property name="text">
|
||||||
</layout>
|
<string>Show Add-Ons Column</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="icon_size_qhbox_layout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="icon_size_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Icon Size:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="icon_size_combobox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="row_1_qhbox_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="row_1_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Row 1 Text:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="row_1_text_combobox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="row_2_qhbox_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="row_2_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Row 2 Text:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="row_2_text_combobox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -191,6 +191,8 @@ GMainWindow::GMainWindow()
|
||||||
provider(std::make_unique<FileSys::ManualContentProvider>()) {
|
provider(std::make_unique<FileSys::ManualContentProvider>()) {
|
||||||
InitializeLogging();
|
InitializeLogging();
|
||||||
|
|
||||||
|
LoadTranslation();
|
||||||
|
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
statusBar()->hide();
|
statusBar()->hide();
|
||||||
|
@ -2048,6 +2050,9 @@ void GMainWindow::OnConfigure() {
|
||||||
const bool old_discord_presence = UISettings::values.enable_discord_presence;
|
const bool old_discord_presence = UISettings::values.enable_discord_presence;
|
||||||
|
|
||||||
ConfigureDialog configure_dialog(this, hotkey_registry);
|
ConfigureDialog configure_dialog(this, hotkey_registry);
|
||||||
|
connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this,
|
||||||
|
&GMainWindow::OnLanguageChanged);
|
||||||
|
|
||||||
const auto result = configure_dialog.exec();
|
const auto result = configure_dialog.exec();
|
||||||
if (result != QDialog::Accepted) {
|
if (result != QDialog::Accepted) {
|
||||||
return;
|
return;
|
||||||
|
@ -2620,6 +2625,43 @@ void GMainWindow::UpdateUITheme() {
|
||||||
QIcon::setThemeSearchPaths(theme_paths);
|
QIcon::setThemeSearchPaths(theme_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GMainWindow::LoadTranslation() {
|
||||||
|
// If the selected language is English, no need to install any translation
|
||||||
|
if (UISettings::values.language == QStringLiteral("en")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loaded;
|
||||||
|
|
||||||
|
if (UISettings::values.language.isEmpty()) {
|
||||||
|
// If the selected language is empty, use system locale
|
||||||
|
loaded = translator.load(QLocale(), {}, {}, QStringLiteral(":/languages/"));
|
||||||
|
} else {
|
||||||
|
// Otherwise load from the specified file
|
||||||
|
loaded = translator.load(UISettings::values.language, QStringLiteral(":/languages/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loaded) {
|
||||||
|
qApp->installTranslator(&translator);
|
||||||
|
} else {
|
||||||
|
UISettings::values.language = QStringLiteral("en");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::OnLanguageChanged(const QString& locale) {
|
||||||
|
if (UISettings::values.language != QStringLiteral("en")) {
|
||||||
|
qApp->removeTranslator(&translator);
|
||||||
|
}
|
||||||
|
|
||||||
|
UISettings::values.language = locale;
|
||||||
|
LoadTranslation();
|
||||||
|
ui.retranslateUi(this);
|
||||||
|
UpdateWindowTitle();
|
||||||
|
|
||||||
|
if (emulation_running)
|
||||||
|
ui.action_Start->setText(tr("Continue"));
|
||||||
|
}
|
||||||
|
|
||||||
void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
|
void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
|
||||||
#ifdef USE_DISCORD_PRESENCE
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
if (state) {
|
if (state) {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -225,6 +226,7 @@ private slots:
|
||||||
void OnCaptureScreenshot();
|
void OnCaptureScreenshot();
|
||||||
void OnCoreError(Core::System::ResultStatus, std::string);
|
void OnCoreError(Core::System::ResultStatus, std::string);
|
||||||
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
|
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
|
||||||
|
void OnLanguageChanged(const QString& locale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
|
std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
|
||||||
|
@ -237,6 +239,7 @@ private:
|
||||||
void HideMouseCursor();
|
void HideMouseCursor();
|
||||||
void ShowMouseCursor();
|
void ShowMouseCursor();
|
||||||
void OpenURL(const QUrl& url);
|
void OpenURL(const QUrl& url);
|
||||||
|
void LoadTranslation();
|
||||||
|
|
||||||
Ui::MainWindow ui;
|
Ui::MainWindow ui;
|
||||||
|
|
||||||
|
@ -285,6 +288,8 @@ private:
|
||||||
|
|
||||||
HotkeyRegistry hotkey_registry;
|
HotkeyRegistry hotkey_registry;
|
||||||
|
|
||||||
|
QTranslator translator;
|
||||||
|
|
||||||
// Install progress dialog
|
// Install progress dialog
|
||||||
QProgressDialog* install_progress;
|
QProgressDialog* install_progress;
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct Values {
|
||||||
bool game_dir_deprecated_deepscan;
|
bool game_dir_deprecated_deepscan;
|
||||||
QVector<UISettings::GameDir> game_dirs;
|
QVector<UISettings::GameDir> game_dirs;
|
||||||
QStringList recent_files;
|
QStringList recent_files;
|
||||||
|
QString language;
|
||||||
|
|
||||||
QString theme;
|
QString theme;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue