From 6fb980ca79176fdd09ed9c5e8b8d046b09b4be5d Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 18 Apr 2017 21:57:32 +0300 Subject: [PATCH] Improve custom language loading. Apply custom language without relaunching the app. --- Telegram/SourceFiles/boxes/language_box.cpp | 29 +++++++++++++++++-- Telegram/SourceFiles/boxes/language_box.h | 2 +- Telegram/SourceFiles/facades.cpp | 4 --- Telegram/SourceFiles/facades.h | 2 -- Telegram/SourceFiles/lang/lang_instance.cpp | 22 ++++++++++++++ Telegram/SourceFiles/lang/lang_instance.h | 4 ++- .../settings/settings_general_widget.cpp | 29 +------------------ .../settings/settings_general_widget.h | 1 - .../SourceFiles/settings/settings_widget.cpp | 2 +- 9 files changed, 54 insertions(+), 41 deletions(-) diff --git a/Telegram/SourceFiles/boxes/language_box.cpp b/Telegram/SourceFiles/boxes/language_box.cpp index 5c0c56b3e..ffc30af9e 100644 --- a/Telegram/SourceFiles/boxes/language_box.cpp +++ b/Telegram/SourceFiles/boxes/language_box.cpp @@ -31,7 +31,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "lang/lang_cloud_manager.h" #include "styles/style_boxes.h" -class LanguageBox::Inner : public TWidget { +class LanguageBox::Inner : public TWidget, private base::Subscriber { public: Inner(QWidget *parent, gsl::not_null languages); @@ -39,6 +39,7 @@ public: void refresh(); private: + void activateCurrent(); void languageChanged(int languageIndex); gsl::not_null _languages; @@ -51,6 +52,9 @@ LanguageBox::Inner::Inner(QWidget *parent, gsl::not_null languages) , _languages(languages) { _group = std::make_shared(0); _group->setChangedCallback([this](int value) { languageChanged(value); }); + subscribe(Lang::Current().updated(), [this] { + activateCurrent(); + }); } void LanguageBox::Inner::setSelected(int index) { @@ -80,12 +84,31 @@ void LanguageBox::Inner::refresh() { void LanguageBox::Inner::languageChanged(int languageIndex) { Expects(languageIndex >= 0 && languageIndex < _languages->size()); + auto currentId = Lang::Current().id(); auto languageId = (*_languages)[languageIndex].id; - if (languageId != qsl("custom")) { + if (languageId == currentId) { + return; + } + + if (languageId == qsl("custom")) { + activateCurrent(); + Lang::Current().chooseCustomFile(); + } else { Lang::CurrentCloudManager().switchToLanguage(languageId); } } +void LanguageBox::Inner::activateCurrent() { + auto currentId = Lang::Current().id(); + for (auto i = 0, count = _languages->size(); i != count; ++i) { + if ((*_languages)[i].id == currentId) { + _group->setValue(i); + return; + } + } + refresh(); +} + void LanguageBox::prepare() { refreshLang(); subscribe(Lang::Current().updated(), [this] { @@ -125,7 +148,7 @@ void LanguageBox::refreshLanguages() { auto currentIndex = -1; _languages.push_back({ qsl("en"), qsl("English") }); for (auto &language : list) { - auto isCurrent = (language.id == currentId); + auto isCurrent = (language.id == currentId) || (language.id == Lang::DefaultLanguageId() && currentId.isEmpty()); if (language.id != qstr("en")) { if (isCurrent) { currentIndex = _languages.size(); diff --git a/Telegram/SourceFiles/boxes/language_box.h b/Telegram/SourceFiles/boxes/language_box.h index d7f1e3879..a34505ebd 100644 --- a/Telegram/SourceFiles/boxes/language_box.h +++ b/Telegram/SourceFiles/boxes/language_box.h @@ -29,7 +29,7 @@ class RadiobuttonGroup; class Radiobutton; } // namespace Ui -class LanguageBox : public BoxContent, private MTP::Sender { +class LanguageBox : public BoxContent, private MTP::Sender { public: LanguageBox(QWidget*) { } diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 1e6cb4471..fb6364e31 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -671,8 +671,6 @@ struct Data { ProxyData ConnectionProxy; base::Observable ConnectionTypeChanged; - base::Observable ChooseCustomLang; - int AutoLock = 3600; bool LocalPasscode = false; base::Observable LocalPasscodeChanged; @@ -793,8 +791,6 @@ DefineVar(Global, bool, TryIPv6); DefineVar(Global, ProxyData, ConnectionProxy); DefineRefVar(Global, base::Observable, ConnectionTypeChanged); -DefineRefVar(Global, base::Observable, ChooseCustomLang); - DefineVar(Global, int, AutoLock); DefineVar(Global, bool, LocalPasscode); DefineRefVar(Global, base::Observable, LocalPasscodeChanged); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 05cbb97a6..c6796a7f0 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -382,8 +382,6 @@ DeclareVar(bool, TryIPv6); DeclareVar(ProxyData, ConnectionProxy); DeclareRefVar(base::Observable, ConnectionTypeChanged); -DeclareRefVar(base::Observable, ChooseCustomLang); - DeclareVar(int, AutoLock); DeclareVar(bool, LocalPasscode); DeclareRefVar(base::Observable, LocalPasscodeChanged); diff --git a/Telegram/SourceFiles/lang/lang_instance.cpp b/Telegram/SourceFiles/lang/lang_instance.cpp index f7fe4216f..7b8dd89a2 100644 --- a/Telegram/SourceFiles/lang/lang_instance.cpp +++ b/Telegram/SourceFiles/lang/lang_instance.cpp @@ -25,6 +25,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "storage/serialize_common.h" #include "storage/localstorage.h" #include "platform/platform_specific.h" +#include "core/file_utilities.h" +#include "boxes/confirm_box.h" namespace Lang { namespace { @@ -239,9 +241,29 @@ void Instance::switchToId(const QString &id) { _id = id; } +void Instance::chooseCustomFile() { + auto filter = qsl("Language files (*.strings)"); + auto title = qsl("Choose language .strings file"); + FileDialog::GetOpenPath(title, filter, [weak = base::weak_unique_ptr(this)](const FileDialog::OpenResult &result) { + if (!weak || result.paths.isEmpty()) { + return; + } + + auto filePath = result.paths.front(); + Lang::FileParser loader(filePath, { lng_language_name }); + if (loader.errors().isEmpty()) { + weak->switchToCustomFile(filePath); + } else { + Ui::show(Box("Custom lang failed :(\n\nError: " + loader.errors())); + } + }); +} + void Instance::switchToCustomFile(const QString &filePath) { reset(); fillFromCustomFile(filePath); + Local::writeLangPack(); + updated().notify(); } void Instance::reset() { diff --git a/Telegram/SourceFiles/lang/lang_instance.h b/Telegram/SourceFiles/lang/lang_instance.h index 3b4bd8c00..e11d280a3 100644 --- a/Telegram/SourceFiles/lang/lang_instance.h +++ b/Telegram/SourceFiles/lang/lang_instance.h @@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #pragma once #include "lang_auto.h" +#include "base/weak_unique_ptr.h" namespace Lang { @@ -33,12 +34,13 @@ QString DefaultLanguageId(); class Instance; Instance &Current(); -class Instance { +class Instance : public base::enable_weak_from_this { public: Instance() { fillDefaults(); } void switchToId(const QString &id); + void chooseCustomFile(); void switchToCustomFile(const QString &filePath); Instance(const Instance &other) = delete; diff --git a/Telegram/SourceFiles/settings/settings_general_widget.cpp b/Telegram/SourceFiles/settings/settings_general_widget.cpp index 728e54b47..e8dfcc1dc 100644 --- a/Telegram/SourceFiles/settings/settings_general_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_general_widget.cpp @@ -160,7 +160,6 @@ void UpdateStateRow::onFailed() { GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_general)) , _changeLanguage(this, lang(lng_settings_change_lang), st::boxLinkButton) { connect(_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage())); - subscribe(Global::RefChooseCustomLang(), [this]() { chooseCustomLang(); }); refreshControls(); } @@ -206,35 +205,9 @@ void GeneralWidget::refreshControls() { } } -void GeneralWidget::chooseCustomLang() { - auto filter = qsl("Language files (*.strings)"); - auto title = qsl("Choose language .strings file"); - FileDialog::GetOpenPath(title, filter, base::lambda_guarded(this, [this](const FileDialog::OpenResult &result) { - if (result.paths.isEmpty()) { - return; - } - - auto filePath = result.paths.front(); - Lang::FileParser loader(filePath, { lng_sure_save_language, lng_cancel, lng_box_ok }); - if (loader.errors().isEmpty()) { - auto result = loader.found(); - auto text = result.value(lng_sure_save_language, Lang::GetOriginalValue(lng_sure_save_language)), - save = result.value(lng_box_ok, Lang::GetOriginalValue(lng_box_ok)), - cancel = result.value(lng_cancel, Lang::GetOriginalValue(lng_cancel)); - Ui::show(Box(text, save, cancel, base::lambda_guarded(this, [this, filePath] { - Lang::Current().switchToCustomFile(filePath); - Local::writeLangPack(); - onRestart(); - }))); - } else { - Ui::show(Box("Custom lang failed :(\n\nError: " + loader.errors())); - } - })); -} - void GeneralWidget::onChangeLanguage() { if ((_changeLanguage->clickModifiers() & Qt::ShiftModifier) && (_changeLanguage->clickModifiers() & Qt::AltModifier)) { - chooseCustomLang(); + Lang::Current().chooseCustomFile(); return; } auto manager = Messenger::Instance().langCloudManager(); diff --git a/Telegram/SourceFiles/settings/settings_general_widget.h b/Telegram/SourceFiles/settings/settings_general_widget.h index 04f9c54ad..71f2260a1 100644 --- a/Telegram/SourceFiles/settings/settings_general_widget.h +++ b/Telegram/SourceFiles/settings/settings_general_widget.h @@ -104,7 +104,6 @@ private slots: private: void refreshControls(); void updateWorkmode(); - void chooseCustomLang(); object_ptr _changeLanguage; #ifndef TDESKTOP_DISABLE_AUTOUPDATE diff --git a/Telegram/SourceFiles/settings/settings_widget.cpp b/Telegram/SourceFiles/settings/settings_widget.cpp index 1d995c93b..6b1196807 100644 --- a/Telegram/SourceFiles/settings/settings_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_widget.cpp @@ -61,7 +61,7 @@ void fillCodes() { })); }); Codes.insert(qsl("loadlang"), [] { - Global::RefChooseCustomLang().notify(); + Lang::Current().chooseCustomFile(); }); Codes.insert(qsl("debugfiles"), [] { if (!cDebug()) return;