Qt: Add translation support and language setting

This commit is contained in:
Connor McLaughlin 2020-07-28 19:14:44 +10:00
parent bb56b169fc
commit 3edb255eca
4 changed files with 80 additions and 1 deletions

View File

@ -463,6 +463,31 @@ void MainWindow::setupAdditionalUi()
}); });
} }
updateDebugMenuGPURenderer(); updateDebugMenuGPURenderer();
const QString current_language(
QString::fromStdString(m_host_interface->GetStringSettingValue("Main", "Language", "")));
for (const std::pair<QString, QString>& it : m_host_interface->getAvailableLanguageList())
{
QAction* action = m_ui.menuSettingsLanguage->addAction(it.first);
action->setCheckable(true);
action->setChecked(it.second == current_language);
action->setData(it.second);
connect(action, &QAction::triggered, [this, action]() {
const QString new_language = action->data().toString();
m_host_interface->SetStringSettingValue("Main", "Language", new_language.toUtf8().constData());
QMessageBox::information(this, tr("DuckStation"),
tr("Language changed. Please restart the application to apply."));
for (QObject* obj : m_ui.menuSettingsLanguage->children())
{
QAction* other_action = qobject_cast<QAction*>(obj);
if (other_action)
{
QSignalBlocker blocker(other_action);
action->setChecked(other_action == action);
}
}
});
}
} }
void MainWindow::updateEmulationActions(bool starting, bool running) void MainWindow::updateEmulationActions(bool starting, bool running)

View File

@ -90,6 +90,11 @@
<string>Theme</string> <string>Theme</string>
</property> </property>
</widget> </widget>
<widget class="QMenu" name="menuSettingsLanguage">
<property name="title">
<string>Language</string>
</property>
</widget>
<addaction name="actionFullscreen"/> <addaction name="actionFullscreen"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionGeneralSettings"/> <addaction name="actionGeneralSettings"/>
@ -106,6 +111,7 @@
<addaction name="actionScanForNewGames"/> <addaction name="actionScanForNewGames"/>
<addaction name="actionRescanAllGames"/> <addaction name="actionRescanAllGames"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="menuSettingsLanguage"/>
<addaction name="menuSettingsTheme"/> <addaction name="menuSettingsTheme"/>
</widget> </widget>
<widget class="QMenu" name="menuHelp"> <widget class="QMenu" name="menuHelp">

View File

@ -23,7 +23,9 @@
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QEventLoop> #include <QtCore/QEventLoop>
#include <QtCore/QFile>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtCore/QTranslator>
#include <QtWidgets/QMenu> #include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox> #include <QtWidgets/QMessageBox>
#include <algorithm> #include <algorithm>
@ -49,10 +51,19 @@ const char* QtHostInterface::GetFrontendName() const
return "DuckStation Qt Frontend"; return "DuckStation Qt Frontend";
} }
std::vector<std::pair<QString, QString>> QtHostInterface::getAvailableLanguageList()
{
return {{QStringLiteral("English"), QStringLiteral("")}};
}
bool QtHostInterface::Initialize() bool QtHostInterface::Initialize()
{ {
createThread(); createThread();
return m_worker_thread->waitForInit(); if (!m_worker_thread->waitForInit())
return false;
installTranslator();
return true;
} }
void QtHostInterface::Shutdown() void QtHostInterface::Shutdown()
@ -82,6 +93,36 @@ void QtHostInterface::shutdownOnThread()
CommonHostInterface::Shutdown(); CommonHostInterface::Shutdown();
} }
void QtHostInterface::installTranslator()
{
m_translator = std::make_unique<QTranslator>();
std::string language = GetStringSettingValue("Main", "Language", "");
if (language.empty())
return;
const QString path =
QStringLiteral("%1/translations/duckstation-qt_%3.qm").arg(qApp->applicationDirPath()).arg(language.c_str());
if (!QFile::exists(path))
{
QMessageBox::warning(
nullptr, QStringLiteral("Translation Error"),
QStringLiteral("Failed to find translation file for language '%1':\n%2").arg(language.c_str()).arg(path));
return;
}
if (!m_translator->load(path))
{
QMessageBox::warning(
nullptr, QStringLiteral("Translation Error"),
QStringLiteral("Failed to load translation file for language '%1':\n%2").arg(language.c_str()).arg(path));
return;
}
Log_InfoPrintf("Loaded translation file for language '%s'", language.c_str());
qApp->installTranslator(m_translator.get());
}
void QtHostInterface::ReportError(const char* message) void QtHostInterface::ReportError(const char* message)
{ {
HostInterface::ReportError(message); HostInterface::ReportError(message);

View File

@ -22,6 +22,7 @@ class QEventLoop;
class QMenu; class QMenu;
class QWidget; class QWidget;
class QTimer; class QTimer;
class QTranslator;
class GameList; class GameList;
class INISettingsInterface; class INISettingsInterface;
@ -95,6 +96,9 @@ public:
/// Returns a path relative to the application directory (for system files). /// Returns a path relative to the application directory (for system files).
QString getProgramDirectoryRelativePath(const QString& arg) const; QString getProgramDirectoryRelativePath(const QString& arg) const;
/// Returns a list of supported languages and codes (suffixes for translation files).
static std::vector<std::pair<QString, QString>> getAvailableLanguageList();
Q_SIGNALS: Q_SIGNALS:
void errorReported(const QString& message); void errorReported(const QString& message);
void messageReported(const QString& message); void messageReported(const QString& message);
@ -213,6 +217,7 @@ private:
void threadEntryPoint(); void threadEntryPoint();
bool initializeOnThread(); bool initializeOnThread();
void shutdownOnThread(); void shutdownOnThread();
void installTranslator();
void renderDisplay(); void renderDisplay();
void connectDisplaySignals(QtDisplayWidget* widget); void connectDisplaySignals(QtDisplayWidget* widget);
void updateDisplayState(); void updateDisplayState();
@ -222,6 +227,8 @@ private:
std::unique_ptr<INISettingsInterface> m_settings_interface; std::unique_ptr<INISettingsInterface> m_settings_interface;
std::recursive_mutex m_settings_mutex; std::recursive_mutex m_settings_mutex;
std::unique_ptr<QTranslator> m_translator;
MainWindow* m_main_window = nullptr; MainWindow* m_main_window = nullptr;
QThread* m_original_thread = nullptr; QThread* m_original_thread = nullptr;
Thread* m_worker_thread = nullptr; Thread* m_worker_thread = nullptr;