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();
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)

View File

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

View File

@ -23,7 +23,9 @@
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QEventLoop>
#include <QtCore/QFile>
#include <QtCore/QTimer>
#include <QtCore/QTranslator>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox>
#include <algorithm>
@ -49,10 +51,19 @@ const char* QtHostInterface::GetFrontendName() const
return "DuckStation Qt Frontend";
}
std::vector<std::pair<QString, QString>> QtHostInterface::getAvailableLanguageList()
{
return {{QStringLiteral("English"), QStringLiteral("")}};
}
bool QtHostInterface::Initialize()
{
createThread();
return m_worker_thread->waitForInit();
if (!m_worker_thread->waitForInit())
return false;
installTranslator();
return true;
}
void QtHostInterface::Shutdown()
@ -82,6 +93,36 @@ void QtHostInterface::shutdownOnThread()
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)
{
HostInterface::ReportError(message);

View File

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