From a043e2262219763aa25ea4f1d1ac6accc4299e76 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 9 Dec 2022 17:43:47 +0300 Subject: [PATCH] Added internal support of skipping translation for multiple languages. --- Telegram/Resources/langs/lang.strings | 2 + Telegram/SourceFiles/boxes/language_box.cpp | 27 +++++------ Telegram/SourceFiles/boxes/translate_box.cpp | 42 ++++++++++------ Telegram/SourceFiles/boxes/translate_box.h | 3 ++ Telegram/SourceFiles/core/core_settings.cpp | 51 +++++++++++++++----- Telegram/SourceFiles/core/core_settings.h | 7 +-- 6 files changed, 87 insertions(+), 45 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index da44f5438..cb96ca5c3 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -493,6 +493,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_change_lang" = "Change language"; "lng_languages" = "Languages"; "lng_languages_none" = "No languages found."; +"lng_languages_count#one" = "{count} language"; +"lng_languages_count#other" = "{count} languages"; "lng_sure_save_language" = "Telegram will restart in order to change language"; "lng_settings_update_automatically" = "Update automatically"; "lng_settings_install_beta" = "Install beta versions"; diff --git a/Telegram/SourceFiles/boxes/language_box.cpp b/Telegram/SourceFiles/boxes/language_box.cpp index d61721976..1001c6383 100644 --- a/Telegram/SourceFiles/boxes/language_box.cpp +++ b/Telegram/SourceFiles/boxes/language_box.cpp @@ -1117,7 +1117,8 @@ void LanguageBox::prepare() { Core::App().saveSettingsDelayed(); }, translateEnabled->lifetime()); - const auto label = lifetime().make_state>(); + using Locales = std::vector; + const auto label = lifetime().make_state>(); const auto translateSkipWrap = topContainer->add( object_ptr>( topContainer, @@ -1129,28 +1130,24 @@ void LanguageBox::prepare() { const auto translateSkip = Settings::AddButtonWithLabel( translateSkipWrap->entity(), tr::lng_translate_settings_choose(), - label->events() | rpl::map(Ui::LanguageName), + label->events( + ) | rpl::map([](const Locales &locales) { + return (locales.size() > 1) + ? tr::lng_languages_count(tr::now, lt_count, locales.size()) + : Ui::LanguageName(locales.front()); + }), st::settingsButtonNoIcon); - { - const auto settingsLang = - Core::App().settings().skipTranslationForLanguage(); - const auto locale = (settingsLang == QLocale::English) - ? QLocale(Lang::LanguageIdOrDefault(Lang::Id())) - : (settingsLang == QLocale::C) - ? QLocale(QLocale::English) - : QLocale(settingsLang); - label->fire_copy(locale); - } + label->fire(Ui::Translate::LocalesFromSettings()); translateSkip->setClickedCallback([=] { Ui::BoxShow(this).showBox( Box(Ui::ChooseLanguageBox, [=](QLocale locale) { - label->fire_copy(locale); + label->fire({ locale }); const auto result = (locale.language() == QLocale::English) ? QLocale::c() : locale; - Core::App().settings().setSkipTranslationForLanguage( - result.language()); + Core::App().settings().setSkipTranslationForLanguages( + { result.language() }); Core::App().saveSettingsDelayed(); }), Ui::LayerOption::KeepOther); diff --git a/Telegram/SourceFiles/boxes/translate_box.cpp b/Telegram/SourceFiles/boxes/translate_box.cpp index 4ef60894b..125118007 100644 --- a/Telegram/SourceFiles/boxes/translate_box.cpp +++ b/Telegram/SourceFiles/boxes/translate_box.cpp @@ -129,6 +129,29 @@ rpl::producer ShowButton::clicks() const { } // namespace +namespace Translate { + +std::vector LocalesFromSettings() { + const auto langs = Core::App().settings().skipTranslationForLanguages(); + if (langs.empty()) { + return { QLocale(QLocale::English) }; + } + return ranges::views::all( + langs + ) | ranges::view::transform([](int langId) { + const auto lang = QLocale::Language(langId); + return (lang == QLocale::English) + ? QLocale(Lang::LanguageIdOrDefault(Lang::Id())) + : (lang == QLocale::C) + ? QLocale(QLocale::English) + : QLocale(lang); + }) | ranges::to_vector; +} + +} // namespace Translate + +using namespace Translate; + QString LanguageName(const QLocale &locale) { if (locale.language() == QLocale::English && (locale.country() == QLocale::UnitedStates @@ -149,13 +172,7 @@ void TranslateBox( box->setWidth(st::boxWideWidth); box->addButton(tr::lng_box_ok(), [=] { box->closeBox(); }); const auto container = box->verticalLayout(); - const auto settingsLang = - Core::App().settings().skipTranslationForLanguage(); - const auto defaultId = (settingsLang == QLocale::English) - ? Lang::LanguageIdOrDefault(Lang::Id()) - : (settingsLang == QLocale::C) - ? u"en"_q - : QLocale(settingsLang).name().mid(0, 2); + const auto defaultId = LocalesFromSettings().front().name().mid(0, 2); const auto api = box->lifetime().make_state( &peer->session().mtp()); @@ -356,14 +373,9 @@ bool SkipTranslate(TextWithEntities textWithEntities) { if (result.unknown) { return false; } - const auto settingsLang = - Core::App().settings().skipTranslationForLanguage(); - const auto skip = (settingsLang == QLocale::English) - ? QLocale(Lang::LanguageIdOrDefault(Lang::Id())).language() - : (settingsLang == QLocale::C) - ? QLocale::English - : settingsLang; - return (result.locale.language() == skip); + return ranges::any_of(LocalesFromSettings(), [&](const QLocale &l) { + return result.locale.language() == l.language(); + }); #else return false; #endif diff --git a/Telegram/SourceFiles/boxes/translate_box.h b/Telegram/SourceFiles/boxes/translate_box.h index 467fb4b85..267d6a17f 100644 --- a/Telegram/SourceFiles/boxes/translate_box.h +++ b/Telegram/SourceFiles/boxes/translate_box.h @@ -10,6 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class PeerData; namespace Ui { +namespace Translate { +[[nodiscard]] std::vector LocalesFromSettings(); +} // namespace Translate class GenericBox; diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index c36c39c62..da140dcf8 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -267,7 +267,13 @@ QByteArray Settings::serialize() const { << qint32(_hardwareAcceleratedVideo ? 1 : 0) << qint32(_suggestAnimatedEmoji ? 1 : 0) << qint32(_cornerReaction.current() ? 1 : 0) - << qint32(_skipTranslationForLanguage); + << qint32(_translateButtonEnabled ? 1 : 0); + + stream + << qint32(_skipTranslationForLanguages.size()); + for (const auto &lang : _skipTranslationForLanguages) { + stream << quint64(lang); + } } return result; } @@ -361,7 +367,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) { qint32 chatQuickAction = static_cast(_chatQuickAction); qint32 suggestAnimatedEmoji = _suggestAnimatedEmoji ? 1 : 0; qint32 cornerReaction = _cornerReaction.current() ? 1 : 0; - qint32 skipTranslationForLanguage = _skipTranslationForLanguage; + qint32 legacySkipTranslationForLanguage = _translateButtonEnabled ? 1 : 0; + qint32 skipTranslationForLanguagesCount = 0; + std::vector skipTranslationForLanguages; stream >> themesAccentColors; if (!stream.atEnd()) { @@ -560,7 +568,17 @@ void Settings::addFromSerialized(const QByteArray &serialized) { stream >> cornerReaction; } if (!stream.atEnd()) { - stream >> skipTranslationForLanguage; + stream >> legacySkipTranslationForLanguage; + } + if (!stream.atEnd()) { + stream >> skipTranslationForLanguagesCount; + if (stream.status() == QDataStream::Ok) { + for (auto i = 0; i != skipTranslationForLanguagesCount; ++i) { + quint64 language; + stream >> language; + skipTranslationForLanguages.emplace_back(language); + } + } } if (stream.status() != QDataStream::Ok) { LOG(("App Error: " @@ -731,7 +749,18 @@ void Settings::addFromSerialized(const QByteArray &serialized) { } _suggestAnimatedEmoji = (suggestAnimatedEmoji == 1); _cornerReaction = (cornerReaction == 1); - _skipTranslationForLanguage = skipTranslationForLanguage; + { // Parse the legacy translation setting. + _skipTranslationForLanguages = skipTranslationForLanguages; + if (legacySkipTranslationForLanguage == 0) { + _translateButtonEnabled = false; + } else if (legacySkipTranslationForLanguage == 1) { + _translateButtonEnabled = true; + } else { + _translateButtonEnabled = (legacySkipTranslationForLanguage > 0); + _skipTranslationForLanguages.push_back( + std::abs(legacySkipTranslationForLanguage)); + } + } } QString Settings::getSoundPath(const QString &key) const { @@ -1042,18 +1071,16 @@ float64 Settings::DefaultDialogsWidthRatio() { } void Settings::setTranslateButtonEnabled(bool value) { - _skipTranslationForLanguage = std::abs(_skipTranslationForLanguage) - * (value ? 1 : -1); + _translateButtonEnabled = value; } bool Settings::translateButtonEnabled() const { - return _skipTranslationForLanguage > 0; + return _translateButtonEnabled; } -void Settings::setSkipTranslationForLanguage(QLocale::Language language) { - const auto enabled = translateButtonEnabled(); - _skipTranslationForLanguage = language * (enabled ? 1 : -1); +void Settings::setSkipTranslationForLanguages(std::vector languages) { + _skipTranslationForLanguages = std::move(languages); } -QLocale::Language Settings::skipTranslationForLanguage() const { - return QLocale::Language(std::abs(_skipTranslationForLanguage)); +std::vector Settings::skipTranslationForLanguages() const { + return _skipTranslationForLanguages; } } // namespace Core diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index afabc40bd..c012d8f46 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -724,8 +724,8 @@ public: void setTranslateButtonEnabled(bool value); [[nodiscard]] bool translateButtonEnabled() const; - void setSkipTranslationForLanguage(QLocale::Language language); - [[nodiscard]] QLocale::Language skipTranslationForLanguage() const; + void setSkipTranslationForLanguages(std::vector languages); + [[nodiscard]] std::vector skipTranslationForLanguages() const; [[nodiscard]] static bool ThirdColumnByDefault(); [[nodiscard]] static float64 DefaultDialogsWidthRatio(); @@ -841,7 +841,8 @@ private: #endif // Q_OS_MAC HistoryView::DoubleClickQuickAction _chatQuickAction = HistoryView::DoubleClickQuickAction(); - int _skipTranslationForLanguage = -int(QLocale::English); + bool _translateButtonEnabled = false; + std::vector _skipTranslationForLanguages; bool _tabbedReplacedWithInfo = false; // per-window rpl::event_stream _tabbedReplacedWithInfoValue; // per-window