Skip to content

Commit fc7881e

Browse files
committed
GUI - Add language section to toolbar; move the language setting to its own tab in the SettingsWidget; fix bugs from renaming source files
Also, when the user selects 'System language', we now show them the list of detected system languages, and show them which one is in use,
1 parent 74d19df commit fc7881e

File tree

6 files changed

+134
-70
lines changed

6 files changed

+134
-70
lines changed

app/gui/qt/mainwindow.cpp

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,39 +2199,6 @@ void MainWindow::changeSystemPreAmp(int val, int silent)
21992199
statusBar()->showMessage(tr("Updating System Volume..."), 2000);
22002200
}
22012201

2202-
// TODO: Implement real-time language switching
2203-
void MainWindow::changeUILanguage(QString lang) {
2204-
if (lang != piSettings->language) {
2205-
std::cout << "Current language: " << piSettings->language.toUtf8().constData() << std::endl;
2206-
std::cout << "New language selected: " << lang.toUtf8().constData() << std::endl;
2207-
QString old_lang = sonicPii18n->getNativeLanguageName(piSettings->language);
2208-
QString new_lang = sonicPii18n->getNativeLanguageName(lang);
2209-
2210-
// Load new language
2211-
//QString language = sonicPii18n->determineUILanguage(lang);
2212-
//sonicPii18n->loadTranslations(language);
2213-
//QString title_new = tr("Updated the UI language from %s to %s").arg();
2214-
2215-
QMessageBox msgBox(this);
2216-
msgBox.setText(QString(tr("You've selected a new language: %1")).arg(new_lang));
2217-
msgBox.setInformativeText(tr("Do you want to apply this language?\nApplying the new language will restart Sonic Pi."));
2218-
QPushButton *restartButton = msgBox.addButton(tr("Apply and Restart"), QMessageBox::ActionRole);
2219-
QPushButton *dismissButton = msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
2220-
msgBox.setDefaultButton(restartButton);
2221-
msgBox.setIcon(QMessageBox::Information);
2222-
msgBox.exec();
2223-
2224-
if (msgBox.clickedButton() == (QAbstractButton*)restartButton) {
2225-
piSettings->language = lang;
2226-
restartApp();
2227-
} else if (msgBox.clickedButton() == (QAbstractButton*)dismissButton) {
2228-
// Don't apply the new language settings
2229-
settingsWidget->updateSelectedUILanguage(piSettings->language);
2230-
}
2231-
2232-
}
2233-
}
2234-
22352202
void MainWindow::changeScopeKindVisibility(QString name)
22362203
{
22372204
foreach (QAction* action, scopeKindVisibilityMenu->actions())
@@ -3356,6 +3323,39 @@ void MainWindow::createToolBar()
33563323
viewMenu->addAction(focusHelpListingAct);
33573324
viewMenu->addAction(focusHelpDetailsAct);
33583325
viewMenu->addAction(focusErrorsAct);
3326+
3327+
languageMenu = menuBar()->addMenu(tr("Language"));
3328+
QStringList available_languages = sonicPii18n->getAvailableLanguages();
3329+
3330+
langActionGroup = new QActionGroup(this);
3331+
langActionGroup->setExclusionPolicy(QActionGroup::ExclusionPolicy::Exclusive);
3332+
3333+
QSignalMapper *signalMapper = new QSignalMapper(this);
3334+
3335+
for (size_t i = 0; i < available_languages.length(); i += 1) {
3336+
bool is_current_lang = (available_languages[i] == piSettings->language);
3337+
3338+
QAction *langAct = new QAction(sonicPii18n->getNativeLanguageName(available_languages[i]), this);
3339+
langAct->setCheckable(true);
3340+
langAct->setChecked(is_current_lang);
3341+
3342+
connect(langAct, SIGNAL(triggered()), signalMapper, SLOT(map()));
3343+
signalMapper->setMapping(langAct, i);
3344+
3345+
langActionGroup->addAction(langAct);
3346+
languageMenu->addAction(langAct);
3347+
3348+
if (i == 0) { // add separator after System language
3349+
languageMenu->addSeparator();
3350+
}
3351+
}
3352+
3353+
connect(signalMapper, SIGNAL(mappedInt(int)), settingsWidget, SLOT(updateUILanguage(int)));
3354+
connect(settingsWidget, SIGNAL(uiLanguageChanged(QString)), this, SLOT(updateSelectedUILanguageAction(QString)));
3355+
}
3356+
3357+
void MainWindow::updateSelectedUILanguageAction(QString lang) {
3358+
langActionGroup->actions()[sonicPii18n->getAvailableLanguages().indexOf(lang)]->setChecked(true);
33593359
}
33603360

