Move lang keys to td_lang library.

This commit is contained in:
John Preston 2020-09-30 12:11:44 +03:00
parent def1266216
commit 8634c1f7f3
41 changed files with 271 additions and 164 deletions

View file

@ -23,7 +23,6 @@ add_subdirectory(codegen)
include(CheckCXXSourceCompiles) include(CheckCXXSourceCompiles)
include(lib_ui/cmake/generate_styles.cmake) include(lib_ui/cmake/generate_styles.cmake)
include(cmake/generate_lang.cmake)
include(cmake/generate_numbers.cmake) include(cmake/generate_numbers.cmake)
get_filename_component(src_loc SourceFiles REALPATH) get_filename_component(src_loc SourceFiles REALPATH)
@ -35,6 +34,7 @@ include(cmake/lib_tgvoip.cmake)
include(cmake/lib_tgcalls.cmake) include(cmake/lib_tgcalls.cmake)
include(cmake/td_export.cmake) include(cmake/td_export.cmake)
include(cmake/td_mtproto.cmake) include(cmake/td_mtproto.cmake)
include(cmake/td_lang.cmake)
include(cmake/td_scheme.cmake) include(cmake/td_scheme.cmake)
include(cmake/td_ui.cmake) include(cmake/td_ui.cmake)
@ -66,7 +66,6 @@ set(dependent_style_files
) )
generate_styles(Telegram ${src_loc} "${style_files}" "${dependent_style_files}") generate_styles(Telegram ${src_loc} "${style_files}" "${dependent_style_files}")
generate_lang(Telegram ${res_loc}/langs/lang.strings)
generate_numbers(Telegram ${res_loc}/numbers.txt) generate_numbers(Telegram ${res_loc}/numbers.txt)
set_target_properties(Telegram PROPERTIES AUTOMOC ON AUTORCC ON) set_target_properties(Telegram PROPERTIES AUTOMOC ON AUTORCC ON)
@ -78,6 +77,7 @@ PRIVATE
tdesktop::lib_tgvoip tdesktop::lib_tgvoip
tdesktop::td_export tdesktop::td_export
tdesktop::td_mtproto tdesktop::td_mtproto
tdesktop::td_lang
tdesktop::td_scheme tdesktop::td_scheme
tdesktop::td_ui tdesktop::td_ui
desktop-app::lib_webrtc desktop-app::lib_webrtc
@ -720,23 +720,12 @@ PRIVATE
intro/intro_widget.h intro/intro_widget.h
lang/lang_cloud_manager.cpp lang/lang_cloud_manager.cpp
lang/lang_cloud_manager.h lang/lang_cloud_manager.h
lang/lang_file_parser.cpp
lang/lang_file_parser.h
lang/lang_hardcoded.h
lang/lang_instance.cpp lang/lang_instance.cpp
lang/lang_instance.h lang/lang_instance.h
lang/lang_keys.cpp
lang/lang_keys.h
lang/lang_numbers_animation.cpp lang/lang_numbers_animation.cpp
lang/lang_numbers_animation.h lang/lang_numbers_animation.h
lang/lang_tag.cpp
lang/lang_tag.h
lang/lang_text_entity.cpp
lang/lang_text_entity.h
lang/lang_translator.cpp lang/lang_translator.cpp
lang/lang_translator.h lang/lang_translator.h
lang/lang_values.cpp
lang/lang_values.h
main/main_account.cpp main/main_account.cpp
main/main_account.h main/main_account.h
main/main_app_config.cpp main/main_app_config.cpp

View file

