Added auto download of new dictionary when input locale is changed.

This commit is contained in:
23rd 2020-02-21 00:44:25 +03:00
parent bc6e1e7a0d
commit 8734ebe4c4
1 changed files with 95 additions and 33 deletions

View File

@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "spellcheck/spellcheck_value.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QInputMethod>
namespace Spellchecker {
@ -47,6 +48,14 @@ inline auto LWC(QLocale::Country country) {
return (l.language() * 1000) + country;
}
inline auto LanguageFromLocale(QLocale loc) {
const auto locLang = int(loc.language());
return (ranges::contains(kLangsForLWC, locLang)
&& (loc.country() != QLocale::AnyCountry))
? LWC(loc.country())
: locLang;
}
const auto kDictionaries = {
Dict{{ QLocale::English, 649, 174'516, "English" }}, // en_US
Dict{{ QLocale::Bulgarian, 594, 229'658, "\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd1\x81\xd0\xba\xd0\xb8" }}, // bg_BG
@ -92,6 +101,10 @@ const auto kDictionaries = {
// The Tajik code is 'tg_TG' in Chromium, but QT has only 'tg_TJ'.
};
inline auto IsSupportedLang(int lang) {
return ranges::contains(kDictionaries, lang, &Dict::id);
}
void EnsurePath() {
if (!QDir::current().mkpath(Spellchecker::DictionariesPath())) {
LOG(("App Error: Could not create dictionaries path."));
@ -322,17 +335,20 @@ rpl::producer<QString> ButtonManageDictsState(
std::vector<int> DefaultLanguages() {
std::vector<int> langs;
const auto append = [&](const auto loc) {
const auto l = LanguageFromLocale(loc);
if (!ranges::contains(langs, l) && IsSupportedLang(l)) {
langs.push_back(l);
}
};
const auto method = QGuiApplication::inputMethod();
langs.reserve(method ? 3 : 2);
if (method) {
const auto loc = method->locale();
const auto locLang = int(loc.language());
langs.push_back(ranges::contains(kLangsForLWC, locLang)
? LWC(loc.country())
: locLang);
append(method->locale());
}
langs.push_back(QLocale(Platform::SystemLanguage()).language());
langs.push_back(QLocale(Lang::Current().id()).language());
append(QLocale(Platform::SystemLanguage()));
append(QLocale(Lang::LanguageIdOrDefault(Lang::Current().id())));
return langs;
}
@ -345,7 +361,17 @@ void Start(not_null<Main::Session*> session) {
} });
const auto settings = &session->settings();
if (!Platform::Spellchecker::IsSystemSpellchecker()) {
const auto guard = gsl::finally([=]{
if (settings->spellcheckerEnabled()) {
Platform::Spellchecker::UpdateLanguages(
settings->dictionariesEnabled());
}
});
if (Platform::Spellchecker::IsSystemSpellchecker()) {
return;
}
Spellchecker::SetWorkingDirPath(DictionariesPath());
settings->dictionariesEnabledChanges(
@ -361,6 +387,30 @@ void Start(not_null<Main::Session*> session) {
: std::vector<int>());
}, session->lifetime());
const auto method = QGuiApplication::inputMethod();
const auto connectInput = [=] {
if (!method || !settings->spellcheckerEnabled()) {
return;
}
auto callback = [=] {
if (BackgroundLoader) {
return;
}
const auto l = LanguageFromLocale(method->locale());
if (!IsSupportedLang(l) || DictionaryExists(l)) {
return;
}
crl::on_main(session, [=] {
DownloadDictionaryInBackground(session, 0, { l });
});
};
QObject::connect(
method,
&QInputMethod::localeChanged,
std::move(callback));
};
if (settings->autoDownloadDictionaries()) {
session->data().contactsLoaded().changes(
) | rpl::start_with_next([=](bool loaded) {
@ -370,13 +420,25 @@ void Start(not_null<Main::Session*> session) {
DownloadDictionaryInBackground(session, 0, DefaultLanguages());
}, session->lifetime());
connectInput();
}
rpl::combine(
settings->spellcheckerEnabledValue(),
settings->autoDownloadDictionariesValue()
) | rpl::start_with_next([=](bool spell, bool download) {
if (spell && download) {
connectInput();
return;
}
if (settings->spellcheckerEnabled()) {
Platform::Spellchecker::UpdateLanguages(
settings->dictionariesEnabled());
}
QObject::disconnect(
method,
&QInputMethod::localeChanged,
nullptr,
nullptr);
}, session->lifetime());
}
} // namespace Spellchecker