33613361
QString MainWindow::readFile(QString name)

app/gui/qt/mainwindow.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "config.h"
3535

3636
class QAction;
37+
class QActionGroup;
3738
class QMenu;
3839
class QToolBar;
3940
class QLineEdit;
@@ -141,7 +142,7 @@ class MainWindow : public QMainWindow
141142

142143
private slots:
143144

144-
void changeUILanguage(QString lang);
145+
void updateSelectedUILanguageAction(QString lang);
145146
void updateContext(int line, int index);
146147
void updateContextWithCurrentWs();
147148
void docLinkClicked(const QUrl &url);
@@ -335,7 +336,7 @@ class MainWindow : public QMainWindow
335336
std::string number_name(int);
336337
std::string workspaceFilename(SonicPiScintilla* text);
337338
SonicPiScintilla* filenameToWorkspace(std::string filename);
338-
339+
339340
bool sendOSC(oscpkt::Message m);
340341
// void initPrefsWindow();
341342
void initDocsWindow();
@@ -360,7 +361,7 @@ class MainWindow : public QMainWindow
360361
void addUniversalCopyShortcuts(QTextEdit *te);
361362
void updateTranslatedUIText();
362363

363-
QMenu *liveMenu, *codeMenu, *audioMenu, *displayMenu, *viewMenu, *ioMenu, *ioMidiInMenu, *ioMidiOutMenu, *ioMidiOutChannelMenu, *localIpAddressesMenu, *themeMenu, *scopeKindVisibilityMenu;
364+
QMenu *liveMenu, *codeMenu, *audioMenu, *displayMenu, *viewMenu, *ioMenu, *ioMidiInMenu, *ioMidiOutMenu, *ioMidiOutChannelMenu, *localIpAddressesMenu, *themeMenu, *scopeKindVisibilityMenu, *languageMenu;
364365

365366
SonicPiSettings *piSettings;
366367
SonicPii18n *sonicPii18n;
@@ -422,6 +423,7 @@ class MainWindow : public QMainWindow
422423

423424
QAction *exitAct, *runAct, *stopAct, *saveAsAct, *loadFileAct, *recAct, *textAlignAct, *textIncAct, *textDecAct, *scopeAct, *infoAct, *helpAct, *prefsAct, *focusEditorAct, *focusLogsAct, *focusContextAct, *focusCuesAct, *focusPreferencesAct, *focusHelpListingAct, *focusHelpDetailsAct, *focusErrorsAct, *showLineNumbersAct, *showAutoCompletionAct, *showContextAct, *audioSafeAct, *audioTimingGuaranteesAct, *enableExternalSynthsAct, *mixerInvertStereoAct, *mixerForceMonoAct, *midiEnabledAct, *enableOSCServerAct, *allowRemoteOSCAct, *showLogAct, *showCuesAct, *logAutoScrollAct, *logCuesAct, *logSynthsAct, *clearOutputOnRunAct, *autoIndentOnRunAct, *showButtonsAct, *showTabsAct, *fullScreenAct, *lightThemeAct, *darkThemeAct, *proLightThemeAct, *proDarkThemeAct, *highContrastThemeAct, *showScopeLabelsAct;
424425
QShortcut *runSc, *stopSc, *saveAsSc, *loadFileSc, *recSc, *textAlignSc, *textIncSc, *textDecSc, *scopeSc, *infoSc, *helpSc, *prefsSc, *focusEditorSc, *focusLogsSc, *focusContextSc, *focusCuesSc, *focusPreferencesSc, *focusHelpListingSc, *focusHelpDetailsSc, *focusErrorsSc;
426+
QActionGroup *langActionGroup;
425427

