Add runtime language switching

This commit is contained in:
Cacodemon345
2022-01-08 16:39:51 +06:00
parent 2e06e6cc0c
commit f2f06aa958
8 changed files with 1359 additions and 46 deletions

1170
src/qt/languages/en-US.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin)
#include <iostream>
#include "qt_mainwindow.hpp"
#include "qt_progsettings.hpp"
#include "cocoa_mouse.hpp"
#include "qt_styleoverride.hpp"
@@ -97,30 +98,6 @@ main_thread_fn()
is_quit = 1;
}
class CustomTranslator : public QTranslator
{
protected:
QString translate(const char *context, const char *sourceText,
const char *disambiguation = nullptr, int n = -1) const override
{
if (strcmp(sourceText, "&Fullscreen") == 0) sourceText = "&Fullscreen\tCtrl+Alt+PageUP";
if (strcmp(sourceText, "&Ctrl+Alt+Del") == 0) sourceText = "&Ctrl+Alt+Del\tCtrl+F12";
if (strcmp(sourceText, "Take s&creenshot") == 0) sourceText = "Take s&creenshot\tCtrl+F11";
if (strcmp(sourceText, "&Qt (Software)") == 0)
{
QString finalstr = QTranslator::translate("", "&SDL (Software)", disambiguation, n);
finalstr.replace("SDL", "Qt");
finalstr.replace("(&S)", "(&Q)");
return finalstr;
}
QString finalstr = QTranslator::translate("", sourceText, disambiguation, n);
#ifdef Q_OS_MACOS
if (finalstr.contains('\t')) finalstr.truncate(finalstr.indexOf('\t'));
#endif
return finalstr;
}
};
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
Q_INIT_RESOURCE(qt_resources);
@@ -133,20 +110,7 @@ int main(int argc, char* argv[]) {
while (it.hasNext()) {
qDebug() << it.next() << "\n";
}
QTranslator qtTranslator;
qtTranslator.load(QLocale::system(), QStringLiteral("qt_"), QString(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
if (app.installTranslator(&qtTranslator))
{
qDebug() << "Qt translations loaded." << "\n";
}
CustomTranslator translator;
qDebug() << QLocale::system().name() << "\n";
auto localetofilename = QLocale::system().name().replace('_', '-');
if (translator.load(QLatin1String("86box_"), QLatin1String(":/"), QString(), localetofilename + ".qm"))
{
qDebug() << "Translations loaded.\n";
QCoreApplication::installTranslator(&translator);
}
#ifdef __APPLE__
CocoaEventFilter cocoafilter;
app.installNativeEventFilter(&cocoafilter);
@@ -157,6 +121,7 @@ int main(int argc, char* argv[]) {
{
return 0;
}
ProgSettings::loadTranslators(&app);
if (! pc_init_modules()) {
ui_msgbox_header(MBX_FATAL, (void*)IDS_2120, (void*)IDS_2056);
return 6;

View File

@@ -18,6 +18,7 @@
#include <QElapsedTimer>
#include "qt_mainwindow.hpp"
#include "qt_progsettings.hpp"
#ifdef Q_OS_UNIX
#include <sys/mman.h>
@@ -373,15 +374,49 @@ void set_language(uint32_t id) {
lang_id = id;
}
QMap<uint32_t, QPair<QString, QString>> ProgSettings::lcid_langcode =
{
{0x0405, {"cs-CZ", "Czech (Czech Republic)"} },
{0x0407, {"de-DE", "German (Germany)"} },
{0x0408, {"en-US", "English (United States)"} },
{0x0809, {"en-GB", "English (United Kingdom)"} },
{0x0C0A, {"es-ES", "Spanish (Spain)"} },
{0x040B, {"fi-FI", "Finnish (Finland)"} },
{0x040C, {"fr-FR", "French (France)"} },
{0x041A, {"hr-HR", "Croatian (Croatia)"} },
{0x040E, {"hu-HU", "Hungarian (Hungary)"} },
{0x0410, {"it-IT", "Italian (Italy)"} },
{0x0411, {"ja-JP", "Japanese (Japan)"} },
{0x0412, {"ko-KR", "Korean (Korea)"} },
{0x0416, {"pt-BR", "Portuguese (Brazil)"} },
{0x0816, {"pt-PT", "Portuguese (Portugal)"} },
{0x0419, {"ru-RU", "Russian (Russia)"} },
{0x0424, {"sl-SI", "Slovenian (Slovenia)"} },
{0x041F, {"tr-TR", "Turkish (Turkey)"} },
{0x0804, {"zh-CN", "Chinese (China)"} },
{0xFFFF, {"system", "(System Default)"} },
};
/* Sets up the program language before initialization. */
uint32_t plat_language_code(char* langcode) {
/* or maybe not */
return 0;
for (auto& curKey : ProgSettings::lcid_langcode.keys())
{
if (ProgSettings::lcid_langcode[curKey].first == langcode)
{
return curKey;
}
}
return 0xFFFF;
}
/* Converts back the language code to LCID */
void plat_language_code_r(uint32_t lcid, char* outbuf, int len) {
/* or maybe not */
if (!ProgSettings::lcid_langcode.contains(lcid))
{
qstrncpy(outbuf, "system", len);
return;
}
qstrncpy(outbuf, ProgSettings::lcid_langcode[lcid].first.toUtf8().constData(), len);
return;
}
@@ -489,9 +524,9 @@ size_t c16stombs(char dst[], const uint16_t src[], int len)
#endif
static std::map<int, std::wstring> translatedstrings;
QMap<int, std::wstring> ProgSettings::translatedstrings;
static void reload_strings()
void ProgSettings::reloadStrings()
{
translatedstrings.clear();
translatedstrings[IDS_2077] = QCoreApplication::translate("", "Click to capture mouse").toStdWString();
@@ -536,8 +571,8 @@ static void reload_strings()
wchar_t* plat_get_string(int i)
{
if (translatedstrings.empty()) reload_strings();
return translatedstrings[i].data();
if (ProgSettings::translatedstrings.empty()) ProgSettings::reloadStrings();
return ProgSettings::translatedstrings[i].data();
}
int

View File

@@ -1,3 +1,5 @@
#include <QDebug>
#include "qt_progsettings.hpp"
#include "ui_qt_progsettings.h"
#include "qt_mainwindow.hpp"
@@ -7,6 +9,7 @@
#include <QMap>
#include <QDir>
#include <QFile>
#include <QLibraryInfo>
extern "C"
{
@@ -19,6 +22,8 @@ extern "C"
static QMap<QString, QString> iconset_to_qt;
extern MainWindow* main_window;
ProgSettings::CustomTranslator* ProgSettings::translator = nullptr;
QTranslator* ProgSettings::qtTranslator = nullptr;
QString ProgSettings::getIconSetPath()
{
QString roms_root;
@@ -69,12 +74,29 @@ ProgSettings::ProgSettings(QWidget *parent) :
ui->comboBox->setCurrentIndex(ui->comboBox->findData(i.key()));
}
}
ui->comboBox->setItemData(0, '(' + tr("Default") + ')', Qt::DisplayRole);
ui->comboBoxLanguage->setItemData(0, 0xFFFF);
for (auto i = lcid_langcode.begin() + 1; i != lcid_langcode.end(); i++)
{
if (i.key() == 0xFFFF) continue;
ui->comboBoxLanguage->addItem(lcid_langcode[i.key()].second, i.key());
if (i.key() == lang_id)
{
ui->comboBoxLanguage->setCurrentIndex(ui->comboBoxLanguage->findData(i.key()));
}
}
}
void ProgSettings::accept()
{
strcpy(icon_set, ui->comboBox->currentData().toString().toUtf8().data());
lang_id = ui->comboBoxLanguage->currentData().toUInt();
loadTranslators(QCoreApplication::instance());
reloadStrings();
update_mouse_msg();
main_window->ui->retranslateUi(main_window);
QString msg = main_window->status->getMessage();
main_window->status.reset(new MachineStatus(main_window));
main_window->refreshMediaMenu();
@@ -96,3 +118,50 @@ void ProgSettings::on_pushButton_released()
ui->comboBox->setCurrentIndex(0);
}
void ProgSettings::loadTranslators(QObject *parent)
{
if (qtTranslator)
{
QApplication::removeTranslator(qtTranslator);
qtTranslator = nullptr;
}
if (translator)
{
QApplication::removeTranslator(translator);
translator = nullptr;
}
qtTranslator = new QTranslator(parent);
translator = new CustomTranslator(parent);
QString localetofilename = "";
if (lang_id == 0xFFFF || lcid_langcode.contains(lang_id) == false)
{
for (int i = 0; i < QLocale::system().uiLanguages().size(); i++)
{
localetofilename = QLocale::system().uiLanguages()[i];
if (translator->load(QLatin1String("86box_") + localetofilename, QLatin1String(":/")))
{
qDebug() << "Translations loaded.\n";
QCoreApplication::installTranslator(translator);
qtTranslator->load(QLatin1String("qtbase_") + localetofilename.replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
if (QApplication::installTranslator(qtTranslator))
{
qDebug() << "Qt translations loaded." << "\n";
}
break;
}
}
}
else
{
translator->load(QLatin1String("86box_") + lcid_langcode[lang_id].first, QLatin1String(":/"));
QCoreApplication::installTranslator(translator);
qtTranslator->load(QLatin1String("qtbase_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
QCoreApplication::installTranslator(qtTranslator);
}
}
void ProgSettings::on_pushButtonLanguage_released()
{
ui->comboBoxLanguage->setCurrentIndex(0);
}

View File

@@ -16,11 +16,43 @@ public:
explicit ProgSettings(QWidget *parent = nullptr);
~ProgSettings();
static QString getIconSetPath();
static void loadTranslators(QObject* parent = nullptr);
static void reloadStrings();
class CustomTranslator : public QTranslator
{
public:
CustomTranslator(QObject* parent = nullptr) : QTranslator(parent) {};
protected:
QString translate(const char *context, const char *sourceText,
const char *disambiguation = nullptr, int n = -1) const override
{
if (strcmp(sourceText, "&Fullscreen") == 0) sourceText = "&Fullscreen\tCtrl+Alt+PageUP";
if (strcmp(sourceText, "&Ctrl+Alt+Del") == 0) sourceText = "&Ctrl+Alt+Del\tCtrl+F12";
if (strcmp(sourceText, "Take s&creenshot") == 0) sourceText = "Take s&creenshot\tCtrl+F11";
if (strcmp(sourceText, "&Qt (Software)") == 0)
{
QString finalstr = QTranslator::translate("", "&SDL (Software)", disambiguation, n);
finalstr.replace("SDL", "Qt");
finalstr.replace("(&S)", "(&Q)");
return finalstr;
}
QString finalstr = QTranslator::translate("", sourceText, disambiguation, n);
#ifdef Q_OS_MACOS
if (finalstr.contains('\t')) finalstr.truncate(finalstr.indexOf('\t'));
#endif
return finalstr;
}
};
static CustomTranslator* translator;
static QTranslator* qtTranslator;
static QMap<uint32_t, QPair<QString, QString>> lcid_langcode;
static QMap<int, std::wstring> translatedstrings;
protected slots:
void accept() override;
private slots:
void on_pushButton_released();
void on_pushButtonLanguage_released();
private:
Ui::ProgSettings *ui;

View File

@@ -73,6 +73,47 @@
<string>Default</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>140</y>
<width>91</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Language:</string>
</property>
</widget>
<widget class="QPushButton" name="pushButtonLanguage">
<property name="geometry">
<rect>
<x>290</x>
<y>190</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Default</string>
</property>
</widget>
<widget class="QComboBox" name="comboBoxLanguage">
<property name="geometry">
<rect>
<x>20</x>
<y>160</y>
<width>351</width>
<height>23</height>
</rect>
</property>
<item>
<property name="text">
<string>(System Default)</string>
</property>
</item>
</widget>
</widget>
<resources/>
<connections>

View File

@@ -52,7 +52,7 @@ SettingsMachine::SettingsMachine(QWidget *parent) :
waitStatesModel->setData(idx, 0, Qt::UserRole);
for (int i = 0; i < 8; ++i) {
idx = waitStatesModel->index(i+1, 0);
waitStatesModel->setData(idx, QString("%1 Wait State(s)").arg(i), Qt::DisplayRole);
waitStatesModel->setData(idx, QString::asprintf(tr("%i Wait state(s)").toUtf8().constData(), i), Qt::DisplayRole);
waitStatesModel->setData(idx, i+1, Qt::UserRole);
}

View File

@@ -2,6 +2,7 @@
<qresource prefix="/">
<file>86box_cs-CZ.qm</file>
<file>86box_de-DE.qm</file>
<file>86box_en-US.qm</file>
<file>86box_en-GB.qm</file>
<file>86box_es-ES.qm</file>
<file>86box_fi-FI.qm</file>