From 903568d9d6b0c7d95c0924e3d0c7d7c2f0175286 Mon Sep 17 00:00:00 2001 From: evgeny Date: Fri, 16 Oct 2026 15:34:31 +0200 Subject: [PATCH] Apply the selected language immediately in first-run setup --- tools/chatgui/src/main.cpp | 63 +++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/tools/chatgui/src/main.cpp b/tools/chatgui/src/main.cpp index 611da1a8..36cab95d 100644 --- a/tools/chatgui/src/main.cpp +++ b/tools/chatgui/src/main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -190,17 +191,23 @@ int main(int argc, char *argv[]) { } QTranslator guiTranslator, qtTranslator; - const QString language = resolveGuiLanguage(cfg.language()); - if (!guiTranslator.load(":/translations/chatgui_" + language + ".qm") || !app.installTranslator(&guiTranslator)) { - DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "GUI language: failed to load embedded catalog for %s", qPrintable(language)); - return 1; - } - if (language == "ru") { - if (!qtTranslator.load(QStringLiteral(":/translations/qtbase_ru.qm")) || !app.installTranslator(&qtTranslator)) { - DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "GUI language: failed to load embedded Qt Russian catalog"); - return 1; + auto loadLanguage = [&](const QString& selected) { + app.removeTranslator(&guiTranslator); + app.removeTranslator(&qtTranslator); + if (!guiTranslator.load(":/translations/chatgui_" + selected + ".qm") || !app.installTranslator(&guiTranslator)) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "GUI language: failed to load embedded catalog for %s", qPrintable(selected)); + return false; } - } + if (selected == "ru") { + if (!qtTranslator.load(QStringLiteral(":/translations/qtbase_ru.qm")) || !app.installTranslator(&qtTranslator)) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "GUI language: failed to load embedded Qt Russian catalog"); + return false; + } + } + return true; + }; + QString language = resolveGuiLanguage(cfg.language()); + if (!loadLanguage(language)) return 1; if (!locked) { QMessageBox::warning(nullptr, "vibechat", QCoreApplication::translate("ChatGui", "vibechat is already running.")); return 1; @@ -210,23 +217,47 @@ int main(int argc, char *argv[]) { const bool firstRun = !cfg.exists(); if (firstRun) { QDialog wizard; - wizard.setWindowTitle(QCoreApplication::translate("ChatGui", "Welcome to vibechat")); wizard.setMinimumWidth(380); auto* layout = new QVBoxLayout(&wizard); - layout->addWidget(new QLabel(QCoreApplication::translate("ChatGui", "Your nickname:"), &wizard)); + auto* languageLabel = new QLabel(QStringLiteral("Language / Язык"), &wizard); + layout->addWidget(languageLabel); + auto* languageCombo = new QComboBox(&wizard); + languageCombo->addItem(QString(), QStringLiteral("system")); + languageCombo->addItem(QStringLiteral("English"), QStringLiteral("en")); + languageCombo->addItem(QStringLiteral("Русский"), QStringLiteral("ru")); + layout->addWidget(languageCombo); + auto* nicknameLabel = new QLabel(&wizard); + layout->addWidget(nicknameLabel); auto* nickname = new QLineEdit(&wizard); nickname->setMaxLength(32); const QString host = QHostInfo::localHostName(); nickname->setText(host.isEmpty() ? QStringLiteral("vibechat") : host); layout->addWidget(nickname); - auto* hint = new QLabel(QCoreApplication::translate("ChatGui", "Others will see this name. You can change it later in Settings."), &wizard); + auto* hint = new QLabel(&wizard); hint->setWordWrap(true); layout->addWidget(hint); layout->addSpacing(12); auto* buttons = new QDialogButtonBox(QDialogButtonBox::Cancel, &wizard); - auto* start = buttons->addButton(QCoreApplication::translate("ChatGui", "Start chatting"), QDialogButtonBox::AcceptRole); + auto* start = buttons->addButton(QString(), QDialogButtonBox::AcceptRole); start->setDefault(true); layout->addWidget(buttons); + auto translateWizard = [&] { + wizard.setWindowTitle(QCoreApplication::translate("ChatGui", "Welcome to vibechat")); + languageCombo->setItemText(0, QCoreApplication::translate("ChatGui", "System language")); + nicknameLabel->setText(QCoreApplication::translate("ChatGui", "Your nickname:")); + hint->setText(QCoreApplication::translate("ChatGui", "Others will see this name. You can change it later in Settings.")); + start->setText(QCoreApplication::translate("ChatGui", "Start chatting")); + }; + translateWizard(); + bool languageReady = true; + QObject::connect(languageCombo, qOverload(&QComboBox::currentIndexChanged), &wizard, [&](int) { + const QString preference = languageCombo->currentData().toString(); + language = resolveGuiLanguage(preference); + languageReady = loadLanguage(language); + if (!languageReady) { wizard.reject(); return; } + translateWizard(); + DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "First-run setup: language preference=%s selected=%s", qPrintable(preference), qPrintable(language)); + }); QObject::connect(nickname, &QLineEdit::textChanged, &wizard, [start](const QString& text) { start->setEnabled(!text.trimmed().isEmpty()); }); @@ -243,11 +274,13 @@ int main(int argc, char *argv[]) { QObject::connect(buttons, &QDialogButtonBox::rejected, &wizard, &QDialog::reject); nickname->setFocus(); nickname->selectAll(); - DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "First-run setup: requesting nickname, config=%s", qPrintable(cfgPath)); + DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "First-run setup: requesting nickname and language, config=%s", qPrintable(cfgPath)); if (wizard.exec() != QDialog::Accepted) { + if (!languageReady) return 1; DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "First-run setup: cancelled, config not created"); return 0; } + cfg.setLanguage(languageCombo->currentData().toString()); if (!cfg.create(nickname->text().trimmed(), 1333)) { DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "First-run setup: failed to create config=%s", qPrintable(cfgPath)); QMessageBox::critical(nullptr, wizard.windowTitle(),