426428
SettingsWidget *settingsWidget;
427429

app/gui/qt/utils/sonicpi_i18n.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,28 @@
1313

1414
SonicPii18n::SonicPii18n(QString rootpath) {
1515
this->root_path = rootpath;
16+
this->system_languages = findSystemLanguages();
1617
this->system_language_available = true; // Set to true unless we can't load the system language
17-
1818
this->available_languages = findAvailableLanguages();
19+
this->currently_loaded_language = "en";
20+
21+
1922
//checkAllTranslations(); // For testing and debugging purposes
2023
}
2124

2225
SonicPii18n::~SonicPii18n() {
2326
}
2427

28+
QStringList SonicPii18n::findSystemLanguages() {
29+
QLocale locale;
30+
QStringList preferred_languages = locale.uiLanguages();
31+
std::cout << "Looping through preferred ui languages" << std::endl;
32+
for (int i = 0; i < preferred_languages.length(); i += 1) {
33+
preferred_languages[i] = preferred_languages[i].replace("-", "_");
34+
}
35+
return preferred_languages;
36+
}
37+
2538
QString SonicPii18n::determineUILanguage(QString lang_pref) {
2639
QStringList available_languages = getAvailableLanguages();
2740
//std::cout << available_languages.join("\n").toUtf8().constData() << std::endl;
@@ -42,7 +55,7 @@ QString SonicPii18n::determineUILanguage(QString lang_pref) {
4255
}
4356
} else {
4457
QStringList preferred_languages = locale.uiLanguages();
45-
// If the specified language isn't available, or if the setting is set to system_language...
58+
// If the setting is set to system_language...
4659
// ...run through the list of preferred languages
4760
std::cout << "Looping through preferred ui languages" << std::endl;
4861

@@ -108,11 +121,15 @@ bool SonicPii18n::loadTranslations(QString lang) {
108121
qtTranslator.load("qt_" + language, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
109122
app->installTranslator(&qtTranslator);
110123

124+
this->currently_loaded_language = language;
125+
111126
return i18n;
112127
}
113128

114129
QStringList SonicPii18n::getAvailableLanguages() {
115-
return this->available_languages;
130+
QStringList list = this->available_languages;
131+
list.prepend("system_language");
132+
return list;
116133
}
117134

118135
std::map<QString, QString> SonicPii18n::getNativeLanguageNameList() {
@@ -142,6 +159,14 @@ QString SonicPii18n::getNativeLanguageName(QString lang) {
142159
}
143160
}
144161

162+
QStringList SonicPii18n::getNativeLanguageNames(QStringList languages) {
163+
QStringList language_names;
164+
for (size_t i = 0; i < languages.length(); i += 1) {
165+
language_names << getNativeLanguageName(languages[i]);
166+
}
167+
return language_names;
168+
}
169+
145170
// For testing and debugging purposes
146171
bool SonicPii18n::checkAllTranslations() {
147172
QStringList failed_to_load = QStringList();

app/gui/qt/utils/sonicpi_i18n.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,18 @@ class SonicPii18n : public QObject {
2222
SonicPii18n(QString rootpath);
2323
~SonicPii18n();
2424

25+
QStringList system_languages;
26+
bool system_language_available;
27+
QString currently_loaded_language;
28+
2529
public slots:
2630
QString determineUILanguage(QString lang_pref);
2731
QStringList getAvailableLanguages();
2832
std::map<QString, QString> getNativeLanguageNameList();
2933
QString getNativeLanguageName(QString lang);
34+
QStringList getNativeLanguageNames(QStringList languages);
3035
bool loadTranslations(QString lang);
3136

32-
bool system_language_available;
33-
3437
private:
3538
QString root_path;
3639
QTranslator qtTranslator;
@@ -39,6 +42,7 @@ public slots:
3942
static std::map<QString, QString> native_language_names;
4043

4144
QStringList findAvailableLanguages();
45+
QStringList findSystemLanguages();
4246
bool checkAllTranslations();
4347
};
4448
#endif

app/gui/qt/widgets/settingswidget.cpp

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "settingswidget.h"
2-
#include "utils/sonic_pi_i18n.h"
2+
#include "utils/sonicpi_i18n.h"
33

44
#include <QSettings>
55
#include <QVBoxLayout>
@@ -28,7 +28,6 @@ SettingsWidget::SettingsWidget(int port, bool i18n, SonicPiSettings *piSettings,
2828
this->sonicPii18n = sonicPii18n;
2929
this->localeNames = sonicPii18n->getNativeLanguageNameList();
3030
this->available_languages = sonicPii18n->getAvailableLanguages();
31-
available_languages.prepend("system_language");
3231
server_osc_cues_port = port;
3332

3433
prefTabs = new QTabWidget();
@@ -51,6 +50,9 @@ SettingsWidget::SettingsWidget(int port, bool i18n, SonicPiSettings *piSettings,
5150
QGroupBox *update_prefs_box = createUpdatePrefsTab();
5251
prefTabs->addTab(update_prefs_box, tr("Updates"));
5352

53+
QGroupBox *language_prefs_box = createLanguagePrefsTab();
54+
prefTabs->addTab(language_prefs_box, tr("Language"));
55+
5456
if (!sonicPii18n->system_language_available) {
5557
QGroupBox *translation_box = new QGroupBox("Translation");
5658
QVBoxLayout *translation_box_layout = new QVBoxLayout;
@@ -374,34 +376,12 @@ QGroupBox* SettingsWidget::createEditorPrefsTab() {
374376
debug_box->setLayout(debug_box_layout);
375377

376378

377-
QGroupBox *language_box = new QGroupBox(tr("Language"));
378-
language_box->setToolTip(tr("Configure language settings"));
379-
380-
language_combo = new QComboBox();
381-
add_language_combo_box_entries(language_combo);
382-
language_combo->setToolTip(tr("Change the language of the UI & Tutorial (Requires a restart to take effect)"));
383-
language_combo->setMinimumContentsLength(2);
384-
language_combo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
385-
386-
language_option_label = new QLabel;
387-
language_option_label->setText(tr("UI & Tutorial Language (Requires a restart to take effect)"));
388-
language_option_label->setToolTip(tr("Change the language of the UI & Tutorial (Requires a restart to take effect)"));
389-
390-
language_info_label = new QLabel;
391-
language_info_label->setText(tr("Translations have been generously provided by volunteers \non https://hosted.weblate.org/projects/sonic-pi/. Thank you! :)"));
392-
393-
QVBoxLayout *language_box_layout = new QVBoxLayout;
394-
language_box_layout->addWidget(language_combo);
395-
language_box_layout->addWidget(language_option_label);
396-
language_box_layout->addWidget(language_info_label);
397-
398-
language_box->setLayout(language_box_layout);
399379

400380
gridEditorPrefs->addWidget(editor_display_box, 0, 0);
401381
gridEditorPrefs->addWidget(editor_look_feel_box, 0, 1);
402382
gridEditorPrefs->addWidget(automation_box, 1, 1);
403383
gridEditorPrefs->addWidget(debug_box, 1, 0);
404-
gridEditorPrefs->addWidget(language_box, 2, 0, 1, 2);
384+
405385

406386
editor_box->setLayout(gridEditorPrefs);
407387
return editor_box;
@@ -496,6 +476,42 @@ QGroupBox* SettingsWidget::createUpdatePrefsTab() {
496476
return update_prefs_box;
497477
}
498478

479+
/**
480+
* create Language Preferences Tab of Settings Widget
481+
*/
482+
QGroupBox* SettingsWidget::createLanguagePrefsTab() {
483+
QGroupBox *language_box = new QGroupBox(tr("Language"));
484+
language_box->setToolTip(tr("Configure language settings"));
485+
QSizePolicy languagePrefSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
486+
language_box->setSizePolicy(languagePrefSizePolicy);
487+
488+
language_option_label = new QLabel;
489+
language_option_label->setText(tr("UI & Tutorial Language (Requires a restart to take effect)"));
490+
language_option_label->setToolTip(tr("Change the language of the UI & Tutorial (Requires a restart to take effect)"));
491+
492+
language_combo = new QComboBox();
493+
add_language_combo_box_entries(language_combo);
494+
language_combo->setToolTip(tr("Change the language of the UI & Tutorial (Requires a restart to take effect)"));
495+
language_combo->setMinimumContentsLength(2);
496+
language_combo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
497+
498+
language_info_label = new QLabel;
499+
language_info_label->setText(tr("Translations have been generously provided by volunteers \non https://hosted.weblate.org/projects/sonic-pi/. Thank you! :)"));
500+
501+
QVBoxLayout *language_box_layout = new QVBoxLayout;
502+
503+
language_box_layout->addWidget(language_option_label);
504+
language_box_layout->addWidget(language_combo);
505+
language_box_layout->addWidget(language_info_label);
506+
507+
language_box->setLayout(language_box_layout);
508+
509+
QGroupBox *language_prefs_box = new QGroupBox();
510+
QGridLayout *language_prefs_box_layout = new QGridLayout;
511+
language_prefs_box_layout->addWidget(language_box, 0, 0, 0, 0);
512+
language_prefs_box->setLayout(language_prefs_box_layout);
513+
return language_prefs_box;
514+
}
499515

500516
// TODO utils?
501517
QString SettingsWidget::tooltipStrShiftMeta(char key, QString str) {
@@ -556,7 +572,13 @@ void SettingsWidget::updateUILanguage(int index) {
556572

557573
QMessageBox msgBox(this);
558574
msgBox.setText(QString(tr("You've selected a new language: %1")).arg(new_lang));
559-
msgBox.setInformativeText(tr("Do you want to apply this language?") + "\n" + tr("Applying the new language will stop any current runs & recordings, and restart Sonic Pi."));
575+
QString info_text = tr("Do you want to apply this language?") + "\n" + tr("Applying the new language will stop any current runs & recordings, and restart Sonic Pi.");
576+
577+
if (lang == "system_language") {
578+
info_text = tr("System languages found %1").arg(sonicPii18n->getNativeLanguageNames(sonicPii18n->system_languages).join(", ")) + "\n" + info_text;
579+
}
580+
581+
msgBox.setInformativeText(info_text);
560582
QPushButton *restartButton = msgBox.addButton(tr("Apply and Restart"), QMessageBox::ActionRole);
561583
QPushButton *dismissButton = msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
562584
msgBox.setDefaultButton(restartButton);
@@ -570,6 +592,7 @@ void SettingsWidget::updateUILanguage(int index) {
570592
} else if (msgBox.clickedButton() == (QAbstractButton*)dismissButton) {
571593
// Don't apply the new language settings
572594
updateSelectedUILanguage(piSettings->language);
595+
emit uiLanguageChanged(piSettings->language);
573596
}
574597

575598
}
@@ -755,6 +778,13 @@ void SettingsWidget::updateSettings() {
755778

756779
void SettingsWidget::settingsChanged() {
757780
language_combo->setCurrentIndex(available_languages.indexOf(piSettings->language));
781+
if (piSettings->language == "system_language") {
782+
language_info_label->setText(
783+
tr("System languages: %1").arg(sonicPii18n->getNativeLanguageNames(sonicPii18n->system_languages).join(", ")) + "\n" + tr("Current UI language: %1").arg(sonicPii18n->getNativeLanguageName(sonicPii18n->currently_loaded_language))
784+
+ "\n\n" + tr("Translations have been generously provided by volunteers \non https://hosted.weblate.org/projects/sonic-pi/. Thank you! :)")
785+
);
786+
}
787+
758788
mixer_invert_stereo->setChecked(piSettings->mixer_invert_stereo);
759789
mixer_force_mono->setChecked(piSettings->mixer_force_mono);
760790
check_args->setChecked(piSettings->check_args);

0 commit comments

Comments
 (0)