diff --git a/src/icons.qrc b/src/icons.qrc index 455b9bc..deb2fb1 100644 --- a/src/icons.qrc +++ b/src/icons.qrc @@ -103,5 +103,7 @@ icons/dark/actions/go-up-search.svg icons/light/actions/go-down-search.svg icons/light/actions/go-up-search.svg + icons/languages/en.svg + icons/languages/ru.svg diff --git a/src/icons/languages/en.svg b/src/icons/languages/en.svg new file mode 100644 index 0000000..9f9328d --- /dev/null +++ b/src/icons/languages/en.svg @@ -0,0 +1,228 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/languages/ru.svg b/src/icons/languages/ru.svg new file mode 100644 index 0000000..7878ce2 --- /dev/null +++ b/src/icons/languages/ru.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/kristall.hpp b/src/kristall.hpp index 49219cf..eac5bdd 100644 --- a/src/kristall.hpp +++ b/src/kristall.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "identitycollection.hpp" #include "ssltrust.hpp" @@ -164,9 +166,15 @@ namespace kristall QDir styles; }; - struct Globals + struct Localization { + QLocale locale; + QTranslator qt; + QTranslator kristall; + }; + struct Globals + { ProtocolSetup protocols; QSettings * settings; @@ -182,6 +190,8 @@ namespace kristall Trust trust; Dirs dirs; + + Localization localization; }; //! returns the instance of the globals structure @@ -222,6 +232,12 @@ namespace kristall //! Saves the current session including all windows, tabs and positions. void saveSession(); + + //! Changes the currently used locale + void setLocale(QLocale const & locale); + + //! Saves the currently used locale + void saveLocale(); } #endif // KRISTALL_HPP diff --git a/src/main.cpp b/src/main.cpp index 8a79d7a..c5c796c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -370,6 +370,24 @@ MainWindow * kristall::openNewWindow(QVector const & urls) } +//! Changes the currently used locale +void kristall::setLocale(QLocale const & locale) +{ + auto & i18n = kristall::globals().localization; + i18n.locale = locale; + i18n.qt.load(i18n.locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + i18n.kristall.load(i18n.locale, "kristall", "_", ":/i18n"); +} + +//! Saves the currently used locale +void kristall::saveLocale() +{ + if(app_settings_ptr == nullptr) + return; + app_settings_ptr->setValue("language", kristall::globals().localization.locale.bcp47Name()); + app_settings_ptr->sync(); +} + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -380,6 +398,28 @@ int main(int argc, char *argv[]) // this is relevant to delete kristall::Globals before the application itself. EnsureGlobalsReset ensure_globals_reset; + // Initialize kristall directories + { + QString cache_root = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + QString config_root = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); + + kristall::globals().dirs.config_root = QDir { config_root }; + kristall::globals().dirs.cache_root = QDir { cache_root }; + + kristall::globals().dirs.offline_pages = derive_dir(kristall::globals().dirs.cache_root, "offline-pages"); + kristall::globals().dirs.themes = derive_dir(kristall::globals().dirs.config_root, "themes"); + + kristall::globals().dirs.styles = derive_dir(kristall::globals().dirs.config_root, "styles"); + kristall::globals().dirs.styles.setNameFilters(QStringList { "*.kthm" }); + kristall::globals().dirs.styles.setFilter(QDir::Files); + } + + QSettings app_settings { + kristall::globals().dirs.config_root.absoluteFilePath("config.ini"), + QSettings::IniFormat + }; + app_settings_ptr = &app_settings; + QObject::connect(&app, &QApplication::focusChanged, [](QWidget *old, QWidget *now) { // Determine the window for both, we're only interested in window focus changes. if(old != nullptr) old = old->window(); @@ -402,11 +442,23 @@ int main(int argc, char *argv[]) } }); - QTranslator trans, qttrans; - qttrans.load(QLocale(), QLatin1String("qt"), "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - trans.load(QLocale(), QLatin1String("kristall"), QLatin1String("_"), QLatin1String(":/i18n")); - app.installTranslator(&qttrans); - app.installTranslator(&trans); + // Initialize localization + { + + // Load the currently selected locale + auto const lang_id = app_settings.value("language", QString()).toString(); + if(not lang_id.isEmpty()) { + kristall::setLocale( QLocale(lang_id) ); + } + else { + kristall::setLocale ( QLocale() ); + } + + auto & i18n = kristall::globals().localization; + app.installTranslator(&i18n.qt); + app.installTranslator(&i18n.kristall); + qDebug() << "current locale" << i18n.locale.nativeLanguageName(); + } addEmojiSubstitutions(); @@ -500,25 +552,6 @@ int main(int argc, char *argv[]) } } - QString cache_root = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); - QString config_root = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); - - kristall::globals().dirs.config_root = QDir { config_root }; - kristall::globals().dirs.cache_root = QDir { cache_root }; - - kristall::globals().dirs.offline_pages = derive_dir(kristall::globals().dirs.cache_root, "offline-pages"); - kristall::globals().dirs.themes = derive_dir(kristall::globals().dirs.config_root, "themes"); - - kristall::globals().dirs.styles = derive_dir(kristall::globals().dirs.config_root, "styles"); - kristall::globals().dirs.styles.setNameFilters(QStringList { "*.kthm" }); - kristall::globals().dirs.styles.setFilter(QDir::Files); - - QSettings app_settings { - kristall::globals().dirs.config_root.absoluteFilePath("config.ini"), - QSettings::IniFormat - }; - app_settings_ptr = &app_settings; - std::unique_ptr session_store; // isolated sessions don't have session management