@ -125,7 +125,7 @@ QString telegramFaqLink() {
const auto langpacked = [&](const char *language) { const auto langpacked = [&](const char *language) {
return result + '/' + language; return result + '/' + language;
}; };
const auto current = Lang::Current().id(); const auto current = Lang::Id();
for (const auto language : { "de", "es", "it", "ko" }) { for (const auto language : { "de", "es", "it", "ko" }) {
if (current.startsWith(QLatin1String(language))) { if (current.startsWith(QLatin1String(language))) {
return langpacked(language); return langpacked(language);

View file

@ -196,7 +196,7 @@ std::pair<Languages, Languages> PrepareLists() {
const auto projId = [](const Language &language) { const auto projId = [](const Language &language) {
return language.id; return language.id;
}; };
const auto current = Lang::LanguageIdOrDefault(Lang::Current().id()); const auto current = Lang::LanguageIdOrDefault(Lang::Id());
auto official = Lang::CurrentCloudManager().languageList(); auto official = Lang::CurrentCloudManager().languageList();
auto recent = Local::readRecentLanguages(); auto recent = Local::readRecentLanguages();
ranges::stable_partition(recent, [&](const Language &language) { ranges::stable_partition(recent, [&](const Language &language) {
@ -207,13 +207,13 @@ std::pair<Languages, Languages> PrepareLists() {
const auto generate = [&] { const auto generate = [&] {
const auto name = (current == "#custom") const auto name = (current == "#custom")
? "Custom lang pack" ? "Custom lang pack"
: Lang::Current().name(); : Lang::GetInstance().name();
return Language{ return Language{
current, current,
QString(), QString(),
QString(), QString(),
name, name,
Lang::Current().nativeName() Lang::GetInstance().nativeName()
}; };
}; };
const auto i = ranges::find(official, current, projId); const auto i = ranges::find(official, current, projId);
@ -867,7 +867,7 @@ void Content::setupContent(
const Languages &official) { const Languages &official) {
using namespace rpl::mappers; using namespace rpl::mappers;
const auto current = Lang::LanguageIdOrDefault(Lang::Current().id()); const auto current = Lang::LanguageIdOrDefault(Lang::Id());
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this); const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
const auto add = [&](const Languages &list, bool areOfficial) { const auto add = [&](const Languages &list, bool areOfficial) {
if (list.empty()) { if (list.empty()) {
@ -1101,7 +1101,7 @@ void LanguageBox::prepare() {
// "#custom" is applied each time it's passed to switchToLanguage(). // "#custom" is applied each time it's passed to switchToLanguage().
// So we check that the language really has changed. // So we check that the language really has changed.
const auto currentId = [] { const auto currentId = [] {
return Lang::LanguageIdOrDefault(Lang::Current().id()); return Lang::LanguageIdOrDefault(Lang::Id());
}; };
if (language.id != currentId()) { if (language.id != currentId()) {
Lang::CurrentCloudManager().switchToLanguage(language); Lang::CurrentCloudManager().switchToLanguage(language);

View file

@ -569,7 +569,7 @@ std::vector<QString> EmojiKeywords::languages() {
const auto yieldList = [&](const QStringList &list) { const auto yieldList = [&](const QStringList &list) {
result.insert(end(result), list.begin(), list.end()); result.insert(end(result), list.begin(), list.end());
}; };
yield(Lang::Current().id()); yield(Lang::Id());
yield(Lang::DefaultLanguageId()); yield(Lang::DefaultLanguageId());
yield(Lang::CurrentCloudManager().suggestedLanguage()); yield(Lang::CurrentCloudManager().suggestedLanguage());
yield(Platform::SystemLanguage()); yield(Platform::SystemLanguage());

View file

@ -366,7 +366,7 @@ std::vector<int> DefaultLanguages() {
append(method->locale()); append(method->locale());
} }
append(QLocale(Platform::SystemLanguage())); append(QLocale(Platform::SystemLanguage()));
append(QLocale(Lang::LanguageIdOrDefault(Lang::Current().id()))); append(QLocale(Lang::LanguageIdOrDefault(Lang::Id())));
return langs; return langs;
} }

View file

@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_translator.h" #include "lang/lang_translator.h"
#include "lang/lang_cloud_manager.h" #include "lang/lang_cloud_manager.h"
#include "lang/lang_hardcoded.h" #include "lang/lang_hardcoded.h"
#include "lang/lang_instance.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "core/file_utilities.h" #include "core/file_utilities.h"
#include "main/main_account.h" #include "main/main_account.h"

View file

@ -58,6 +58,10 @@ void UiIntegration::startFontsBegin() {
void UiIntegration::startFontsEnd() { void UiIntegration::startFontsEnd() {
} }
QString UiIntegration::timeFormat() {
return cTimeFormat();
}
std::shared_ptr<ClickHandler> UiIntegration::createLinkHandler( std::shared_ptr<ClickHandler> UiIntegration::createLinkHandler(
const EntityLinkData &data, const EntityLinkData &data,
const std::any &context) { const std::any &context) {

View file

@ -39,6 +39,7 @@ public:
void startFontsBegin() override; void startFontsBegin() override;
void startFontsEnd() override; void startFontsEnd() override;
QString timeFormat() override;
std::shared_ptr<ClickHandler> createLinkHandler( std::shared_ptr<ClickHandler> createLinkHandler(
const EntityLinkData &data, const EntityLinkData &data,

View file

@ -314,8 +314,7 @@ void paintRow(
const auto type = history->topPromotionType(); const auto type = history->topPromotionType();
const auto custom = type.isEmpty() const auto custom = type.isEmpty()
? QString() ? QString()
: Lang::Current().getNonDefaultValue( : Lang::GetNonDefaultValue(kPsaBadgePrefix + type.toUtf8());
kPsaBadgePrefix + type.toUtf8());
const auto text = type.isEmpty() const auto text = type.isEmpty()
? tr::lng_proxy_sponsor(tr::now) ? tr::lng_proxy_sponsor(tr::now)
: custom.isEmpty() : custom.isEmpty()

View file

@ -155,7 +155,7 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
if (fromChannel || !psaType.isEmpty()) { if (fromChannel || !psaType.isEmpty()) {
auto custom = psaType.isEmpty() auto custom = psaType.isEmpty()
? QString() ? QString()
: Lang::Current().getNonDefaultValue( : Lang::GetNonDefaultValue(
kPsaForwardedPrefix + psaType.toUtf8()); kPsaForwardedPrefix + psaType.toUtf8());
phrase = !custom.isEmpty() phrase = !custom.isEmpty()
? custom.replace("{channel}", textcmdLink(1, phrase)) ? custom.replace("{channel}", textcmdLink(1, phrase))

View file

@ -2233,8 +2233,7 @@ void HistoryWidget::showAboutTopPromotion() {
const auto type = _history->topPromotionType(); const auto type = _history->topPromotionType();
const auto custom = type.isEmpty() const auto custom = type.isEmpty()
? QString() ? QString()
: Lang::Current().getNonDefaultValue( : Lang::GetNonDefaultValue(kPsaAboutPrefix + type.toUtf8());
kPsaAboutPrefix + type.toUtf8());
const auto text = type.isEmpty() const auto text = type.isEmpty()
? tr::lng_proxy_sponsor_about(tr::now, Ui::Text::RichLangValue) ? tr::lng_proxy_sponsor_about(tr::now, Ui::Text::RichLangValue)
: custom.isEmpty() : custom.isEmpty()

View file

@ -1438,8 +1438,7 @@ ClickHandlerPtr Message::psaTooltipLink() const {
const auto handler = [=] { const auto handler = [=] {
const auto custom = type.isEmpty() const auto custom = type.isEmpty()
? QString() ? QString()
: Lang::Current().getNonDefaultValue( : Lang::GetNonDefaultValue(kPsaTooltipPrefix + type.toUtf8());
kPsaTooltipPrefix + type.toUtf8());
auto text = Ui::Text::RichLangValue( auto text = Ui::Text::RichLangValue(
(custom.isEmpty() (custom.isEmpty()
? tr::lng_tooltip_psa_default(tr::now) ? tr::lng_tooltip_psa_default(tr::now)

View file

@ -67,9 +67,13 @@ TopBarWidget::TopBarWidget(
, _menuToggle(this, st::topBarMenuToggle) , _menuToggle(this, st::topBarMenuToggle)
, _titlePeerText(st::windowMinWidth / 3) , _titlePeerText(st::windowMinWidth / 3)
, _onlineUpdater([=] { updateOnlineDisplay(); }) { , _onlineUpdater([=] { updateOnlineDisplay(); }) {
subscribe(Lang::Current().updated(), [=] { refreshLang(); });
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
_forward->setClickedCallback([=] { _forwardSelection.fire({}); }); _forward->setClickedCallback([=] { _forwardSelection.fire({}); });
_forward->setWidthChangedCallback([=] { updateControlsGeometry(); }); _forward->setWidthChangedCallback([=] { updateControlsGeometry(); });
_sendNow->setClickedCallback([=] { _sendNowSelection.fire({}); }); _sendNow->setClickedCallback([=] { _sendNowSelection.fire({}); });

View file

@ -89,7 +89,10 @@ CodeWidget::CodeWidget(
, _callTimeout(getData()->callTimeout) , _callTimeout(getData()->callTimeout)
, _callLabel(this, st::introDescription) , _callLabel(this, st::introDescription)
, _checkRequestTimer([=] { checkRequest(); }) { , _checkRequestTimer([=] { checkRequest(); }) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); }); Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
connect(_code, &CodeInput::changed, [=] { codeChanged(); }); connect(_code, &CodeInput::changed, [=] { codeChanged(); });
_noTelegramCode->addClickHandler([=] { noTelegramCode(); }); _noTelegramCode->addClickHandler([=] { noTelegramCode(); });

View file

@ -40,7 +40,10 @@ PasswordCheckWidget::PasswordCheckWidget(
, _toPassword(this, tr::lng_signin_try_password(tr::now)) { , _toPassword(this, tr::lng_signin_try_password(tr::now)) {
Expects(!!_request); Expects(!!_request);
subscribe(Lang::Current().updated(), [=] { refreshLang(); }); Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
_toRecover->addClickHandler([=] { toRecover(); }); _toRecover->addClickHandler([=] { toRecover(); });
_toPassword->addClickHandler([=] { toPassword(); }); _toPassword->addClickHandler([=] { toPassword(); });

View file

@ -35,7 +35,11 @@ SignupWidget::SignupWidget(
, _first(this, st::introName, tr::lng_signup_firstname()) , _first(this, st::introName, tr::lng_signup_firstname())
, _last(this, st::introName, tr::lng_signup_lastname()) , _last(this, st::introName, tr::lng_signup_lastname())
, _invertOrder(langFirstNameGoesSecond()) { , _invertOrder(langFirstNameGoesSecond()) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); }); Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
if (_invertOrder) { if (_invertOrder) {
setTabOrder(_last, _first); setTabOrder(_last, _first);
} else { } else {

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "storage/storage_account.h" #include "storage/storage_account.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "lang/lang_instance.h"
#include "lang/lang_cloud_manager.h" #include "lang/lang_cloud_manager.h"
#include "main/main_account.h" #include "main/main_account.h"
#include "main/main_domain.h" #include "main/main_domain.h"
@ -175,11 +176,11 @@ void Step::createSession(
QImage photo, QImage photo,
const QVector<MTPDialogFilter> &filters) { const QVector<MTPDialogFilter> &filters) {
// Save the default language if we've suggested some other and user ignored it. // Save the default language if we've suggested some other and user ignored it.
const auto currentId = Lang::Current().id(); const auto currentId = Lang::Id();
const auto defaultId = Lang::DefaultLanguageId(); const auto defaultId = Lang::DefaultLanguageId();
const auto suggested = Lang::CurrentCloudManager().suggestedLanguage(); const auto suggested = Lang::CurrentCloudManager().suggestedLanguage();
if (currentId.isEmpty() && !suggested.isEmpty() && suggested != defaultId) { if (currentId.isEmpty() && !suggested.isEmpty() && suggested != defaultId) {
Lang::Current().switchToId(Lang::DefaultLanguage()); Lang::GetInstance().switchToId(Lang::DefaultLanguage());
Local::writeLangPack(); Local::writeLangPack();
} }

View file

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "intro/intro_signup.h" #include "intro/intro_signup.h"
#include "intro/intro_password_check.h" #include "intro/intro_password_check.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "lang/lang_instance.h"
#include "lang/lang_cloud_manager.h" #include "lang/lang_cloud_manager.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "main/main_account.h" #include "main/main_account.h"
@ -126,7 +127,10 @@ Widget::Widget(
_changeLanguage->finishAnimating(); _changeLanguage->finishAnimating();
} }
subscribe(Lang::Current().updated(), [this] { refreshLang(); }); Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
show(); show();
showControls(); showControls();
@ -241,7 +245,7 @@ void Widget::createLanguageLink() {
updateControlsGeometry(); updateControlsGeometry();
}; };
const auto currentId = Lang::LanguageIdOrDefault(Lang::Current().id()); const auto currentId = Lang::LanguageIdOrDefault(Lang::Id());
const auto defaultId = Lang::DefaultLanguageId(); const auto defaultId = Lang::DefaultLanguageId();
const auto suggested = Lang::CurrentCloudManager().suggestedLanguage(); const auto suggested = Lang::CurrentCloudManager().suggestedLanguage();
if (currentId != defaultId) { if (currentId != defaultId) {

View file

@ -8,6 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_file_parser.h" #include "lang/lang_file_parser.h"
#include "base/parse_helper.h" #include "base/parse_helper.h"
#include "ui/integration.h"
#include <QtCore/QTextStream>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
namespace Lang { namespace Lang {
namespace { namespace {
@ -30,7 +35,7 @@ FileParser::FileParser(const QByteArray &content, Fn<void(QLatin1String key, con
void FileParser::parse() { void FileParser::parse() {
if (_content.isEmpty()) { if (_content.isEmpty()) {
error(qsl("Got empty lang file content")); error(u"Got empty lang file content"_q);
return; return;
} }
@ -72,21 +77,21 @@ bool FileParser::readKeyValue(const char *&from, const char *end) {
auto key = QLatin1String(nameStart, from - nameStart); auto key = QLatin1String(nameStart, from - nameStart);
if (from == end || *from != '"') { if (from == end || *from != '"') {
return error(qsl("Expected quote after key name '%1'!").arg(key)); return error(u"Expected quote after key name '%1'!"_q.arg(key));
} }
++from; ++from;
if (!skipWhitespaces(from, end)) { if (!skipWhitespaces(from, end)) {
return error(qsl("Unexpected end of file in key '%1'!").arg(key)); return error(u"Unexpected end of file in key '%1'!"_q.arg(key));
} }
if (*from != '=') { if (*from != '=') {
return error(qsl("'=' expected in key '%1'!").arg(key)); return error(u"'=' expected in key '%1'!"_q.arg(key));
} }
if (!skipWhitespaces(++from, end)) { if (!skipWhitespaces(++from, end)) {
return error(qsl("Unexpected end of file in key '%1'!").arg(key)); return error(u"Unexpected end of file in key '%1'!"_q.arg(key));
} }
if (*from != '"') { if (*from != '"') {
return error(qsl("Expected string after '=' in key '%1'!").arg(key)); return error(u"Expected string after '=' in key '%1'!"_q.arg(key));
} }
auto skipping = false; auto skipping = false;
@ -105,11 +110,11 @@ bool FileParser::readKeyValue(const char *&from, const char *end) {
const char *start = ++from; const char *start = ++from;
while (from < end && *from != '"') { while (from < end && *from != '"') {
if (*from == '\n') { if (*from == '\n') {
return error(qsl("Unexpected end of string in key '%1'!").arg(key)); return error(u"Unexpected end of string in key '%1'!"_q.arg(key));
} }
if (*from == '\\') { if (*from == '\\') {
if (from + 1 >= end) { if (from + 1 >= end) {
return error(qsl("Unexpected end of file in key '%1'!").arg(key)); return error(u"Unexpected end of file in key '%1'!"_q.arg(key));
} }
if (*(from + 1) == '"' || *(from + 1) == '\\') { if (*(from + 1) == '"' || *(from + 1) == '\\') {
if (from > start) appendValue(start, from - start); if (from > start) appendValue(start, from - start);
@ -123,17 +128,17 @@ bool FileParser::readKeyValue(const char *&from, const char *end) {
++from; ++from;
} }
if (from >= end) { if (from >= end) {
return error(qsl("Unexpected end of file in key '%1'!").arg(key)); return error(u"Unexpected end of file in key '%1'!"_q.arg(key));
} }
if (from > start) { if (from > start) {
appendValue(start, from - start); appendValue(start, from - start);
} }
if (!skipWhitespaces(++from, end)) { if (!skipWhitespaces(++from, end)) {
return error(qsl("Unexpected end of file in key '%1'!").arg(key)); return error(u"Unexpected end of file in key '%1'!"_q.arg(key));
} }
if (*from != ';') { if (*from != ';') {
return error(qsl("';' expected after \"value\" in key '%1'!").arg(key)); return error(u"';' expected after \"value\" in key '%1'!"_q.arg(key));
} }
skipWhitespaces(++from, end); skipWhitespaces(++from, end);
@ -150,18 +155,18 @@ bool FileParser::readKeyValue(const char *&from, const char *end) {
QByteArray FileParser::ReadFile(const QString &absolutePath, const QString &relativePath) { QByteArray FileParser::ReadFile(const QString &absolutePath, const QString &relativePath) {
QFile file(QFileInfo(relativePath).exists() ? relativePath : absolutePath); QFile file(QFileInfo(relativePath).exists() ? relativePath : absolutePath);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
LOG(("Lang Error: Could not open file at '%1' ('%2')").arg(relativePath).arg(absolutePath)); Ui::Integration::Instance().writeLogEntry(u"Lang Error: Could not open file at '%1' ('%2')"_q.arg(relativePath).arg(absolutePath));
return QByteArray(); return QByteArray();
} }
if (file.size() > kLangFileLimit) { if (file.size() > kLangFileLimit) {
LOG(("Lang Error: File is too big: %1").arg(file.size())); Ui::Integration::Instance().writeLogEntry(u"Lang Error: File is too big: %1"_q.arg(file.size()));
return QByteArray(); return QByteArray();
} }
constexpr auto kCodecMagicSize = 3; constexpr auto kCodecMagicSize = 3;
auto codecMagic = file.read(kCodecMagicSize); auto codecMagic = file.read(kCodecMagicSize);
if (codecMagic.size() < kCodecMagicSize) { if (codecMagic.size() < kCodecMagicSize) {
LOG(("Lang Error: Found bad file at '%1' ('%2')").arg(relativePath).arg(absolutePath)); Ui::Integration::Instance().writeLogEntry(u"Lang Error: Found bad file at '%1' ('%2')"_q.arg(relativePath).arg(absolutePath));
return QByteArray(); return QByteArray();
} }
file.seek(0); file.seek(0);
@ -172,11 +177,11 @@ QByteArray FileParser::ReadFile(const QString &absolutePath, const QString &rela
stream.setCodec("UTF-16"); stream.setCodec("UTF-16");
auto string = stream.readAll(); auto string = stream.readAll();
if (stream.status() != QTextStream::Ok) { if (stream.status() != QTextStream::Ok) {
LOG(("Lang Error: Could not read UTF-16 data from '%1' ('%2')").arg(relativePath).arg(absolutePath)); Ui::Integration::Instance().writeLogEntry(u"Lang Error: Could not read UTF-16 data from '%1' ('%2')"_q.arg(relativePath).arg(absolutePath));
return QByteArray(); return QByteArray();
} }
if (string.isEmpty()) { if (string.isEmpty()) {
LOG(("Lang Error: Empty UTF-16 content in '%1' ('%2')").arg(relativePath).arg(absolutePath)); Ui::Integration::Instance().writeLogEntry(u"Lang Error: Empty UTF-16 content in '%1' ('%2')"_q.arg(relativePath).arg(absolutePath));
return QByteArray(); return QByteArray();
} }
return string.toUtf8(); return string.toUtf8();
@ -192,7 +197,7 @@ QByteArray FileParser::ReadFile(const QString &absolutePath, const QString &rela
data = data.mid(3); // skip UTF-8 BOM data = data.mid(3); // skip UTF-8 BOM
} }
if (data.isEmpty()) { if (data.isEmpty()) {
LOG(("Lang Error: Empty UTF-8 content in '%1' ('%2')").arg(relativePath).arg(absolutePath)); Ui::Integration::Instance().writeLogEntry(u"Lang Error: Empty UTF-8 content in '%1' ('%2')"_q.arg(relativePath).arg(absolutePath));
return QByteArray(); return QByteArray();
} }
return data; return data;

View file

@ -9,6 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include <set>
#include <QtCore/QMap>
namespace Lang { namespace Lang {
class FileParser { class FileParser {

View file

@ -11,59 +11,59 @@ namespace Lang {
namespace Hard { namespace Hard {
inline QString FavedSetTitle() { inline QString FavedSetTitle() {
return qsl("Favorite stickers"); return u"Favorite stickers"_q;
} }
inline QString CallErrorIncompatible() { inline QString CallErrorIncompatible() {
return qsl("{user}'s app is using an incompatible protocol. They need to update their app before you can call them."); return u"{user}'s app is using an incompatible protocol. They need to update their app before you can call them."_q;
} }
inline QString ServerError() { inline QString ServerError() {
return qsl("Internal server error."); return u"Internal server error."_q;
} }
inline QString ClearPathFailed() { inline QString ClearPathFailed() {
return qsl("Clear failed :("); return u"Clear failed :("_q;
} }
inline QString ProxyConfigError() { inline QString ProxyConfigError() {
return qsl("The proxy you are using is not configured correctly and will be disabled. Please find another one."); return u"The proxy you are using is not configured correctly and will be disabled. Please find another one."_q;
} }
inline QString NoAuthorizationBot() { inline QString NoAuthorizationBot() {
return qsl("Could not get authorization bot."); return u"Could not get authorization bot."_q;
} }
inline QString SecureSaveError() { inline QString SecureSaveError() {
return qsl("Error saving value."); return u"Error saving value."_q;
} }
inline QString SecureAcceptError() { inline QString SecureAcceptError() {
return qsl("Error acception form."); return u"Error accepting form."_q;
} }
inline QString PassportCorrupted() { inline QString PassportCorrupted() {
return qsl("It seems your Telegram Passport data was corrupted.\n\nYou can reset your Telegram Passport and restart this authorization."); return u"It seems your Telegram Passport data was corrupted.\n\nYou can reset your Telegram Passport and restart this authorization."_q;
} }
inline QString PassportCorruptedChange() { inline QString PassportCorruptedChange() {
return qsl("It seems your Telegram Passport data was corrupted.\n\nYou can reset your Telegram Passport and change your cloud password."); return u"It seems your Telegram Passport data was corrupted.\n\nYou can reset your Telegram Passport and change your cloud password."_q;
} }
inline QString PassportCorruptedReset() { inline QString PassportCorruptedReset() {
return qsl("Reset"); return u"Reset"_q;
} }
inline QString PassportCorruptedResetSure() { inline QString PassportCorruptedResetSure() {
return qsl("Are you sure you want to reset your Telegram Passport data?"); return u"Are you sure you want to reset your Telegram Passport data?"_q;
} }
inline QString UnknownSecureScanError() { inline QString UnknownSecureScanError() {
return qsl("Unknown scan read error."); return u"Unknown scan read error."_q;
} }
inline QString EmailConfirmationExpired() { inline QString EmailConfirmationExpired() {
return qsl("This email confirmation has expired. Please setup two-step verification once again."); return u"This email confirmation has expired. Please setup two-step verification once again."_q;
} }
} // namespace Hard } // namespace Hard

View file

@ -258,7 +258,7 @@ void Instance::switchToId(const Language &data) {
value = PrepareTestValue(value, _id[5]); value = PrepareTestValue(value, _id[5]);
} }
if (!_derived) { if (!_derived) {
_updated.notify(); _updated.fire({});
} }
} }
updatePluralRules(); updatePluralRules();
@ -278,7 +278,7 @@ void Instance::setBaseId(const QString &baseId, const QString &pluralId) {
void Instance::switchToCustomFile(const QString &filePath) { void Instance::switchToCustomFile(const QString &filePath) {
if (loadFromCustomFile(filePath)) { if (loadFromCustomFile(filePath)) {
Local::writeLangPack(); Local::writeLangPack();
_updated.notify(); _updated.fire({});
} }
} }
@ -667,9 +667,9 @@ void Instance::applyDifferenceToMe(
}); });
} }
if (!_derived) { if (!_derived) {
_updated.notify(); _updated.fire({});
} else { } else {
_derived->_updated.notify(); _derived->_updated.fire({});
} }
} }
@ -742,24 +742,38 @@ void Instance::resetValue(const QByteArray &key) {
} }
} }
Instance &Current() { Instance &GetInstance() {
return Core::App().langpack(); return Core::App().langpack();
} }
QString Id() {
return GetInstance().id();
}
rpl::producer<> Updated() {
return GetInstance().updated();
}
QString GetNonDefaultValue(const QByteArray &key) {
return GetInstance().getNonDefaultValue(key);
}
namespace details { namespace details {
QString Current(ushort key) { QString Current(ushort key) {
return Lang::Current().getValue(key); return GetInstance().getValue(key);
} }
rpl::producer<QString> Viewer(ushort key) { rpl::producer<QString> Value(ushort key) {
return rpl::single( return rpl::single(
Lang::Current().getValue(key) Current(key)
) | then(base::ObservableViewer( ) | then(
Lang::Current().updated() Updated() | rpl::map([=] { return Current(key); })
) | rpl::map([=] { );
return Lang::Current().getValue(key); }
}));
bool IsNonDefaultPlural(ushort keyBase) {
return GetInstance().isNonDefaultPlural(keyBase);
} }
} // namespace details } // namespace details

View file

@ -36,7 +36,7 @@ QString CustomLanguageId();
Language DefaultLanguage(); Language DefaultLanguage();
class Instance; class Instance;
Instance &Current(); Instance &GetInstance();
enum class Pack { enum class Pack {
None, None,
@ -79,8 +79,9 @@ public:
const MTPDlangPackDifference &difference); const MTPDlangPackDifference &difference);
static std::map<ushort, QString> ParseStrings( static std::map<ushort, QString> ParseStrings(
const MTPVector<MTPLangPackString> &strings); const MTPVector<MTPLangPackString> &strings);
base::Observable<void> &updated() {
return _updated; [[nodiscard]] rpl::producer<> updated() const {
return _updated.events();
} }
QString getValue(ushort key) const { QString getValue(ushort key) const {
@ -129,7 +130,7 @@ private:
QString _customFilePathRelative; QString _customFilePathRelative;
QByteArray _customFileContent; QByteArray _customFileContent;
int _version = 0; int _version = 0;
base::Observable<void> _updated; rpl::event_stream<> _updated;
mutable QString _systemLanguage; mutable QString _systemLanguage;
@ -144,7 +145,7 @@ private:
namespace details { namespace details {
QString Current(ushort key); QString Current(ushort key);
rpl::producer<QString> Viewer(ushort key); rpl::producer<QString> Value(ushort key);
} // namespace details } // namespace details
} // namespace Lang } // namespace Lang

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "lang/lang_file_parser.h" #include "lang/lang_file_parser.h"
#include "ui/integration.h"
namespace { namespace {
@ -18,7 +19,7 @@ inline QString langDateMaybeWithYear(
WithoutYear withoutYear) { WithoutYear withoutYear) {
const auto month = date.month(); const auto month = date.month();
if (month <= 0 || month > 12) { if (month <= 0 || month > 12) {
return qsl("MONTH_ERR"); return u"MONTH_ERR"_q;
}; };
const auto year = date.year(); const auto year = date.year();
const auto current = QDate::currentDate(); const auto current = QDate::currentDate();
@ -177,7 +178,7 @@ QString langMonthOfYear(int month, int year) {
MonthSmall(month)(tr::now), MonthSmall(month)(tr::now),
lt_year, lt_year,
QString::number(year)) QString::number(year))
: qsl("MONTH_ERR"); : u"MONTH_ERR"_q;
} }
QString langMonth(const QDate &date) { QString langMonth(const QDate &date) {
@ -196,7 +197,7 @@ QString langMonthOfYearFull(int month, int year) {
Month(month)(tr::now), Month(month)(tr::now),
lt_year, lt_year,
QString::number(year)) QString::number(year))
: qsl("MONTH_ERR"); : u"MONTH_ERR"_q;
} }
QString langMonthFull(const QDate &date) { QString langMonthFull(const QDate &date) {
@ -208,5 +209,23 @@ QString langMonthFull(const QDate &date) {
} }
QString langDayOfWeek(int index) { QString langDayOfWeek(int index) {
return (index > 0 && index <= 7) ? Weekday(index)(tr::now) : qsl("DAY_ERR"); return (index > 0 && index <= 7) ? Weekday(index)(tr::now) : u"DAY_ERR"_q;
}
QString langDateTime(const QDateTime &date) {
return tr::lng_mediaview_date_time(
tr::now,
lt_date,
langDayOfMonth(date.date()),
lt_time,
date.time().toString(Ui::Integration::Instance().timeFormat()));
}
QString langDateTimeFull(const QDateTime &date) {
return tr::lng_mediaview_date_time(
tr::now,
lt_date,
langDayOfMonthFull(date.date()),
lt_time,
date.time().toString(Ui::Integration::Instance().timeFormat()));
} }

View file

@ -7,38 +7,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "lang/lang_instance.h" #include "lang_auto.h"
#include "lang/lang_hardcoded.h" #include "lang/lang_hardcoded.h"
#include "lang/lang_text_entity.h" #include "lang/lang_text_entity.h"
QString langDayOfMonth(const QDate &date); [[nodiscard]] QString langDayOfMonth(const QDate &date);
QString langDayOfMonthFull(const QDate &date); [[nodiscard]] QString langDayOfMonthFull(const QDate &date);
QString langMonthOfYear(int month, int year); [[nodiscard]] QString langMonthOfYear(int month, int year);
QString langMonth(const QDate &date); [[nodiscard]] QString langMonth(const QDate &date);
QString langMonthOfYearFull(int month, int year); [[nodiscard]] QString langMonthOfYearFull(int month, int year);
QString langMonthFull(const QDate &date); [[nodiscard]] QString langMonthFull(const QDate &date);
QString langDayOfWeek(int index); [[nodiscard]] QString langDayOfWeek(int index);
inline QString langDayOfWeek(const QDate &date) { [[nodiscard]] inline QString langDayOfWeek(const QDate &date) {
return langDayOfWeek(date.dayOfWeek()); return langDayOfWeek(date.dayOfWeek());
} }
inline QString langDateTime(const QDateTime &date) { [[nodiscard]] QString langDateTime(const QDateTime &date);
return tr::lng_mediaview_date_time( [[nodiscard]] QString langDateTimeFull(const QDateTime &date);
tr::now, [[nodiscard]] bool langFirstNameGoesSecond();
lt_date,
langDayOfMonth(date.date()),
lt_time,
date.time().toString(cTimeFormat()));
}
inline QString langDateTimeFull(const QDateTime &date) { namespace Lang {
return tr::lng_mediaview_date_time(
tr::now,
lt_date,
langDayOfMonthFull(date.date()),
lt_time,
date.time().toString(cTimeFormat()));
}
bool langFirstNameGoesSecond(); [[nodiscard]] QString Id();
[[nodiscard]] rpl::producer<> Updated();
[[nodiscard]] QString GetNonDefaultValue(const QByteArray &key);
} // namespace Lang

View file

@ -0,0 +1,13 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#include <QtCore/QString>
#include <QtCore/QDateTime>
#include <rpl/rpl.h>
#include "base/basic_types.h"

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_tag.h" #include "lang/lang_tag.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/text/text.h"
namespace Lang { namespace Lang {
namespace { namespace {
@ -952,8 +953,8 @@ PluralResult Plural(
// Simplified. // Simplified.
const auto n = std::abs(shortened.number ? float64(shortened.number) : value); const auto n = std::abs(shortened.number ? float64(shortened.number) : value);
const auto i = qFloor(n); const auto i = int(std::floor(n));
const auto integer = (qCeil(n) == i); const auto integer = (int(std::ceil(n)) == i);
const auto formatted = integer ? QString() : FormatDouble(n); const auto formatted = integer ? QString() : FormatDouble(n);
const auto dot = formatted.indexOf('.'); const auto dot = formatted.indexOf('.');
const auto fraction = (dot >= 0) ? formatted.mid(dot + 1) : QString(); const auto fraction = (dot >= 0) ? formatted.mid(dot + 1) : QString();
@ -963,7 +964,7 @@ PluralResult Plural(
const auto t = f; const auto t = f;
const auto useNonDefaultPlural = (ChoosePlural != ChoosePluralDefault) const auto useNonDefaultPlural = (ChoosePlural != ChoosePluralDefault)
&& Lang::Current().isNonDefaultPlural(keyBase); && Lang::details::IsNonDefaultPlural(keyBase);
const auto shift = (useNonDefaultPlural ? ChoosePlural : ChoosePluralDefault)( const auto shift = (useNonDefaultPlural ? ChoosePlural : ChoosePluralDefault)(
(integer ? i : -1), (integer ? i : -1),
i, i,

View file

@ -1,9 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "lang/lang_values.h"

View file

@ -22,16 +22,22 @@ inline constexpr ushort TagValue();
template <typename P> template <typename P>
using S = std::decay_t<decltype(std::declval<P>()(QString()))>; using S = std::decay_t<decltype(std::declval<P>()(QString()))>;
QString Current(ushort key); [[nodiscard]] QString Current(ushort key);
rpl::producer<QString> Viewer(ushort key); [[nodiscard]] rpl::producer<QString> Value(ushort key);
[[nodiscard]] bool IsNonDefaultPlural(ushort keyBase);
template <int Index, typename Type, typename Tuple> template <int Index, typename Type, typename Tuple>
Type ReplaceUnwrapTuple(Type accumulated, const Tuple &tuple) { [[nodiscard]] Type ReplaceUnwrapTuple(Type accumulated, const Tuple &tuple) {
return accumulated; return accumulated;
} }
template <int Index, typename Type, typename Tuple, typename Tag, typename ...Tags> template <
Type ReplaceUnwrapTuple( int Index,
typename Type,
typename Tuple,
typename Tag,
typename ...Tags>
[[nodiscard]] Type ReplaceUnwrapTuple(
Type accumulated, Type accumulated,
const Tuple &tuple, const Tuple &tuple,
Tag tag, Tag tag,
@ -51,7 +57,7 @@ struct ReplaceUnwrap;
template <> template <>
struct ReplaceUnwrap<> { struct ReplaceUnwrap<> {
template <typename Type> template <typename Type>
static Type Call(Type accumulated) { [[nodiscard]] static Type Call(Type accumulated) {
return accumulated; return accumulated;
} }
}; };
@ -59,7 +65,7 @@ struct ReplaceUnwrap<> {
template <typename Tag, typename ...Tags> template <typename Tag, typename ...Tags>
struct ReplaceUnwrap<Tag, Tags...> { struct ReplaceUnwrap<Tag, Tags...> {
template <typename Type, typename Value, typename ...Values> template <typename Type, typename Value, typename ...Values>
static Type Call( [[nodiscard]] static Type Call(
Type accumulated, Type accumulated,
const Value &value, const Value &value,
const Values &...values) { const Values &...values) {
@ -75,9 +81,9 @@ struct ReplaceUnwrap<Tag, Tags...> {
template <typename ...Tags> template <typename ...Tags>
struct Producer { struct Producer {
template <typename P, typename ...Values> template <typename P, typename ...Values>
static rpl::producer<S<P>> Combine(ushort base, P p, Values &...values) { [[nodiscard]] static rpl::producer<S<P>> Combine(ushort base, P p, Values &...values) {
return rpl::combine( return rpl::combine(
Viewer(base), Value(base),
std::move(values)... std::move(values)...
) | rpl::map([p = std::move(p)](auto tuple) { ) | rpl::map([p = std::move(p)](auto tuple) {
return ReplaceUnwrapTuple<1>(p(std::get<0>(tuple)), tuple, TagValue<Tags>()...); return ReplaceUnwrapTuple<1>(p(std::get<0>(tuple)), tuple, TagValue<Tags>()...);
@ -85,7 +91,7 @@ struct Producer {
} }
template <typename P, typename ...Values> template <typename P, typename ...Values>
static S<P> Current(ushort base, P p, const Values &...values) { [[nodiscard]] static S<P> Current(ushort base, P p, const Values &...values) {
return ReplaceUnwrap<Tags...>::template Call( return ReplaceUnwrap<Tags...>::template Call(
p(Lang::details::Current(base)), p(Lang::details::Current(base)),
values...); values...);
@ -95,12 +101,12 @@ struct Producer {
template <> template <>
struct Producer<> { struct Producer<> {
template <typename P> template <typename P>
static rpl::producer<S<P>> Combine(ushort base, P p) { [[nodiscard]] static rpl::producer<S<P>> Combine(ushort base, P p) {
return Viewer(base) | rpl::map(std::move(p)); return Value(base) | rpl::map(std::move(p));
} }
template <typename P> template <typename P>
static S<P> Current(ushort base, P p) { [[nodiscard]] static S<P> Current(ushort base, P p) {
return p(Lang::details::Current(base)); return p(Lang::details::Current(base));
} }
}; };
@ -108,19 +114,19 @@ struct Producer<> {
template <typename ...Tags> template <typename ...Tags>
struct Producer<lngtag_count, Tags...> { struct Producer<lngtag_count, Tags...> {
template <typename P, typename ...Values> template <typename P, typename ...Values>
static rpl::producer<S<P>> Combine( [[nodiscard]] static rpl::producer<S<P>> Combine(
ushort base, ushort base,
P p, P p,
lngtag_count type, lngtag_count type,
rpl::producer<float64> &count, rpl::producer<float64> &count,
Values &...values) { Values &...values) {
return rpl::combine( return rpl::combine(
Viewer(base), Value(base),
Viewer(base + 1), Value(base + 1),
Viewer(base + 2), Value(base + 2),
Viewer(base + 3), Value(base + 3),
Viewer(base + 4), Value(base + 4),
Viewer(base + 5), Value(base + 5),
std::move(count), std::move(count),
std::move(values)... std::move(values)...
) | rpl::map([base, type, p = std::move(p)](auto tuple) { ) | rpl::map([base, type, p = std::move(p)](auto tuple) {
@ -148,7 +154,7 @@ struct Producer<lngtag_count, Tags...> {
} }
template <typename P, typename ...Values> template <typename P, typename ...Values>
static S<P> Current( [[nodiscard]] static S<P> Current(
ushort base, ushort base,
P p, P p,
lngtag_count type, lngtag_count type,

View file

@ -321,7 +321,10 @@ OverlayWidget::OverlayWidget()
, _stateAnimation([=](crl::time now) { return stateAnimationCallback(now); }) , _stateAnimation([=](crl::time now) { return stateAnimationCallback(now); })
, _dropdown(this, st::mediaviewDropdownMenu) , _dropdown(this, st::mediaviewDropdownMenu)
, _dropdownShowTimer(this) { , _dropdownShowTimer(this) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); }); Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
_lastPositiveVolume = (Core::App().settings().videoVolume() > 0.) _lastPositiveVolume = (Core::App().settings().videoVolume() > 0.)
? Core::App().settings().videoVolume() ? Core::App().settings().videoVolume()

View file

@ -63,7 +63,6 @@ using OverlayParent = Ui::RpWidget;
class OverlayWidget final class OverlayWidget final
: public OverlayParent : public OverlayParent
, private base::Subscriber
, public ClickHandlerHost , public ClickHandlerHost
, private PlaybackControls::Delegate { , private PlaybackControls::Delegate {
Q_OBJECT Q_OBJECT

View file

@ -1661,15 +1661,15 @@ DcId Instance::mainDcId() const {
} }
QString Instance::systemLangCode() const { QString Instance::systemLangCode() const {
return Lang::Current().systemLangCode(); return Lang::GetInstance().systemLangCode();
} }
QString Instance::cloudLangCode() const { QString Instance::cloudLangCode() const {
return Lang::Current().cloudLangCode(Lang::Pack::Current); return Lang::GetInstance().cloudLangCode(Lang::Pack::Current);
} }
QString Instance::langPackName() const { QString Instance::langPackName() const {
return Lang::Current().langPackName(); return Lang::GetInstance().langPackName();
} }
rpl::producer<> Instance::writeKeysRequests() const { rpl::producer<> Instance::writeKeysRequests() const {

View file

@ -302,7 +302,7 @@ EditDocumentScheme GetDocumentScheme(
if (i == end(config.languagesByCountryCode)) { if (i == end(config.languagesByCountryCode)) {
return QString(); return QString();
} }
return Lang::Current().getNonDefaultValue( return Lang::GetNonDefaultValue(
kLanguageNamePrefix + i->second.toUtf8()); kLanguageNamePrefix + i->second.toUtf8());
}; };
result.additionalHeader = [=](const QString &countryCode) { result.additionalHeader = [=](const QString &countryCode) {

View file

@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_cloud_themes.h" #include "data/data_cloud_themes.h"
#include "data/data_chat_filters.h" #include "data/data_chat_filters.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "lang/lang_instance.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "main/main_session_settings.h" #include "main/main_session_settings.h"
@ -48,10 +49,10 @@ void SetupLanguageButton(
container, container,
tr::lng_settings_language(), tr::lng_settings_language(),
rpl::single( rpl::single(
Lang::Current().id() Lang::GetInstance().id()
) | rpl::then( ) | rpl::then(
Lang::Current().idChanges() Lang::GetInstance().idChanges()
) | rpl::map([] { return Lang::Current().nativeName(); }), ) | rpl::map([] { return Lang::GetInstance().nativeName(); }),
icon ? st::settingsSectionButton : st::settingsButton, icon ? st::settingsSectionButton : st::settingsButton,
icon ? &st::settingsIconLanguage : nullptr); icon ? &st::settingsIconLanguage : nullptr);
const auto guard = Ui::CreateChild<base::binary_guard>(button.get()); const auto guard = Ui::CreateChild<base::binary_guard>(button.get());

View file

@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_account.h" #include "main/main_account.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "lang/lang_instance.h"
#include "facades.h" #include "facades.h"
#include <QtCore/QDirIterator> #include <QtCore/QDirIterator>
@ -1092,12 +1093,12 @@ void readLangPack() {
auto data = QByteArray(); auto data = QByteArray();
langpack.stream >> data; langpack.stream >> data;
if (langpack.stream.status() == QDataStream::Ok) { if (langpack.stream.status() == QDataStream::Ok) {
Lang::Current().fillFromSerialized(data, langpack.version); Lang::GetInstance().fillFromSerialized(data, langpack.version);
} }
} }
void writeLangPack() { void writeLangPack() {
auto langpack = Lang::Current().serialize(); auto langpack = Lang::GetInstance().serialize();
if (!_langPackKey) { if (!_langPackKey) {
_langPackKey = GenerateKey(_basePath); _langPackKey = GenerateKey(_basePath);
writeSettings(); writeSettings();

View file

@ -416,7 +416,7 @@ Widget::Widget(
QPoint startPosition, QPoint startPosition,
int shift, int shift,
Direction shiftDirection) Direction shiftDirection)
: TWidget(Core::App().getModalParent()) : RpWidget(Core::App().getModalParent())
, _manager(manager) , _manager(manager)
, _startPosition(startPosition) , _startPosition(startPosition)
, _direction(shiftDirection) , _direction(shiftDirection)
@ -587,7 +587,10 @@ Notification::Notification(
, _fromScheduled(fromScheduled) , _fromScheduled(fromScheduled)
, _close(this, st::notifyClose) , _close(this, st::notifyClose)
, _reply(this, tr::lng_notification_reply(), st::defaultBoxButton) { , _reply(this, tr::lng_notification_reply(), st::defaultBoxButton) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); }); Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
auto position = computePosition(st::notifyMinHeight); auto position = computePosition(st::notifyMinHeight);
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight); updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight);

View file

@ -122,7 +122,7 @@ private:
namespace internal { namespace internal {
class Widget : public TWidget, protected base::Subscriber { class Widget : public Ui::RpWidget, protected base::Subscriber {
public: public:
enum class Direction { enum class Direction {
Up, Up,

View file

@ -25,7 +25,11 @@ HistoryHider::HistoryHider(
: RpWidget(parent) : RpWidget(parent)
, _text(text) , _text(text)
, _confirm(std::move(confirm)) { , _confirm(std::move(confirm)) {
subscribe(Lang::Current().updated(), [=] { refreshLang(); }); Lang::Updated(
) | rpl::start_with_next([=] {
refreshLang();
}, lifetime());
subscribe(Global::RefPeerChooseCancel(), [=] { startHide(); }); subscribe(Global::RefPeerChooseCancel(), [=] { startHide(); });
_chooseWidth = st::historyForwardChooseFont->width(_text); _chooseWidth = st::historyForwardChooseFont->width(_text);

View file

@ -0,0 +1,39 @@
# This file is part of Telegram Desktop,
# the official desktop application for the Telegram messaging service.
#
# For license and copyright information please follow this link:
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
add_library(td_lang OBJECT)
init_target(td_lang)
add_library(tdesktop::td_lang ALIAS td_lang)
include(cmake/generate_lang.cmake)
generate_lang(td_lang ${res_loc}/langs/lang.strings)
target_precompile_headers(td_lang PRIVATE ${src_loc}/lang/lang_pch.h)
nice_target_sources(td_lang ${src_loc}
PRIVATE
lang/lang_file_parser.cpp
lang/lang_file_parser.h
lang/lang_hardcoded.h
lang/lang_keys.cpp
lang/lang_keys.h
lang/lang_pch.h
lang/lang_tag.cpp
lang/lang_tag.h
lang/lang_text_entity.cpp
lang/lang_text_entity.h
lang/lang_values.h
)
target_include_directories(td_lang
PUBLIC
${src_loc}
)
target_link_libraries(td_lang
PUBLIC
desktop-app::lib_ui
)

View file

@ -40,5 +40,6 @@ PUBLIC
target_link_libraries(td_ui target_link_libraries(td_ui
PUBLIC PUBLIC
tdesktop::td_lang
desktop-app::lib_ui desktop-app::lib_ui
) )

@ -1 +1 @@
Subproject commit 03ea7a05e62332ee4e41d00606e9f80cfdd95f33 Subproject commit e712f9b3de36ed387c5ab08b2b48e1984f682314