diff --git a/Telegram/SourceFiles/base/lambda.h b/Telegram/SourceFiles/base/lambda.h index 206a0e2e2..6bf720563 100644 --- a/Telegram/SourceFiles/base/lambda.h +++ b/Telegram/SourceFiles/base/lambda.h @@ -335,12 +335,12 @@ public: } // Copy / move construct / assign from an arbitrary type. - template ()(std::declval()...))> + template ()(std::declval()...)),Return>::value>> lambda_once(Lambda other) { data_.vtable = &lambda_internal::vtable_once::instance; lambda_internal::vtable_once::construct_move_lambda_method(data_.storage, &other); } - template ()(std::declval()...))> + template ()(std::declval()...)),Return>::value>> lambda_once &operator=(Lambda other) { if (data_.vtable) { data_.vtable->destruct(data_.storage); @@ -414,11 +414,11 @@ public: } // Copy / move construct / assign from an arbitrary type. - template ()(std::declval()...))> + template ()(std::declval()...)),Return>::value>> lambda(Lambda other) : Parent(&lambda_internal::vtable::instance, typename Parent::Private()) { lambda_internal::vtable::construct_move_lambda_method(this->data_.storage, &other); } - template ()(std::declval()...))> + template ()(std::declval()...)),Return>::value>> lambda &operator=(Lambda other) { if (this->data_.vtable) { this->data_.vtable->destruct(this->data_.storage); diff --git a/Telegram/SourceFiles/boxes/about_box.cpp b/Telegram/SourceFiles/boxes/about_box.cpp index a87edf141..6f2ed8504 100644 --- a/Telegram/SourceFiles/boxes/about_box.cpp +++ b/Telegram/SourceFiles/boxes/about_box.cpp @@ -39,9 +39,10 @@ AboutBox::AboutBox(QWidget *parent) } void AboutBox::prepare() { - setTitle(qsl("Telegram Desktop")); + constexpr auto test = std::is_convertible::value; + setTitle([] { return qsl("Telegram Desktop"); }); - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); _text3->setRichText(lng_about_text_3(lt_faq_open, qsl("[a href=\"%1\"]").arg(telegramFaqLink()), lt_faq_close, qsl("[/a]"))); diff --git a/Telegram/SourceFiles/boxes/abstract_box.cpp b/Telegram/SourceFiles/boxes/abstract_box.cpp index 5f3c7e680..d37f9fda4 100644 --- a/Telegram/SourceFiles/boxes/abstract_box.cpp +++ b/Telegram/SourceFiles/boxes/abstract_box.cpp @@ -33,12 +33,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org BoxLayerTitleShadow::BoxLayerTitleShadow(QWidget *parent) : Ui::PlainShadow(parent, st::boxLayerTitleShadow) { } -QPointer BoxContent::addButton(const QString &text, base::lambda clickCallback) { - return addButton(text, std::move(clickCallback), st::defaultBoxButton); +QPointer BoxContent::addButton(base::lambda textFactory, base::lambda clickCallback) { + return addButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton); } -QPointer BoxContent::addLeftButton(const QString &text, base::lambda clickCallback) { - return getDelegate()->addLeftButton(text, std::move(clickCallback), st::defaultBoxButton); +QPointer BoxContent::addLeftButton(base::lambda textFactory, base::lambda clickCallback) { + return getDelegate()->addLeftButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton); } void BoxContent::setInner(object_ptr inner) { @@ -198,6 +198,7 @@ void BoxContent::paintEvent(QPaintEvent *e) { AbstractBox::AbstractBox(QWidget *parent, Window::Controller *controller, object_ptr content) : LayerWidget(parent) , _controller(controller) , _content(std::move(content)) { + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); _content->setParent(this); _content->setDelegate(this); } @@ -256,17 +257,18 @@ void AbstractBox::parentResized() { update(); } -void AbstractBox::setTitle(const QString &title) { - setTitle({ title, EntitiesInText() }); +void AbstractBox::setTitle(base::lambda titleFactory) { + _titleFactory = std::move(titleFactory); + refreshTitle(); } -void AbstractBox::setTitle(const TextWithEntities &title) { +void AbstractBox::refreshTitle() { auto wasTitle = hasTitle(); - if (!title.text.isEmpty()) { + if (_titleFactory) { if (!_title) { _title.create(this, st::boxTitle); } - _title->setMarkedText(title); + _title->setMarkedText(_titleFactory()); updateTitlePosition(); } else { _title.destroy(); @@ -276,11 +278,22 @@ void AbstractBox::setTitle(const TextWithEntities &title) { } } -void AbstractBox::setAdditionalTitle(const QString &additional) { - _additionalTitle = additional; +void AbstractBox::setAdditionalTitle(base::lambda additionalFactory) { + _additionalTitleFactory = std::move(additionalFactory); + refreshAdditionalTitle(); +} + +void AbstractBox::refreshAdditionalTitle() { + _additionalTitle = _additionalTitleFactory ? _additionalTitleFactory() : QString(); update(); } +void AbstractBox::refreshLang() { + refreshTitle(); + refreshAdditionalTitle(); + InvokeQueued(this, [this] { updateButtonsPositions(); }); +} + bool AbstractBox::hasTitle() const { return (_title != nullptr) || !_additionalTitle.isEmpty(); } @@ -320,8 +333,8 @@ void AbstractBox::clearButtons() { _leftButton.destroy(); } -QPointer AbstractBox::addButton(const QString &text, base::lambda clickCallback, const style::RoundButton &st) { - _buttons.push_back(object_ptr(this, text, st)); +QPointer AbstractBox::addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) { + _buttons.push_back(object_ptr(this, std::move(textFactory), st)); auto result = QPointer(_buttons.back()); result->setClickedCallback(std::move(clickCallback)); result->show(); @@ -329,8 +342,8 @@ QPointer AbstractBox::addButton(const QString &text, base::lamb return result; } -QPointer AbstractBox::addLeftButton(const QString &text, base::lambda clickCallback, const style::RoundButton &st) { - _leftButton = object_ptr(this, text, st); +QPointer AbstractBox::addLeftButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) { + _leftButton = object_ptr(this, std::move(textFactory), st); auto result = QPointer(_leftButton); result->setClickedCallback(std::move(clickCallback)); result->show(); diff --git a/Telegram/SourceFiles/boxes/abstract_box.h b/Telegram/SourceFiles/boxes/abstract_box.h index 386d44c8e..0bba4d45b 100644 --- a/Telegram/SourceFiles/boxes/abstract_box.h +++ b/Telegram/SourceFiles/boxes/abstract_box.h @@ -47,13 +47,12 @@ public: virtual Window::Controller *controller() const = 0; virtual void setLayerType(bool layerType) = 0; - virtual void setTitle(const QString &title) = 0; - virtual void setTitle(const TextWithEntities &title) = 0; - virtual void setAdditionalTitle(const QString &additional) = 0; + virtual void setTitle(base::lambda titleFactory) = 0; + virtual void setAdditionalTitle(base::lambda additionalFactory) = 0; virtual void clearButtons() = 0; - virtual QPointer addButton(const QString &text, base::lambda clickCallback, const style::RoundButton &st) = 0; - virtual QPointer addLeftButton(const QString &text, base::lambda clickCallback, const style::RoundButton &st) = 0; + virtual QPointer addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) = 0; + virtual QPointer addLeftButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) = 0; virtual void updateButtonsPositions() = 0; virtual void setDimensions(int newWidth, int maxHeight) = 0; @@ -78,23 +77,27 @@ public: getDelegate()->closeBox(); } - void setTitle(const QString &title) { - getDelegate()->setTitle(title); + void setTitle(base::lambda titleFactory) { + if (titleFactory) { + getDelegate()->setTitle([titleFactory] { return TextWithEntities { titleFactory(), EntitiesInText() }; }); + } else { + getDelegate()->setTitle(base::lambda()); + } } - void setTitle(const TextWithEntities &title) { - getDelegate()->setTitle(title); + void setTitle(base::lambda titleFactory) { + getDelegate()->setTitle(std::move(titleFactory)); } - void setAdditionalTitle(const QString &additional) { - getDelegate()->setAdditionalTitle(additional); + void setAdditionalTitle(base::lambda additional) { + getDelegate()->setAdditionalTitle(std::move(additional)); } void clearButtons() { getDelegate()->clearButtons(); } - QPointer addButton(const QString &text, base::lambda clickCallback); - QPointer addLeftButton(const QString &text, base::lambda clickCallback); - QPointer addButton(const QString &text, base::lambda clickCallback, const style::RoundButton &st) { - return getDelegate()->addButton(text, std::move(clickCallback), st); + QPointer addButton(base::lambda textFactory, base::lambda clickCallback); + QPointer addLeftButton(base::lambda textFactory, base::lambda clickCallback); + QPointer addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) { + return getDelegate()->addButton(std::move(textFactory), std::move(clickCallback), st); } void updateButtonsGeometry() { getDelegate()->updateButtonsPositions(); @@ -208,13 +211,12 @@ public: void parentResized() override; void setLayerType(bool layerType) override; - void setTitle(const QString &title) override; - void setTitle(const TextWithEntities &title) override; - void setAdditionalTitle(const QString &additional) override; + void setTitle(base::lambda titleFactory) override; + void setAdditionalTitle(base::lambda additionalFactory) override; void clearButtons() override; - QPointer addButton(const QString &text, base::lambda clickCallback, const style::RoundButton &st) override; - QPointer addLeftButton(const QString &text, base::lambda clickCallback, const style::RoundButton &st) override; + QPointer addButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) override; + QPointer addLeftButton(base::lambda textFactory, base::lambda clickCallback, const style::RoundButton &st) override; void updateButtonsPositions() override; void setDimensions(int newWidth, int maxHeight) override; @@ -248,6 +250,9 @@ protected: private: void paintAdditionalTitle(Painter &p); void updateTitlePosition(); + void refreshTitle(); + void refreshAdditionalTitle(); + void refreshLang(); bool hasTitle() const; int titleHeight() const; @@ -266,7 +271,9 @@ private: object_ptr _content; object_ptr _title = { nullptr }; + base::lambda _titleFactory; QString _additionalTitle; + base::lambda _additionalTitleFactory; int _titleLeft = 0; int _titleTop = 0; bool _layerType = false; diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index 16ca841d2..622560bf5 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -41,9 +41,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "auth_session.h" AddContactBox::AddContactBox(QWidget*, QString fname, QString lname, QString phone) -: _first(this, st::defaultInputField, lang(lng_signup_firstname), fname) -, _last(this, st::defaultInputField, lang(lng_signup_lastname), lname) -, _phone(this, st::defaultInputField, lang(lng_contact_phone), phone) +: _first(this, st::defaultInputField, langFactory(lng_signup_firstname), fname) +, _last(this, st::defaultInputField, langFactory(lng_signup_lastname), lname) +, _phone(this, st::defaultInputField, langFactory(lng_contact_phone), phone) , _invertOrder(langFirstNameGoesSecond()) { if (!phone.isEmpty()) { _phone->setDisabled(true); @@ -52,9 +52,9 @@ AddContactBox::AddContactBox(QWidget*, QString fname, QString lname, QString pho AddContactBox::AddContactBox(QWidget*, UserData *user) : _user(user) -, _first(this, st::defaultInputField, lang(lng_signup_firstname), user->firstName) -, _last(this, st::defaultInputField, lang(lng_signup_lastname), user->lastName) -, _phone(this, st::defaultInputField, lang(lng_contact_phone), user->phone()) +, _first(this, st::defaultInputField, langFactory(lng_signup_firstname), user->firstName) +, _last(this, st::defaultInputField, langFactory(lng_signup_lastname), user->lastName) +, _phone(this, st::defaultInputField, langFactory(lng_contact_phone), user->phone()) , _invertOrder(langFirstNameGoesSecond()) { _phone->setDisabled(true); } @@ -64,10 +64,10 @@ void AddContactBox::prepare() { setTabOrder(_last, _first); } if (_user) { - setTitle(lang(lng_edit_contact_title)); + setTitle(langFactory(lng_edit_contact_title)); } else { - bool readyToAdd = !_phone->getLastText().isEmpty() && (!_first->getLastText().isEmpty() || !_last->getLastText().isEmpty()); - setTitle(lang(readyToAdd ? lng_confirm_contact_data : lng_enter_contact_data)); + auto readyToAdd = !_phone->getLastText().isEmpty() && (!_first->getLastText().isEmpty() || !_last->getLastText().isEmpty()); + setTitle(langFactory(readyToAdd ? lng_confirm_contact_data : lng_enter_contact_data)); } updateButtons(); @@ -236,10 +236,10 @@ void AddContactBox::onRetry() { void AddContactBox::updateButtons() { clearButtons(); if (_retrying) { - addButton(lang(lng_try_other_contact), [this] { onRetry(); }); + addButton(langFactory(lng_try_other_contact), [this] { onRetry(); }); } else { - addButton(lang(_user ? lng_settings_save : lng_add_contact), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(_user ? lng_settings_save : lng_add_contact), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } } @@ -247,7 +247,7 @@ GroupInfoBox::GroupInfoBox(QWidget*, CreatingGroupType creating, bool fromTypeCh : _creating(creating) , _fromTypeChoose(fromTypeChoose) , _photo(this, st::newGroupPhotoSize, st::newGroupPhotoIconPosition) -, _title(this, st::defaultInputField, lang(_creating == CreatingGroupChannel ? lng_dlg_new_channel_name : lng_dlg_new_group_name)) { +, _title(this, st::defaultInputField, langFactory(_creating == CreatingGroupChannel ? lng_dlg_new_channel_name : lng_dlg_new_group_name)) { } void GroupInfoBox::prepare() { @@ -256,7 +256,7 @@ void GroupInfoBox::prepare() { _title->setMaxLength(MaxGroupChannelTitle); if (_creating == CreatingGroupChannel) { - _description.create(this, st::newGroupDescription, lang(lng_create_group_description)); + _description.create(this, st::newGroupDescription, langFactory(lng_create_group_description)); _description->show(); _description->setMaxLength(MaxChannelDescription); @@ -267,8 +267,8 @@ void GroupInfoBox::prepare() { connect(_title, SIGNAL(submitted(bool)), this, SLOT(onNameSubmit())); - addButton(lang(_creating == CreatingGroupChannel ? lng_create_group_create : lng_create_group_next), [this] { onNext(); }); - addButton(lang(_fromTypeChoose ? lng_create_group_back : lng_cancel), [this] { closeBox(); }); + addButton(langFactory(_creating == CreatingGroupChannel ? lng_create_group_create : lng_create_group_next), [this] { onNext(); }); + addButton(langFactory(_fromTypeChoose ? lng_create_group_back : lng_cancel), [this] { closeBox(); }); setupPhotoButton(); @@ -425,7 +425,7 @@ SetupChannelBox::SetupChannelBox(QWidget*, ChannelData *channel, bool existing) , _aboutPublicWidth(st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultBoxCheckbox.textPosition.x()) , _aboutPublic(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth) , _aboutPrivate(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth) -, _link(this, st::setupChannelLink, QString(), channel->username, true) { +, _link(this, st::setupChannelLink, base::lambda(), channel->username, true) { } void SetupChannelBox::prepare() { @@ -435,8 +435,8 @@ void SetupChannelBox::prepare() { _checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string("preston")), RPCDoneHandlerPtr(), rpcFail(&SetupChannelBox::onFirstCheckFail)); - addButton(lang(lng_settings_save), [this] { onSave(); }); - addButton(lang(_existing ? lng_cancel : lng_create_group_skip), [this] { closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { onSave(); }); + addButton(langFactory(_existing ? lng_cancel : lng_create_group_skip), [this] { closeBox(); }); connect(_link, SIGNAL(changed()), this, SLOT(onChange())); _link->setVisible(_privacyGroup->value() == Privacy::Public); @@ -758,26 +758,26 @@ bool SetupChannelBox::onFirstCheckFail(const RPCError &error) { return true; } -EditNameTitleBox::EditNameTitleBox(QWidget*, PeerData *peer) +EditNameTitleBox::EditNameTitleBox(QWidget*, gsl::not_null peer) : _peer(peer) -, _first(this, st::defaultInputField, lang(peer->isUser() ? lng_signup_firstname : lng_dlg_new_group_name), peer->isUser() ? peer->asUser()->firstName : peer->name) -, _last(this, st::defaultInputField, lang(lng_signup_lastname), peer->isUser() ? peer->asUser()->lastName : QString()) +, _first(this, st::defaultInputField, langFactory(_peer->isUser() ? lng_signup_firstname : lng_dlg_new_group_name), _peer->isUser() ? _peer->asUser()->firstName : _peer->name) +, _last(this, st::defaultInputField, langFactory(lng_signup_lastname), peer->isUser() ? peer->asUser()->lastName : QString()) , _invertOrder(!peer->isChat() && langFirstNameGoesSecond()) { } void EditNameTitleBox::prepare() { auto newHeight = st::contactPadding.top() + _first->height(); if (_peer->isUser()) { - setTitle(lang(_peer == App::self() ? lng_edit_self_title : lng_edit_contact_title)); + setTitle(langFactory(_peer->isSelf() ? lng_edit_self_title : lng_edit_contact_title)); newHeight += st::contactSkip + _last->height(); } else if (_peer->isChat()) { - setTitle(lang(lng_edit_group_title)); + setTitle(langFactory(lng_edit_group_title)); } newHeight += st::boxPadding.bottom() + st::contactPadding.bottom(); setDimensions(st::boxWideWidth, newHeight); - addButton(lang(lng_settings_save), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); if (_invertOrder) { setTabOrder(_last, _first); } @@ -913,17 +913,17 @@ void EditNameTitleBox::onSaveChatDone(const MTPUpdates &updates) { EditChannelBox::EditChannelBox(QWidget*, ChannelData *channel) : _channel(channel) -, _title(this, st::defaultInputField, lang(channel->isMegagroup() ? lng_dlg_new_group_name : lng_dlg_new_channel_name), _channel->name) -, _description(this, st::newGroupDescription, lang(lng_create_group_description), _channel->about()) +, _title(this, st::defaultInputField, langFactory(_channel->isMegagroup() ? lng_dlg_new_group_name : lng_dlg_new_channel_name), _channel->name) +, _description(this, st::newGroupDescription, langFactory(lng_create_group_description), _channel->about()) , _sign(this, lang(lng_edit_sign_messages), channel->addsSignature(), st::defaultBoxCheckbox) , _publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), st::boxLinkButton) { } void EditChannelBox::prepare() { - setTitle(lang(_channel->isMegagroup() ? lng_edit_group : lng_edit_channel_title)); + setTitle(langFactory(_channel->isMegagroup() ? lng_edit_group : lng_edit_channel_title)); - addButton(lang(lng_settings_save), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); connect(App::main(), SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(peerUpdated(PeerData*))); @@ -1116,7 +1116,7 @@ void RevokePublicLinkBox::prepare() { MTP::send(MTPchannels_GetAdminedPublicChannels(), rpcDone(&RevokePublicLinkBox::getPublicDone), rpcFail(&RevokePublicLinkBox::getPublicFail)); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); subscribe(AuthSession::CurrentDownloaderTaskFinished(), [this] { update(); }); diff --git a/Telegram/SourceFiles/boxes/add_contact_box.h b/Telegram/SourceFiles/boxes/add_contact_box.h index b16503a23..c742c7542 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.h +++ b/Telegram/SourceFiles/boxes/add_contact_box.h @@ -199,7 +199,7 @@ class EditNameTitleBox : public BoxContent, public RPCSender { Q_OBJECT public: - EditNameTitleBox(QWidget*, PeerData *peer); + EditNameTitleBox(QWidget*, gsl::not_null peer); protected: void setInnerFocus() override; @@ -218,7 +218,7 @@ private: void onSaveChatDone(const MTPUpdates &updates); bool onSaveChatFail(const RPCError &e); - PeerData *_peer; + gsl::not_null _peer; object_ptr _first; object_ptr _last; diff --git a/Telegram/SourceFiles/boxes/autolock_box.cpp b/Telegram/SourceFiles/boxes/autolock_box.cpp index 0573908e0..86f7f4e43 100644 --- a/Telegram/SourceFiles/boxes/autolock_box.cpp +++ b/Telegram/SourceFiles/boxes/autolock_box.cpp @@ -27,9 +27,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "styles/style_boxes.h" void AutoLockBox::prepare() { - setTitle(lang(lng_passcode_autolock)); + setTitle(langFactory(lng_passcode_autolock)); - addButton(lang(lng_box_ok), [this] { closeBox(); }); + addButton(langFactory(lng_box_ok), [this] { closeBox(); }); auto options = { 60, 300, 3600, 18000 }; diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index 594c6b21a..a78091623 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -63,9 +63,9 @@ BackgroundBox::BackgroundBox(QWidget*) { } void BackgroundBox::prepare() { - setTitle(lang(lng_backgrounds_header)); + setTitle(langFactory(lng_backgrounds_header)); - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); setDimensions(st::boxWideWidth, st::boxMaxListHeight); diff --git a/Telegram/SourceFiles/boxes/calendar_box.cpp b/Telegram/SourceFiles/boxes/calendar_box.cpp index f8827b80e..e18ee7f97 100644 --- a/Telegram/SourceFiles/boxes/calendar_box.cpp +++ b/Telegram/SourceFiles/boxes/calendar_box.cpp @@ -463,7 +463,7 @@ void CalendarBox::prepare() { // _inner = setInnerWidget(object_ptr(this, _context.get()), st::calendarScroll, st::calendarTitleHeight); _inner->setDateChosenCallback(std::move(_callback)); - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); subscribe(_context->month(), [this](QDate month) { monthChanged(month); }); diff --git a/Telegram/SourceFiles/boxes/change_phone_box.cpp b/Telegram/SourceFiles/boxes/change_phone_box.cpp index 5c17f7c89..8a2659f7c 100644 --- a/Telegram/SourceFiles/boxes/change_phone_box.cpp +++ b/Telegram/SourceFiles/boxes/change_phone_box.cpp @@ -113,10 +113,10 @@ private: }; void ChangePhoneBox::EnterPhone::prepare() { - setTitle(lang(lng_change_phone_title)); + setTitle(langFactory(lng_change_phone_title)); auto phoneValue = QString(); - _phone.create(this, st::defaultInputField, lang(lng_change_phone_new_title), phoneValue); + _phone.create(this, st::defaultInputField, langFactory(lng_change_phone_new_title), phoneValue); _phone->resize(st::boxWidth - 2 * st::boxPadding.left(), _phone->height()); _phone->moveToLeft(st::boxPadding.left(), st::boxLittleSkip); @@ -128,8 +128,8 @@ void ChangePhoneBox::EnterPhone::prepare() { setDimensions(st::boxWidth, description->bottomNoMargins() + st::boxLittleSkip); - addButton(lang(lng_change_phone_new_submit), [this] { submit(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_change_phone_new_submit), [this] { submit(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } void ChangePhoneBox::EnterPhone::submit() { @@ -206,14 +206,14 @@ ChangePhoneBox::EnterCode::EnterCode(QWidget*, const QString &phone, const QStri } void ChangePhoneBox::EnterCode::prepare() { - setTitle(lang(lng_change_phone_title)); + setTitle(langFactory(lng_change_phone_title)); auto descriptionText = lng_change_phone_code_description(lt_phone, textcmdStartSemibold() + App::formatPhone(_phone) + textcmdStopSemibold()); auto description = object_ptr(this, descriptionText, Ui::FlatLabel::InitType::Rich, st::changePhoneLabel); description->moveToLeft(st::boxPadding.left(), 0); auto phoneValue = QString(); - _code.create(this, st::defaultInputField, lang(lng_change_phone_code_title), phoneValue); + _code.create(this, st::defaultInputField, langFactory(lng_change_phone_code_title), phoneValue); _code->setAutoSubmit(_codeLength, [this] { submit(); }); _code->setChangedCallback([this] { hideError(); }); @@ -228,8 +228,8 @@ void ChangePhoneBox::EnterCode::prepare() { updateCall(); } - addButton(lang(lng_change_phone_new_submit), [this] { submit(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_change_phone_new_submit), [this] { submit(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } int ChangePhoneBox::EnterCode::countHeight() { @@ -302,13 +302,13 @@ bool ChangePhoneBox::EnterCode::sendCodeFail(const RPCError &error) { } void ChangePhoneBox::prepare() { - setTitle(lang(lng_change_phone_title)); - addButton(lang(lng_change_phone_button), [] { + setTitle(langFactory(lng_change_phone_title)); + addButton(langFactory(lng_change_phone_button), [] { Ui::show(Box(lang(lng_change_phone_warning), [] { Ui::show(Box()); })); }); - addButton(lang(lng_cancel), [this] { + addButton(langFactory(lng_cancel), [this] { closeBox(); }); diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 3a3bad473..11f30dcdb 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -115,9 +115,9 @@ void ConfirmBox::init(const QString &text) { } void ConfirmBox::prepare() { - addButton(_confirmText, [this] { confirmed(); }, _confirmStyle); + addButton([this] { return _confirmText; }, [this] { confirmed(); }, _confirmStyle); if (!_informative) { - addButton(_cancelText, [this] { _cancelled = true; closeBox(); }); + addButton([this] { return _cancelText; }, [this] { _cancelled = true; closeBox(); }); } textUpdated(); } @@ -225,7 +225,7 @@ MaxInviteBox::MaxInviteBox(QWidget*, const QString &link) void MaxInviteBox::prepare() { setMouseTracking(true); - addButton(lang(lng_box_ok), [this] { closeBox(); }); + addButton(langFactory(lng_box_ok), [this] { closeBox(); }); _textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right(); _textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxLabelStyle.lineHeight); @@ -293,10 +293,10 @@ void ConvertToSupergroupBox::prepare() { text.push_back(lang(lng_profile_convert_feature3)); text.push_back(lang(lng_profile_convert_feature4)); - setTitle(lang(lng_profile_convert_title)); + setTitle(langFactory(lng_profile_convert_title)); - addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_profile_convert_confirm), [this] { convertToSupergroup(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); _text.setText(st::boxLabelStyle, text.join('\n'), _confirmBoxTextOptions); _note.setText(st::boxLabelStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions); @@ -363,8 +363,8 @@ PinMessageBox::PinMessageBox(QWidget*, ChannelData *channel, MsgId msgId) } void PinMessageBox::prepare() { - addButton(lang(lng_pinned_pin), [this] { pinMessage(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_pinned_pin), [this] { pinMessage(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); setDimensions(st::boxWidth, st::boxPadding.top() + _text->height() + st::boxMediumSkip + _notify->heightNoMargins() + st::boxPadding.bottom()); } @@ -471,8 +471,8 @@ void DeleteMessagesBox::prepare() { } _text.create(this, text, Ui::FlatLabel::InitType::Simple, st::boxLabel); - addButton(lang(lng_box_delete), [this] { deleteAndClear(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_box_delete), [this] { deleteAndClear(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); auto fullHeight = st::boxPadding.top() + _text->height() + st::boxPadding.bottom(); if (_moderateFrom) { @@ -576,12 +576,12 @@ ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, const MTPChat } void ConfirmInviteBox::prepare() { - addButton(lang(lng_group_invite_join), [this] { + addButton(langFactory(lng_group_invite_join), [this] { if (auto main = App::main()) { main->onInviteImport(); } }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); if (_participants.size() > 4) { _participants.resize(4); diff --git a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp index 196e2d101..1b2724198 100644 --- a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp @@ -210,14 +210,14 @@ void ConfirmPhoneBox::prepare() { } _about->setMarkedText(aboutText); - _code.create(this, st::confirmPhoneCodeField, lang(lng_code_ph)); + _code.create(this, st::confirmPhoneCodeField, langFactory(lng_code_ph)); _code->setAutoSubmit(_sentCodeLength, [this] { onSendCode(); }); _code->setChangedCallback([this] { showError(QString()); }); - setTitle(lang(lng_confirm_phone_title)); + setTitle(langFactory(lng_confirm_phone_title)); - addButton(lang(lng_confirm_phone_send), [this] { onSendCode(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_confirm_phone_send), [this] { onSendCode(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); setDimensions(st::boxWidth, st::usernamePadding.top() + _code->height() + st::usernameSkip + _about->height() + st::usernameSkip); diff --git a/Telegram/SourceFiles/boxes/confirm_phone_box.h b/Telegram/SourceFiles/boxes/confirm_phone_box.h index 1e510a40c..88554f4de 100644 --- a/Telegram/SourceFiles/boxes/confirm_phone_box.h +++ b/Telegram/SourceFiles/boxes/confirm_phone_box.h @@ -30,7 +30,7 @@ class FlatLabel; class SentCodeField : public Ui::InputField { public: - SentCodeField(QWidget *parent, const style::InputField &st, const QString &ph = QString(), const QString &val = QString()) : Ui::InputField(parent, st, ph, val) { + SentCodeField(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()) : Ui::InputField(parent, st, std::move(placeholderFactory), val) { connect(this, &Ui::InputField::changed, [this] { fix(); }); } diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index 9d9ab003e..fac3d96dc 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -31,10 +31,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "styles/style_boxes.h" ConnectionBox::ConnectionBox(QWidget *parent) -: _hostInput(this, st::connectionHostInputField, lang(lng_connection_host_ph), Global::ConnectionProxy().host) -, _portInput(this, st::connectionPortInputField, lang(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port)) -, _userInput(this, st::connectionUserInputField, lang(lng_connection_user_ph), Global::ConnectionProxy().user) -, _passwordInput(this, st::connectionPasswordInputField, lang(lng_connection_password_ph), Global::ConnectionProxy().password) +: _hostInput(this, st::connectionHostInputField, langFactory(lng_connection_host_ph), Global::ConnectionProxy().host) +, _portInput(this, st::connectionPortInputField, langFactory(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port)) +, _userInput(this, st::connectionUserInputField, langFactory(lng_connection_user_ph), Global::ConnectionProxy().user) +, _passwordInput(this, st::connectionPasswordInputField, langFactory(lng_connection_password_ph), Global::ConnectionProxy().password) , _typeGroup(std::make_shared>(Global::ConnectionType())) , _autoRadio(this, _typeGroup, dbictAuto, lang(lng_connection_auto_rb), st::defaultBoxCheckbox) , _httpProxyRadio(this, _typeGroup, dbictHttpProxy, lang(lng_connection_http_proxy_rb), st::defaultBoxCheckbox) @@ -43,10 +43,10 @@ ConnectionBox::ConnectionBox(QWidget *parent) } void ConnectionBox::prepare() { - setTitle(lang(lng_connection_header)); + setTitle(langFactory(lng_connection_header)); - addButton(lang(lng_connection_save), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_connection_save), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); _typeGroup->setChangedCallback([this](DBIConnectionType value) { typeChanged(value); }); @@ -215,8 +215,8 @@ AutoDownloadBox::AutoDownloadBox(QWidget *parent) } void AutoDownloadBox::prepare() { - addButton(lang(lng_connection_save), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_connection_save), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); setDimensions(st::boxWidth, 3 * _sectionHeight - st::autoDownloadTopDelta + st::setLittleSkip + _gifPlay->heightNoMargins() + st::setLittleSkip); } diff --git a/Telegram/SourceFiles/boxes/contacts_box.cpp b/Telegram/SourceFiles/boxes/contacts_box.cpp index 7d0831523..e415ad866 100644 --- a/Telegram/SourceFiles/boxes/contacts_box.cpp +++ b/Telegram/SourceFiles/boxes/contacts_box.cpp @@ -113,24 +113,24 @@ void ContactsBox::prepare() { updateTitle(); if (_chat) { if (_membersFilter == MembersFilter::Admins) { - addButton(lang(lng_settings_save), [this] { saveChatAdmins(); }); + addButton(langFactory(lng_settings_save), [this] { saveChatAdmins(); }); } else { - addButton(lang(lng_participant_invite), [this] { inviteParticipants(); }); + addButton(langFactory(lng_participant_invite), [this] { inviteParticipants(); }); } - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } else if (_channel) { if (_membersFilter != MembersFilter::Admins) { - addButton(lang(lng_participant_invite), [this] { inviteParticipants(); }); + addButton(langFactory(lng_participant_invite), [this] { inviteParticipants(); }); } - addButton(lang((_creating == CreatingGroupChannel) ? lng_create_group_skip : lng_cancel), [this] { closeBox(); }); + addButton(langFactory((_creating == CreatingGroupChannel) ? lng_create_group_skip : lng_cancel), [this] { closeBox(); }); } else if (_bot) { - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); } else if (_creating == CreatingGroupGroup) { - addButton(lang(lng_create_group_create), [this] { createGroup(); }); - addButton(lang(lng_create_group_back), [this] { closeBox(); }); + addButton(langFactory(lng_create_group_create), [this] { createGroup(); }); + addButton(langFactory(lng_create_group_back), [this] { closeBox(); }); } else { - addButton(lang(lng_close), [this] { closeBox(); }); - addLeftButton(lang(lng_profile_add_contact), [] { App::wnd()->onShowAddContact(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); + addLeftButton(langFactory(lng_profile_add_contact), [] { App::wnd()->onShowAddContact(); }); } _inner->setPeerSelectedChangedCallback([this](PeerData *peer, bool checked) { @@ -199,19 +199,18 @@ bool ContactsBox::onSearchByUsername(bool searchCache) { void ContactsBox::updateTitle() { if (_chat && _membersFilter == MembersFilter::Admins) { - setTitle(lang(lng_channel_admins)); + setTitle(langFactory(lng_channel_admins)); } else if (_chat || _creating != CreatingGroupNone) { auto addingAdmin = _channel && (_membersFilter == MembersFilter::Admins); - auto title = lang(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant); auto additional = (addingAdmin || (_inner->channel() && !_inner->channel()->isMegagroup())) ? QString() : QString("%1 / %2").arg(_inner->selectedCount()).arg(Global::MegagroupSizeMax()); - setTitle(title); - setAdditionalTitle(additional); + setTitle(langFactory(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant)); + setAdditionalTitle([additional] { return additional; }); } else if (_inner->sharingBotGame()) { - setTitle(lang(lng_bot_choose_chat)); + setTitle(langFactory(lng_bot_choose_chat)); } else if (_inner->bot()) { - setTitle(lang(lng_bot_choose_group)); + setTitle(langFactory(lng_bot_choose_group)); } else { - setTitle(lang(lng_contacts_header)); + setTitle(langFactory(lng_contacts_header)); } } @@ -287,7 +286,7 @@ void ContactsBox::keyPressEvent(QKeyEvent *e) { } object_ptr> ContactsBox::createMultiSelect() { - auto entity = object_ptr(this, st::contactsMultiSelect, lang(lng_participant_filter)); + auto entity = object_ptr(this, st::contactsMultiSelect, langFactory(lng_participant_filter)); auto margins = style::margins(0, 0, 0, 0); auto callback = [this] { updateScrollSkips(); }; return object_ptr>(this, std::move(entity), margins, std::move(callback)); diff --git a/Telegram/SourceFiles/boxes/download_path_box.cpp b/Telegram/SourceFiles/boxes/download_path_box.cpp index a89a9e1e2..dbb9913e1 100644 --- a/Telegram/SourceFiles/boxes/download_path_box.cpp +++ b/Telegram/SourceFiles/boxes/download_path_box.cpp @@ -39,10 +39,10 @@ DownloadPathBox::DownloadPathBox(QWidget *parent) } void DownloadPathBox::prepare() { - addButton(lang(lng_connection_save), [this] { save(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_connection_save), [this] { save(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); - setTitle(lang(lng_download_path_header)); + setTitle(langFactory(lng_download_path_header)); _group->setChangedCallback([this](Directory value) { radioChanged(value); }); diff --git a/Telegram/SourceFiles/boxes/edit_color_box.cpp b/Telegram/SourceFiles/boxes/edit_color_box.cpp index 3c3420216..9abaf2a47 100644 --- a/Telegram/SourceFiles/boxes/edit_color_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_color_box.cpp @@ -643,7 +643,7 @@ EditColorBox::EditColorBox(QWidget*, const QString &title, QColor current) : Box } void EditColorBox::prepare() { - setTitle(_title); + setTitle([this] { return _title; }); connect(_hueField, SIGNAL(changed()), this, SLOT(onFieldChanged())); connect(_saturationField, SIGNAL(changed()), this, SLOT(onFieldChanged())); @@ -661,8 +661,8 @@ void EditColorBox::prepare() { connect(_blueField, SIGNAL(submitted(bool)), this, SLOT(onFieldSubmitted())); connect(_result, SIGNAL(submitted(bool)), this, SLOT(onFieldSubmitted())); - addButton(lang(lng_settings_save), [this] { saveColor(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { saveColor(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); auto height = st::colorEditSkip + st::colorPickerSize + st::colorEditSkip + st::colorSliderWidth + st::colorEditSkip; setDimensions(st::colorEditWidth, height); diff --git a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp index 14c7f15b3..b940bd4f9 100644 --- a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp @@ -33,7 +33,7 @@ namespace { class PrivacyExceptionsBoxController : public ChatsListBoxController { public: - PrivacyExceptionsBoxController(const QString &title, const QVector &selected, base::lambda_once &&result)> saveCallback); + PrivacyExceptionsBoxController(base::lambda titleFactory, const QVector &selected, base::lambda_once &&result)> saveCallback); void rowClicked(PeerListBox::Row *row) override; protected: @@ -41,21 +41,21 @@ protected: std::unique_ptr createRow(History *history) override; private: - QString _title; + base::lambda _titleFactory; QVector _selected; base::lambda_once &&result)> _saveCallback; }; -PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(const QString &title, const QVector &selected, base::lambda_once &&result)> saveCallback) -: _title(title) +PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(base::lambda titleFactory, const QVector &selected, base::lambda_once &&result)> saveCallback) +: _titleFactory(std::move(titleFactory)) , _selected(selected) , _saveCallback(std::move(saveCallback)) { } void PrivacyExceptionsBoxController::prepareViewHook() { - view()->setTitle(_title); - view()->addButton(lang(lng_settings_save), [this] { + view()->setTitle(_titleFactory); + view()->addButton(langFactory(lng_settings_save), [this] { auto peers = view()->collectSelectedRows(); auto users = QVector(); if (!peers.empty()) { @@ -69,7 +69,7 @@ void PrivacyExceptionsBoxController::prepareViewHook() { _saveCallback(std::move(users)); view()->closeBox(); }); - view()->addButton(lang(lng_cancel), [this] { view()->closeBox(); }); + view()->addButton(langFactory(lng_cancel), [this] { view()->closeBox(); }); view()->addSelectedRows(_selected); } @@ -96,8 +96,8 @@ EditPrivacyBox::EditPrivacyBox(QWidget*, std::unique_ptr controller) void EditPrivacyBox::prepare() { _controller->setView(this); - setTitle(_controller->title()); - addButton(lang(lng_cancel), [this] { closeBox(); }); + setTitle([this] { return _controller->title(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); loadData(); @@ -174,7 +174,9 @@ int EditPrivacyBox::countDefaultHeight(int newWidth) { } void EditPrivacyBox::editExceptionUsers(Exception exception) { - auto controller = std::make_unique(_controller->exceptionBoxTitle(exception), exceptionUsers(exception), base::lambda_guarded(this, [this, exception](QVector &&users) { + auto controller = std::make_unique(base::lambda_guarded(this, [this, exception] { + return _controller->exceptionBoxTitle(exception); + }), exceptionUsers(exception), base::lambda_guarded(this, [this, exception](QVector &&users) { exceptionUsers(exception) = std::move(users); exceptionLink(exception)->entity()->setText(exceptionLinkText(exception)); auto removeFrom = ([exception] { @@ -292,14 +294,14 @@ void EditPrivacyBox::createWidgets() { createLabel(_exceptionsDescription, _controller->exceptionsDescription(), st::editPrivacyLabel); clearButtons(); - addButton(lang(lng_settings_save), [this] { + addButton(langFactory(lng_settings_save), [this] { auto someAreDisallowed = (_option != Option::Everyone) || !_neverUsers.empty(); _controller->confirmSave(someAreDisallowed, base::lambda_guarded(this, [this] { App::api()->savePrivacy(_controller->key(), collectResult()); closeBox(); })); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); _optionGroup->setChangedCallback([this](Option value) { _option = value; diff --git a/Telegram/SourceFiles/boxes/emoji_box.cpp b/Telegram/SourceFiles/boxes/emoji_box.cpp index 19b7140c6..af83b50a3 100644 --- a/Telegram/SourceFiles/boxes/emoji_box.cpp +++ b/Telegram/SourceFiles/boxes/emoji_box.cpp @@ -79,10 +79,10 @@ EmojiBox::EmojiBox(QWidget*) : _esize(Ui::Emoji::Size(Ui::Emoji::Index() + 1)) { } void EmojiBox::prepare() { - setTitle(lang(lng_settings_emoji_list)); + setTitle(langFactory(lng_settings_emoji_list)); fillBlocks(); - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); _blockHeight = st::emojiReplaceInnerHeight; diff --git a/Telegram/SourceFiles/boxes/language_box.cpp b/Telegram/SourceFiles/boxes/language_box.cpp index ffc30af9e..9ade20a39 100644 --- a/Telegram/SourceFiles/boxes/language_box.cpp +++ b/Telegram/SourceFiles/boxes/language_box.cpp @@ -125,9 +125,9 @@ void LanguageBox::prepare() { void LanguageBox::refreshLang() { clearButtons(); - addButton(lang(lng_box_ok), [this] { closeBox(); }); + addButton(langFactory(lng_box_ok), [this] { closeBox(); }); - setTitle(lang(lng_languages)); + setTitle(langFactory(lng_languages)); update(); } diff --git a/Telegram/SourceFiles/boxes/local_storage_box.cpp b/Telegram/SourceFiles/boxes/local_storage_box.cpp index 4329acb07..f791c9a24 100644 --- a/Telegram/SourceFiles/boxes/local_storage_box.cpp +++ b/Telegram/SourceFiles/boxes/local_storage_box.cpp @@ -32,9 +32,9 @@ LocalStorageBox::LocalStorageBox(QWidget *parent) } void LocalStorageBox::prepare() { - setTitle(lang(lng_local_storage_title)); + setTitle(langFactory(lng_local_storage_title)); - addButton(lang(lng_box_ok), [this] { closeBox(); }); + addButton(langFactory(lng_box_ok), [this] { closeBox(); }); _clear->setClickedCallback([this] { clearStorage(); }); diff --git a/Telegram/SourceFiles/boxes/members_box.cpp b/Telegram/SourceFiles/boxes/members_box.cpp index 30971617d..02fdada32 100644 --- a/Telegram/SourceFiles/boxes/members_box.cpp +++ b/Telegram/SourceFiles/boxes/members_box.cpp @@ -74,14 +74,14 @@ MembersBox::MembersBox(QWidget*, ChannelData *channel, MembersFilter filter) } void MembersBox::prepare() { - setTitle(lang(_filter == MembersFilter::Recent ? lng_channel_members : lng_channel_admins)); + setTitle(langFactory((_filter == MembersFilter::Recent) ? lng_channel_members : lng_channel_admins)); _inner = setInnerWidget(object_ptr(this, _channel, _filter), st::boxLayerScroll); setDimensions(st::boxWideWidth, st::boxMaxListHeight); - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); if (_channel->amCreator() && (_channel->membersCount() < (_channel->isMegagroup() ? Global::MegagroupSizeMax() : Global::ChatSizeMax()) || (!_channel->isMegagroup() && !_channel->isPublic()) || _filter == MembersFilter::Admins)) { - addLeftButton(lang((_filter == MembersFilter::Admins) ? lng_channel_add_admin : lng_channel_add_members), [this] { onAdd(); }); + addLeftButton(langFactory((_filter == MembersFilter::Admins) ? lng_channel_add_admin : lng_channel_add_members), [this] { onAdd(); }); } connect(_inner, SIGNAL(mustScrollTo(int, int)), this, SLOT(onScrollToY(int, int))); diff --git a/Telegram/SourceFiles/boxes/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp index 644e5807b..f652bad2d 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.cpp +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -119,7 +119,7 @@ NotificationsBox::NotificationsBox(QWidget *parent) } void NotificationsBox::prepare() { - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); _sampleOpacities.reserve(kMaxNotificationsCount); for (int i = 0; i != kMaxNotificationsCount; ++i) { diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index ea0e0474d..938897fc0 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -31,11 +31,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org PasscodeBox::PasscodeBox(QWidget*, bool turningOff) : _turningOff(turningOff) , _about(st::boxWidth - st::boxPadding.left() * 1.5) -, _oldPasscode(this, st::defaultInputField, lang(lng_passcode_enter_old)) -, _newPasscode(this, st::defaultInputField, lang(Global::LocalPasscode() ? lng_passcode_enter_new : lng_passcode_enter_first)) -, _reenterPasscode(this, st::defaultInputField, lang(lng_passcode_confirm_new)) -, _passwordHint(this, st::defaultInputField, lang(lng_cloud_password_hint)) -, _recoverEmail(this, st::defaultInputField, lang(lng_cloud_password_email)) +, _oldPasscode(this, st::defaultInputField, langFactory(lng_passcode_enter_old)) +, _newPasscode(this, st::defaultInputField, langFactory(Global::LocalPasscode() ? lng_passcode_enter_new : lng_passcode_enter_first)) +, _reenterPasscode(this, st::defaultInputField, langFactory(lng_passcode_confirm_new)) +, _passwordHint(this, st::defaultInputField, langFactory(lng_cloud_password_hint)) +, _recoverEmail(this, st::defaultInputField, langFactory(lng_cloud_password_email)) , _recover(this, lang(lng_signin_recover)) { } @@ -46,34 +46,34 @@ PasscodeBox::PasscodeBox(QWidget*, const QByteArray &newSalt, const QByteArray & , _curSalt(curSalt) , _hasRecovery(hasRecovery) , _about(st::boxWidth - st::boxPadding.left() * 1.5) -, _oldPasscode(this, st::defaultInputField, lang(lng_cloud_password_enter_old)) -, _newPasscode(this, st::defaultInputField, lang(curSalt.isEmpty() ? lng_cloud_password_enter_first : lng_cloud_password_enter_new)) -, _reenterPasscode(this, st::defaultInputField, lang(lng_cloud_password_confirm_new)) -, _passwordHint(this, st::defaultInputField, lang(curSalt.isEmpty() ? lng_cloud_password_hint : lng_cloud_password_change_hint)) -, _recoverEmail(this, st::defaultInputField, lang(lng_cloud_password_email)) +, _oldPasscode(this, st::defaultInputField, langFactory(lng_cloud_password_enter_old)) +, _newPasscode(this, st::defaultInputField, langFactory(curSalt.isEmpty() ? lng_cloud_password_enter_first : lng_cloud_password_enter_new)) +, _reenterPasscode(this, st::defaultInputField, langFactory(lng_cloud_password_confirm_new)) +, _passwordHint(this, st::defaultInputField, langFactory(curSalt.isEmpty() ? lng_cloud_password_hint : lng_cloud_password_change_hint)) +, _recoverEmail(this, st::defaultInputField, langFactory(lng_cloud_password_email)) , _recover(this, lang(lng_signin_recover)) { if (!hint.isEmpty()) _hintText.setText(st::passcodeTextStyle, lng_signin_hint(lt_password_hint, hint)); } void PasscodeBox::prepare() { - addButton(lang(_turningOff ? lng_passcode_remove_button : lng_settings_save), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(_turningOff ? lng_passcode_remove_button : lng_settings_save), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); _about.setRichText(st::passcodeTextStyle, lang(_cloudPwd ? lng_cloud_password_about : lng_passcode_about)); _aboutHeight = _about.countHeight(st::boxWidth - st::boxPadding.left() * 1.5); if (_turningOff) { _oldPasscode->show(); - setTitle(lang(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove)); + setTitle(langFactory(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove)); setDimensions(st::boxWidth, st::passcodePadding.top() + _oldPasscode->height() + st::passcodeTextLine + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0) + st::passcodeAboutSkip + _aboutHeight + st::passcodePadding.bottom()); } else { auto has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode(); if (has) { _oldPasscode->show(); - setTitle(lang(_cloudPwd ? lng_cloud_password_change : lng_passcode_change)); + setTitle(langFactory(_cloudPwd ? lng_cloud_password_change : lng_passcode_change)); setDimensions(st::boxWidth, st::passcodePadding.top() + _oldPasscode->height() + st::passcodeTextLine + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeTextLine : 0) + _newPasscode->height() + st::passcodeLittleSkip + _reenterPasscode->height() + st::passcodeSkip + (_cloudPwd ? _passwordHint->height() + st::passcodeLittleSkip : 0) + st::passcodeAboutSkip + _aboutHeight + st::passcodePadding.bottom()); } else { _oldPasscode->hide(); - setTitle(lang(_cloudPwd ? lng_cloud_password_create : lng_passcode_create)); + setTitle(langFactory(_cloudPwd ? lng_cloud_password_create : lng_passcode_create)); setDimensions(st::boxWidth, st::passcodePadding.top() + _newPasscode->height() + st::passcodeLittleSkip + _reenterPasscode->height() + st::passcodeSkip + (_cloudPwd ? _passwordHint->height() + st::passcodeLittleSkip : 0) + st::passcodeAboutSkip + _aboutHeight + (_cloudPwd ? (st::passcodeLittleSkip + _recoverEmail->height() + st::passcodeSkip) : st::passcodePadding.bottom())); } } @@ -421,14 +421,14 @@ bool PasscodeBox::recoverStartFail(const RPCError &error) { RecoverBox::RecoverBox(QWidget*, const QString &pattern) : _pattern(st::normalFont->elided(lng_signin_recover_hint(lt_recover_email, pattern), st::boxWidth - st::boxPadding.left() * 1.5)) -, _recoverCode(this, st::defaultInputField, lang(lng_signin_code)) { +, _recoverCode(this, st::defaultInputField, langFactory(lng_signin_code)) { } void RecoverBox::prepare() { - setTitle(lang(lng_signin_recover_title)); + setTitle(langFactory(lng_signin_recover_title)); - addButton(lang(lng_passcode_submit), [this] { onSubmit(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_passcode_submit), [this] { onSubmit(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); setDimensions(st::boxWidth, st::passcodePadding.top() + st::passcodePadding.bottom() + st::passcodeTextLine + _recoverCode->height() + st::passcodeTextLine); diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index 9bc370bb6..4c772e845 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -42,7 +42,7 @@ PeerListBox::PeerListBox(QWidget*, std::unique_ptr controller) } object_ptr> PeerListBox::createMultiSelect() { - auto entity = object_ptr(this, st::contactsMultiSelect, lang(lng_participant_filter)); + auto entity = object_ptr(this, st::contactsMultiSelect, langFactory(lng_participant_filter)); auto margins = style::margins(0, 0, 0, 0); auto callback = [this] { updateScrollSkips(); }; return object_ptr>(this, std::move(entity), margins, std::move(callback)); diff --git a/Telegram/SourceFiles/boxes/photo_crop_box.cpp b/Telegram/SourceFiles/boxes/photo_crop_box.cpp index 7792b8dfb..5664d491b 100644 --- a/Telegram/SourceFiles/boxes/photo_crop_box.cpp +++ b/Telegram/SourceFiles/boxes/photo_crop_box.cpp @@ -50,8 +50,8 @@ void PhotoCropBox::init(const QImage &img, PeerData *peer) { } void PhotoCropBox::prepare() { - addButton(lang(lng_settings_save), [this] { sendPhoto(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { sendPhoto(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); if (peerToBareInt(_peerId)) { connect(this, SIGNAL(ready(const QImage&)), this, SLOT(onReady(const QImage&))); } diff --git a/Telegram/SourceFiles/boxes/rate_call_box.cpp b/Telegram/SourceFiles/boxes/rate_call_box.cpp index 23b62bca3..f562b4d7b 100644 --- a/Telegram/SourceFiles/boxes/rate_call_box.cpp +++ b/Telegram/SourceFiles/boxes/rate_call_box.cpp @@ -42,10 +42,8 @@ RateCallBox::RateCallBox(QWidget*, uint64 callId, uint64 callAccessHash) } void RateCallBox::prepare() { - auto titleWidth = st::boxWideWidth - 2 * st::boxTitlePosition.x(); - auto titleText = st::boxTitleFont->elided(lang(lng_call_rate_label), titleWidth); - setTitle(titleText); - addButton(lang(lng_cancel), [this] { closeBox(); }); + setTitle(langFactory(lng_call_rate_label)); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); for (auto i = 0; i < kMaxRating; ++i) { _stars.push_back(object_ptr(this, st::callRatingStar)); @@ -75,8 +73,8 @@ void RateCallBox::ratingChanged(int value) { Expects(value > 0 && value <= kMaxRating); if (!_rating) { clearButtons(); - addButton(lang(lng_send_button), [this] { onSend(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_send_button), [this] { onSend(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } _rating = value; @@ -86,7 +84,7 @@ void RateCallBox::ratingChanged(int value) { } if (value < kMaxRating) { if (!_comment) { - _comment.create(this, st::callRatingComment, lang(lng_call_rate_comment)); + _comment.create(this, st::callRatingComment, langFactory(lng_call_rate_comment)); _comment->show(); _comment->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); _comment->setMaxLength(MaxPhotoCaption); diff --git a/Telegram/SourceFiles/boxes/report_box.cpp b/Telegram/SourceFiles/boxes/report_box.cpp index bf791713a..b15cbd05d 100644 --- a/Telegram/SourceFiles/boxes/report_box.cpp +++ b/Telegram/SourceFiles/boxes/report_box.cpp @@ -38,10 +38,10 @@ ReportBox::ReportBox(QWidget*, PeerData *peer) : _peer(peer) } void ReportBox::prepare() { - setTitle(lang(_peer->isUser() ? lng_report_bot_title : (_peer->isMegagroup() ? lng_report_group_title : lng_report_title))); + setTitle(langFactory(_peer->isUser() ? lng_report_bot_title : (_peer->isMegagroup() ? lng_report_group_title : lng_report_title))); - addButton(lang(lng_report_button), [this] { onReport(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_report_button), [this] { onReport(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); _reasonGroup->setChangedCallback([this](Reason value) { reasonChanged(value); }); @@ -64,7 +64,7 @@ void ReportBox::resizeEvent(QResizeEvent *e) { void ReportBox::reasonChanged(Reason reason) { if (reason == Reason::Other) { if (!_reasonOtherText) { - _reasonOtherText.create(this, st::profileReportReasonOther, lang(lng_report_reason_description)); + _reasonOtherText.create(this, st::profileReportReasonOther, langFactory(lng_report_reason_description)); _reasonOtherText->show(); _reasonOtherText->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); _reasonOtherText->setMaxLength(MaxPhotoCaption); diff --git a/Telegram/SourceFiles/boxes/self_destruction_box.cpp b/Telegram/SourceFiles/boxes/self_destruction_box.cpp index a40dda47e..afc0d9d3c 100644 --- a/Telegram/SourceFiles/boxes/self_destruction_box.cpp +++ b/Telegram/SourceFiles/boxes/self_destruction_box.cpp @@ -26,7 +26,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "styles/style_boxes.h" void SelfDestructionBox::prepare() { - setTitle(lang(lng_self_destruct_title)); + setTitle(langFactory(lng_self_destruct_title)); _ttlValues = { 30, 90, 180, 365 }; @@ -42,7 +42,7 @@ void SelfDestructionBox::prepare() { auto loading = object_ptr(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout); loading->moveToLeft((st::boxWidth - loading->width()) / 2, boxHeight / 3); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); request(MTPaccount_GetAccountTTL()).done([this, loading = std::move(loading)](const MTPAccountDaysTTL &result) mutable { Expects(result.type() == mtpc_accountDaysTTL); @@ -72,10 +72,10 @@ void SelfDestructionBox::prepare() { showChildren(); clearButtons(); - addButton(lang(lng_settings_save), [this, group] { + addButton(langFactory(lng_settings_save), [this, group] { MTP::send(MTPaccount_SetAccountTTL(MTP_accountDaysTTL(MTP_int(group->value())))); closeBox(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); }).send(); } diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 4faf3f890..e8321c12f 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -46,7 +46,7 @@ bool ValidatePhotoDimensions(int width, int height) { SendFilesBox::SendFilesBox(QWidget*, QImage image, CompressConfirm compressed) : _image(image) , _compressConfirm(compressed) -, _caption(this, st::confirmCaptionArea, lang(lng_photo_caption)) { +, _caption(this, st::confirmCaptionArea, langFactory(lng_photo_caption)) { _files.push_back(QString()); prepareSingleFileLayout(); } @@ -54,7 +54,7 @@ SendFilesBox::SendFilesBox(QWidget*, QImage image, CompressConfirm compressed) SendFilesBox::SendFilesBox(QWidget*, const QStringList &files, CompressConfirm compressed) : _files(files) , _compressConfirm(compressed) -, _caption(this, st::confirmCaptionArea, lang(_files.size() > 1 ? lng_photos_comment : lng_photo_caption)) { +, _caption(this, st::confirmCaptionArea, langFactory(_files.size() > 1 ? lng_photos_comment : lng_photo_caption)) { if (_files.size() == 1) { prepareSingleFileLayout(); } @@ -237,8 +237,8 @@ void SendFilesBox::prepare() { updateTitleText(); } - _send = addButton(lang(lng_send_button), [this] { onSend(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + _send = addButton(langFactory(lng_send_button), [this] { onSend(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); if (_compressConfirm != CompressConfirm::None) { auto compressed = (_compressConfirm == CompressConfirm::Auto) ? cCompressPastedImage() : (_compressConfirm == CompressConfirm::Yes); @@ -258,13 +258,13 @@ void SendFilesBox::prepare() { updateBoxSize(); } -QString SendFilesBox::getSendButtonText() const { +base::lambda SendFilesBox::getSendButtonText() const { if (!_contactPhone.isEmpty()) { - return lang(lng_send_button); + return langFactory(lng_send_button); } else if (_compressed && _compressed->checked()) { - return lng_send_photos(lt_count, _files.size()); + return [count = _files.size()] { return lng_send_photos(lt_count, count); }; } - return lng_send_files(lt_count, _files.size()); + return [count = _files.size()] { return lng_send_files(lt_count, count); }; } void SendFilesBox::onCompressedChange() { @@ -564,7 +564,7 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : } t_assert(_animated || _photo || _doc); - _field.create(this, st::confirmCaptionArea, lang(lng_photo_caption), caption); + _field.create(this, st::confirmCaptionArea, langFactory(lng_photo_caption), caption); _field->setMaxLength(MaxPhotoCaption); _field->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); } @@ -607,8 +607,8 @@ void EditCaptionBox::clipCallback(Media::Clip::Notification notification) { } void EditCaptionBox::prepare() { - addButton(lang(lng_settings_save), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); updateBoxSize(); connect(_field, SIGNAL(submitted(bool)), this, SLOT(onSave(bool))); diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index dff070727..c5d7ab107 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -72,7 +72,7 @@ private: void updateTitleText(); void updateBoxSize(); void updateControlsGeometry(); - QString getSendButtonText() const; + base::lambda getSendButtonText() const; QString _titleText; QStringList _files; diff --git a/Telegram/SourceFiles/boxes/sessions_box.cpp b/Telegram/SourceFiles/boxes/sessions_box.cpp index e4806b196..8872ff417 100644 --- a/Telegram/SourceFiles/boxes/sessions_box.cpp +++ b/Telegram/SourceFiles/boxes/sessions_box.cpp @@ -35,9 +35,9 @@ SessionsBox::SessionsBox(QWidget*) } void SessionsBox::prepare() { - setTitle(lang(lng_sessions_other_header)); + setTitle(langFactory(lng_sessions_other_header)); - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); setDimensions(st::boxWideWidth, st::sessionsHeight); diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index 4f4e9b105..6dbf75d99 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -45,7 +45,7 @@ ShareBox::ShareBox(QWidget*, CopyCallback &©Callback, SubmitCallback &&submi : _copyCallback(std::move(copyCallback)) , _submitCallback(std::move(submitCallback)) , _filterCallback(std::move(filterCallback)) -, _select(this, st::contactsMultiSelect, lang(lng_participant_filter)) +, _select(this, st::contactsMultiSelect, langFactory(lng_participant_filter)) , _searchTimer(this) { } @@ -53,7 +53,7 @@ void ShareBox::prepare() { _select->resizeToWidth(st::boxWideWidth); myEnsureResized(_select); - setTitle(lang(lng_share_title)); + setTitle(langFactory(lng_share_title)); _inner = setInnerWidget(object_ptr(this, std::move(_filterCallback)), getTopScrollSkip()); connect(_inner, SIGNAL(mustScrollTo(int,int)), this, SLOT(onMustScrollTo(int,int))); @@ -207,11 +207,11 @@ void ShareBox::updateButtons() { void ShareBox::createButtons() { clearButtons(); if (_hasSelected) { - addButton(lang(lng_share_confirm), [this] { onSubmit(); }); + addButton(langFactory(lng_share_confirm), [this] { onSubmit(); }); } else { - addButton(lang(lng_share_copy_link), [this] { onCopyLink(); }); + addButton(langFactory(lng_share_copy_link), [this] { onCopyLink(); }); } - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } void ShareBox::onFilterUpdate(const QString &query) { diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 54b42e5f9..c16ef37e9 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -46,7 +46,7 @@ StickerSetBox::StickerSetBox(QWidget*, const MTPInputStickerSet &set) } void StickerSetBox::prepare() { - setTitle(lang(lng_contacts_loading)); + setTitle(langFactory(lng_contacts_loading)); _inner = setInnerWidget(object_ptr(this, _set), st::stickersScroll); connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated())); @@ -89,16 +89,16 @@ void StickerSetBox::updateButtons() { clearButtons(); if (_inner->loaded()) { if (_inner->notInstalled()) { - addButton(lang(lng_stickers_add_pack), [this] { onAddStickers(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_stickers_add_pack), [this] { onAddStickers(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } else if (_inner->official()) { - addButton(lang(lng_about_done), [this] { closeBox(); }); + addButton(langFactory(lng_about_done), [this] { closeBox(); }); } else { - addButton(lang(lng_stickers_share_pack), [this] { onShareStickers(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_stickers_share_pack), [this] { onShareStickers(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } } else { - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); } update(); } @@ -427,19 +427,19 @@ bool StickerSetBox::Inner::official() const { return _loaded && _setShortName.isEmpty(); } -TextWithEntities StickerSetBox::Inner::title() const { +base::lambda StickerSetBox::Inner::title() const { auto text = _setTitle; auto entities = EntitiesInText(); if (_loaded) { if (_pack.isEmpty()) { - text = lang(lng_attach_failed); + return [] { return TextWithEntities { lang(lng_attach_failed), EntitiesInText() }; }; } else { textParseEntities(text, TextParseMentions, &entities); } } else { - text = lang(lng_contacts_loading); + return [] { return TextWithEntities { lang(lng_contacts_loading), EntitiesInText() }; }; } - return { text, entities }; + return [text, entities] { return TextWithEntities { text, entities }; }; } QString StickerSetBox::Inner::shortName() const { diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.h b/Telegram/SourceFiles/boxes/sticker_set_box.h index 77a982a87..b9412584c 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.h +++ b/Telegram/SourceFiles/boxes/sticker_set_box.h @@ -71,7 +71,7 @@ public: bool loaded() const; int32 notInstalled() const; bool official() const; - TextWithEntities title() const; + base::lambda title() const; QString shortName() const; void setVisibleTopBottom(int visibleTop, int visibleBottom) override; diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 4e71e0b76..fb64dc937 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -230,7 +230,7 @@ void StickersBox::prepare() { } else if (_section == Section::Archived) { requestArchivedSets(); } else if (_section == Section::ArchivedPart) { - setTitle(lang(lng_stickers_archived)); + setTitle(langFactory(lng_stickers_archived)); } if (Global::ArchivedStickerSetsOrder().isEmpty()) { preloadArchivedSets(); @@ -252,7 +252,7 @@ void StickersBox::prepare() { _archived.widget()->setInstallSetCallback([this](uint64 setId) { installSet(setId); }); _archived.widget()->setLoadMoreCallback([this] { loadMoreArchived(); }); - addButton(lang(lng_about_done), [this] { closeBox(); }); + addButton(langFactory(lng_about_done), [this] { closeBox(); }); if (_section == Section::Installed) { _tab = &_installed; diff --git a/Telegram/SourceFiles/boxes/username_box.cpp b/Telegram/SourceFiles/boxes/username_box.cpp index d1f0f30bf..cd3890d02 100644 --- a/Telegram/SourceFiles/boxes/username_box.cpp +++ b/Telegram/SourceFiles/boxes/username_box.cpp @@ -31,7 +31,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "messenger.h" UsernameBox::UsernameBox(QWidget*) -: _username(this, st::defaultInputField, qsl("@username"), App::self()->username, false) +: _username(this, st::defaultInputField, [] { return qsl("@username"); }, App::self()->username, false) , _link(this, QString(), st::boxLinkButton) , _about(st::boxWidth - st::usernamePadding.left()) , _checkTimer(this) { @@ -40,10 +40,10 @@ UsernameBox::UsernameBox(QWidget*) void UsernameBox::prepare() { _goodText = App::self()->username.isEmpty() ? QString() : lang(lng_username_available); - setTitle(lang(lng_username_title)); + setTitle(langFactory(lng_username_title)); - addButton(lang(lng_settings_save), [this] { onSave(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_settings_save), [this] { onSave(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); connect(_username, SIGNAL(changed()), this, SLOT(onChanged())); connect(_username, SIGNAL(submitted(bool)), this, SLOT(onSave())); diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index c2e7d96d4..6bd0ccc55 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -202,8 +202,8 @@ void BoxController::prepare() { } }); - view()->setTitle(lang(lng_call_box_title)); - view()->addButton(lang(lng_close), [this] { view()->closeBox(); }); + view()->setTitle(langFactory(lng_call_box_title)); + view()->addButton(langFactory(lng_close), [this] { view()->closeBox(); }); view()->setAboutText(lang(lng_contacts_loading)); view()->refreshRows(); diff --git a/Telegram/SourceFiles/calls/calls_top_bar.cpp b/Telegram/SourceFiles/calls/calls_top_bar.cpp index f23aea0db..416698820 100644 --- a/Telegram/SourceFiles/calls/calls_top_bar.cpp +++ b/Telegram/SourceFiles/calls/calls_top_bar.cpp @@ -56,8 +56,9 @@ DebugInfoBox::DebugInfoBox(QWidget*, base::weak_unique_ptr call) : _call(c } void DebugInfoBox::prepare() { - setTitle("Call Debug"); - addButton(lang(lng_close), [this] { closeBox(); }); + setTitle([] { return QString("Call Debug"); }); + + addButton(langFactory(lng_close), [this] { closeBox(); }); _text = setInnerWidget(object_ptr(this, st::callDebugLabel)); _text->setSelectable(true); updateText(); diff --git a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp index 6f3410b5f..8d180bf48 100644 --- a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp @@ -70,7 +70,7 @@ private: GifsListWidget::Footer::Footer(gsl::not_null parent) : InnerFooter(parent) , _pan(parent) -, _field(this, st::gifsSearchField, lang(lng_gifs_search)) +, _field(this, st::gifsSearchField, langFactory(lng_gifs_search)) , _cancel(this, st::gifsSearchCancel) { _field->resize(width() - st::gifsSearchFieldPosition.x() - st::gifsSearchCancelPosition.x() - st::gifsSearchCancel.width, _field->height()); _field->moveToLeft(st::gifsSearchFieldPosition.x(), st::gifsSearchFieldPosition.y()); diff --git a/Telegram/SourceFiles/chat_helpers/message_field.cpp b/Telegram/SourceFiles/chat_helpers/message_field.cpp index cce6d7d38..3d742e0c0 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.cpp +++ b/Telegram/SourceFiles/chat_helpers/message_field.cpp @@ -94,7 +94,7 @@ TextWithTags::Tags ConvertEntitiesToTextTags(const EntitiesInText &entities) { return result; } -MessageField::MessageField(QWidget *parent, gsl::not_null controller, const style::FlatTextarea &st, const QString &ph, const QString &val) : Ui::FlatTextarea(parent, st, ph, val) +MessageField::MessageField(QWidget *parent, gsl::not_null controller, const style::FlatTextarea &st, base::lambda placeholderFactory, const QString &val) : Ui::FlatTextarea(parent, st, std::move(placeholderFactory), val) , _controller(controller) { setMinHeight(st::historySendSize.height() - 2 * st::historySendPadding); setMaxHeight(st::historyComposeFieldMaxHeight); diff --git a/Telegram/SourceFiles/chat_helpers/message_field.h b/Telegram/SourceFiles/chat_helpers/message_field.h index bedb69141..5cd97c1e5 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.h +++ b/Telegram/SourceFiles/chat_helpers/message_field.h @@ -36,7 +36,7 @@ class MessageField final : public Ui::FlatTextarea { Q_OBJECT public: - MessageField(QWidget *parent, gsl::not_null controller, const style::FlatTextarea &st, const QString &ph = QString(), const QString &val = QString()); + MessageField(QWidget *parent, gsl::not_null controller, const style::FlatTextarea &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()); bool hasSendText() const; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 7fb6526f3..888f717d5 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -2267,7 +2267,7 @@ void DialogsWidget::UpdateButton::paintEvent(QPaintEvent *e) { DialogsWidget::DialogsWidget(QWidget *parent, gsl::not_null controller) : Window::AbstractSectionWidget(parent, controller) , _mainMenuToggle(this, st::dialogsMenuToggle) -, _filter(this, st::dialogsFilter, lang(lng_dlg_filter)) +, _filter(this, st::dialogsFilter, langFactory(lng_dlg_filter)) , _jumpToDate(this, object_ptr(this, st::dialogsCalendar)) , _cancelSearch(this, st::dialogsCancelSearch) , _lockUnlock(this, st::dialogsLock) diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index eb3d1db32..31322f3e0 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -169,41 +169,42 @@ void ReportSpamPanel::setReported(bool reported, PeerData *onPeer) { HistoryHider::HistoryHider(MainWidget *parent, bool forwardSelected) : TWidget(parent) , _forwardSelected(forwardSelected) -, _send(this, lang(lng_forward_send), st::defaultBoxButton) -, _cancel(this, lang(lng_cancel), st::defaultBoxButton) { +, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) +, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { init(); } HistoryHider::HistoryHider(MainWidget *parent, UserData *sharedContact) : TWidget(parent) , _sharedContact(sharedContact) -, _send(this, lang(lng_forward_send), st::defaultBoxButton) -, _cancel(this, lang(lng_cancel), st::defaultBoxButton) { +, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) +, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { init(); } HistoryHider::HistoryHider(MainWidget *parent) : TWidget(parent) , _sendPath(true) -, _send(this, lang(lng_forward_send), st::defaultBoxButton) -, _cancel(this, lang(lng_cancel), st::defaultBoxButton) { +, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) +, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { init(); } HistoryHider::HistoryHider(MainWidget *parent, const QString &botAndQuery) : TWidget(parent) , _botAndQuery(botAndQuery) -, _send(this, lang(lng_forward_send), st::defaultBoxButton) -, _cancel(this, lang(lng_cancel), st::defaultBoxButton) { +, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) +, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { init(); } HistoryHider::HistoryHider(MainWidget *parent, const QString &url, const QString &text) : TWidget(parent) , _shareUrl(url) , _shareText(text) -, _send(this, lang(lng_forward_send), st::defaultBoxButton) -, _cancel(this, lang(lng_cancel), st::defaultBoxButton) { +, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) +, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { init(); } void HistoryHider::init() { + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); connect(_send, SIGNAL(clicked()), this, SLOT(forward())); connect(_cancel, SIGNAL(clicked()), this, SLOT(startHide())); subscribe(Global::RefPeerChooseCancel(), [this] { startHide(); }); @@ -214,6 +215,10 @@ void HistoryHider::init() { _a_opacity.start([this] { update(); }, 0., 1., st::boxDuration); } +void HistoryHider::refreshLang() { + InvokeQueued(this, [this] { updateControlsGeometry(); }); +} + bool HistoryHider::withConfirm() const { return _sharedContact || _sendPath; } @@ -326,6 +331,10 @@ MainWidget *HistoryHider::parent() { } void HistoryHider::resizeEvent(QResizeEvent *e) { + updateControlsGeometry(); +} + +void HistoryHider::updateControlsGeometry() { auto w = st::boxWidth; auto h = st::boxPadding.top() + st::boxPadding.bottom(); if (_offered) { @@ -496,7 +505,7 @@ HistoryWidget::HistoryWidget(QWidget *parent, gsl::not_null , _botKeyboardHide(this, st::historyBotKeyboardHide) , _botCommandStart(this, st::historyBotCommandStart) , _silent(this) -, _field(this, controller, st::historyComposeField, lang(lng_message_ph)) +, _field(this, controller, st::historyComposeField, langFactory(lng_message_ph)) , _recordCancelWidth(st::historyRecordFont->width(lang(lng_record_cancel))) , _a_recording(animation(this, &HistoryWidget::step_recording)) , _kbScroll(this, st::botKbScroll) @@ -4213,12 +4222,13 @@ void HistoryWidget::onCheckFieldAutocomplete() { void HistoryWidget::updateFieldPlaceholder() { if (_editMsgId) { - _field->setPlaceholder(lang(lng_edit_message_text)); + _field->setPlaceholder(langFactory(lng_edit_message_text)); } else { if (_inlineBot && _inlineBot != Ui::LookingUpInlineBot) { - _field->setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2); + auto text = _inlineBot->botInfo->inlinePlaceholder.mid(1); + _field->setPlaceholder([text] { return text; }, _inlineBot->username.size() + 2); } else { - _field->setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_silent->checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_message_ph)); + _field->setPlaceholder(langFactory((_history && _history->isChannel() && !_history->isMegagroup()) ? (_silent->checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_message_ph)); } } updateSendButtonType(); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 606e51516..b751a9427 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -131,6 +131,8 @@ signals: void forwarded(); private: + void refreshLang(); + void updateControlsGeometry(); void animationCallback(); void init(); MainWidget *parent(); diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp index 3e7b83845..a45a75cda 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp @@ -382,12 +382,13 @@ void Inner::refreshSwitchPmButton(const CacheEntry *entry) { _switchPmStartToken.clear(); } else { if (!_switchPmButton) { - _switchPmButton.create(this, QString(), st::switchPmButton); + _switchPmButton.create(this, base::lambda(), st::switchPmButton); _switchPmButton->show(); _switchPmButton->setTextTransform(Ui::RoundButton::TextTransform::NoTransform); connect(_switchPmButton, SIGNAL(clicked()), this, SLOT(onSwitchPm())); } - _switchPmButton->setText(entry->switchPmText); // doesn't perform text.toUpper() + auto text = entry->switchPmText; + _switchPmButton->setText([text] { return text; }); // doesn't perform text.toUpper() _switchPmStartToken = entry->switchPmStartToken; auto buttonTop = st::stickerPanPadding; _switchPmButton->move(st::inlineResultsLeft - st::buttonRadius, buttonTop); diff --git a/Telegram/SourceFiles/intro/introcode.cpp b/Telegram/SourceFiles/intro/introcode.cpp index 4ebf58aca..42d411e2c 100644 --- a/Telegram/SourceFiles/intro/introcode.cpp +++ b/Telegram/SourceFiles/intro/introcode.cpp @@ -30,7 +30,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace Intro { -CodeInput::CodeInput(QWidget *parent, const style::InputField &st, const QString &ph) : Ui::MaskedInputField(parent, st, ph) { +CodeInput::CodeInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory) : Ui::MaskedInputField(parent, st, std::move(placeholderFactory)) { } void CodeInput::setDigitsCountMax(int digitsCount) { @@ -82,7 +82,7 @@ void CodeInput::correctValue(const QString &was, int wasCursor, QString &now, in CodeWidget::CodeWidget(QWidget *parent, Widget::Data *data) : Step(parent, data) , _noTelegramCode(this, lang(lng_code_no_telegram), st::introLink) -, _code(this, st::introCode, lang(lng_code_ph)) +, _code(this, st::introCode, langFactory(lng_code_ph)) , _callTimer(this) , _callStatus(getData()->callStatus) , _callTimeout(getData()->callTimeout) @@ -104,13 +104,12 @@ CodeWidget::CodeWidget(QWidget *parent, Widget::Data *data) : Step(parent, data) void CodeWidget::refreshLang() { if (_noTelegramCode) _noTelegramCode->setText(lang(lng_code_no_telegram)); - if (_code) _code->setPlaceholder(lang(lng_code_ph)); updateDescText(); updateControlsGeometry(); } void CodeWidget::updateDescText() { - setDescriptionText([byTelegram = getData()->codeByTelegram] { return lang(byTelegram ? lng_code_telegram : lng_code_desc); }); + setDescriptionText(langFactory(getData()->codeByTelegram ? lng_code_telegram : lng_code_desc)); if (getData()->codeByTelegram) { _noTelegramCode->show(); _callTimer->stop(); @@ -221,7 +220,7 @@ void CodeWidget::codeSubmitDone(const MTPauth_Authorization &result) { _sentRequest = 0; auto &d = result.c_auth_authorization(); if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf? - showCodeError([] { return lang(lng_server_error); }); + showCodeError(langFactory(lng_server_error)); return; } cSetLoggedPhoneNumber(getData()->phone); @@ -232,7 +231,7 @@ bool CodeWidget::codeSubmitFail(const RPCError &error) { if (MTP::isFloodError(error)) { stopCheck(); _sentRequest = 0; - showCodeError([] { return lang(lng_flood_error); }); + showCodeError(langFactory(lng_flood_error)); return true; } if (MTP::isDefaultHandledError(error)) return false; @@ -244,7 +243,7 @@ bool CodeWidget::codeSubmitFail(const RPCError &error) { goBack(); return true; } else if (err == qstr("PHONE_CODE_EMPTY") || err == qstr("PHONE_CODE_INVALID")) { - showCodeError([] { return lang(lng_bad_code); }); + showCodeError(langFactory(lng_bad_code)); return true; } else if (err == qstr("PHONE_NUMBER_UNOCCUPIED")) { // success, need to signUp getData()->code = _sentCode; @@ -260,7 +259,7 @@ bool CodeWidget::codeSubmitFail(const RPCError &error) { auto text = err + ": " + error.description(); showCodeError([text] { return text; }); } else { - showCodeError([] { return lang(lng_server_error); }); + showCodeError(langFactory(lng_server_error)); } return false; } @@ -338,7 +337,7 @@ void CodeWidget::onNoTelegramCode() { void CodeWidget::noTelegramCodeDone(const MTPauth_SentCode &result) { if (result.type() != mtpc_auth_sentCode) { - showCodeError([] { return lang(lng_server_error); }); + showCodeError(langFactory(lng_server_error)); return; } @@ -358,7 +357,7 @@ void CodeWidget::noTelegramCodeDone(const MTPauth_SentCode &result) { bool CodeWidget::noTelegramCodeFail(const RPCError &error) { if (MTP::isFloodError(error)) { - showCodeError([] { return lang(lng_flood_error); }); + showCodeError(langFactory(lng_flood_error)); return true; } if (MTP::isDefaultHandledError(error)) return false; @@ -367,7 +366,7 @@ bool CodeWidget::noTelegramCodeFail(const RPCError &error) { auto text = error.type() + ": " + error.description(); showCodeError([text] { return text; }); } else { - showCodeError([] { return lang(lng_server_error); }); + showCodeError(langFactory(lng_server_error)); } return false; } diff --git a/Telegram/SourceFiles/intro/introcode.h b/Telegram/SourceFiles/intro/introcode.h index 37f8f5ad8..2aad77eaa 100644 --- a/Telegram/SourceFiles/intro/introcode.h +++ b/Telegram/SourceFiles/intro/introcode.h @@ -35,7 +35,7 @@ class CodeInput final : public Ui::MaskedInputField { Q_OBJECT public: - CodeInput(QWidget *parent, const style::InputField &st, const QString &ph); + CodeInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory); void setDigitsCountMax(int digitsCount); diff --git a/Telegram/SourceFiles/intro/introphone.cpp b/Telegram/SourceFiles/intro/introphone.cpp index 9b69b361f..0f4660e22 100644 --- a/Telegram/SourceFiles/intro/introphone.cpp +++ b/Telegram/SourceFiles/intro/introphone.cpp @@ -48,8 +48,8 @@ PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, dat connect(_code, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest())); - setTitleText([] { return lang(lng_phone_title); }); - setDescriptionText([] { return lang(lng_phone_desc); }); + setTitleText(langFactory(lng_phone_title)); + setDescriptionText(langFactory(lng_phone_desc)); subscribe(getData()->updated, [this] { countryChanged(); }); setErrorCentered(true); @@ -90,7 +90,7 @@ void PhoneWidget::hidePhoneError() { } void PhoneWidget::showSignup() { - showPhoneError([] { return lang(lng_bad_phone_noreg); }); + showPhoneError(langFactory(lng_bad_phone_noreg)); if (!_signup) { auto signupText = lng_phone_notreg(lt_link_start, textcmdStartLink(1), lt_link_end, textcmdStopLink(), lt_signup_start, textcmdStartLink(2), lt_signup_end, textcmdStopLink()); auto inner = object_ptr(this, signupText, Ui::FlatLabel::InitType::Rich, st::introDescription); @@ -121,7 +121,7 @@ void PhoneWidget::submit() { if (_sentRequest || isHidden()) return; if (!App::isValidPhone(fullNumber())) { - showPhoneError([] { return lang(lng_bad_phone); }); + showPhoneError(langFactory(lng_bad_phone)); _phone->setFocus(); return; } @@ -172,7 +172,7 @@ void PhoneWidget::phoneSubmitDone(const MTPauth_SentCode &result) { _sentRequest = 0; if (result.type() != mtpc_auth_sentCode) { - showPhoneError([] { return lang(lng_server_error); }); + showPhoneError(langFactory(lng_server_error)); return; } @@ -203,7 +203,7 @@ bool PhoneWidget::phoneSubmitFail(const RPCError &error) { if (MTP::isFloodError(error)) { stopCheck(); _sentRequest = 0; - showPhoneError([] { return lang(lng_flood_error); }); + showPhoneError(langFactory(lng_flood_error)); return true; } if (MTP::isDefaultHandledError(error)) return false; @@ -215,14 +215,14 @@ bool PhoneWidget::phoneSubmitFail(const RPCError &error) { Ui::show(Box(lang(lng_error_phone_flood))); return true; } else if (err == qstr("PHONE_NUMBER_INVALID")) { // show error - showPhoneError([] { return lang(lng_bad_phone); }); + showPhoneError(langFactory(lng_bad_phone)); return true; } if (cDebug()) { // internal server error auto text = err + ": " + error.description(); showPhoneError([text] { return text; }); } else { - showPhoneError([] { return lang(lng_server_error); }); + showPhoneError(langFactory(lng_server_error)); } return false; } diff --git a/Telegram/SourceFiles/intro/intropwdcheck.cpp b/Telegram/SourceFiles/intro/intropwdcheck.cpp index 2b2debf48..555bd2f53 100644 --- a/Telegram/SourceFiles/intro/intropwdcheck.cpp +++ b/Telegram/SourceFiles/intro/intropwdcheck.cpp @@ -37,9 +37,9 @@ PwdCheckWidget::PwdCheckWidget(QWidget *parent, Widget::Data *data) : Step(paren , _salt(getData()->pwdSalt) , _hasRecovery(getData()->hasRecovery) , _hint(getData()->pwdHint) -, _pwdField(this, st::introPassword, lang(lng_signin_password)) +, _pwdField(this, st::introPassword, langFactory(lng_signin_password)) , _pwdHint(this, st::introPasswordHint) -, _codeField(this, st::introPassword, lang(lng_signin_code)) +, _codeField(this, st::introPassword, langFactory(lng_signin_code)) , _toRecover(this, lang(lng_signin_recover)) , _toPassword(this, lang(lng_signin_try_password)) , _checkRequest(this) { @@ -51,7 +51,7 @@ PwdCheckWidget::PwdCheckWidget(QWidget *parent, Widget::Data *data) : Step(paren connect(_pwdField, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_codeField, SIGNAL(changed()), this, SLOT(onInputChange())); - setTitleText([] { return lang(lng_signin_title); }); + setTitleText(langFactory(lng_signin_title)); updateDescriptionText(); setErrorBelowLink(true); @@ -67,8 +67,6 @@ PwdCheckWidget::PwdCheckWidget(QWidget *parent, Widget::Data *data) : Step(paren } void PwdCheckWidget::refreshLang() { - if (_pwdField) _pwdField->setPlaceholder(lang(lng_signin_password)); - if (_codeField) _codeField->setPlaceholder(lang(lng_signin_code)); if (_toRecover) _toRecover->setText(lang(lng_signin_recover)); if (_toPassword) _toPassword->setText(lang(lng_signin_try_password)); updateControlsGeometry(); @@ -135,7 +133,7 @@ void PwdCheckWidget::pwdSubmitDone(bool recover, const MTPauth_Authorization &re } auto &d = result.c_auth_authorization(); if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf? - showError([] { return lang(lng_server_error); }); + showError(langFactory(lng_server_error)); return; } finish(d.vuser); @@ -145,7 +143,7 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) { if (MTP::isFloodError(error)) { _sentRequest = 0; stopCheck(); - showError([] { return lang(lng_flood_error); }); + showError(langFactory(lng_flood_error)); _pwdField->showError(); return true; } @@ -155,7 +153,7 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) { stopCheck(); auto &err = error.type(); if (err == qstr("PASSWORD_HASH_INVALID")) { - showError([] { return lang(lng_signin_bad_password); }); + showError(langFactory(lng_signin_bad_password)); _pwdField->selectAll(); _pwdField->showError(); return true; @@ -166,7 +164,7 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) { auto text = err + ": " + error.description(); showError([text] { return text; }); } else { - showError([] { return lang(lng_server_error); }); + showError(langFactory(lng_server_error)); } _pwdField->setFocus(); return false; @@ -174,7 +172,7 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) { bool PwdCheckWidget::codeSubmitFail(const RPCError &error) { if (MTP::isFloodError(error)) { - showError([] { return lang(lng_flood_error); }); + showError(langFactory(lng_flood_error)); _codeField->showError(); return true; } @@ -194,7 +192,7 @@ bool PwdCheckWidget::codeSubmitFail(const RPCError &error) { onToPassword(); return true; } else if (err == qstr("CODE_INVALID")) { - showError([] { return lang(lng_signin_wrong_code); }); + showError(langFactory(lng_signin_wrong_code)); _codeField->selectAll(); _codeField->showError(); return true; @@ -203,7 +201,7 @@ bool PwdCheckWidget::codeSubmitFail(const RPCError &error) { auto text = err + ": " + error.description(); showError([text] { return text; }); } else { - showError([] { return lang(lng_server_error); }); + showError(langFactory(lng_server_error)); } _codeField->setFocus(); return false; diff --git a/Telegram/SourceFiles/intro/introsignup.cpp b/Telegram/SourceFiles/intro/introsignup.cpp index 3cf46afa6..a655d52e5 100644 --- a/Telegram/SourceFiles/intro/introsignup.cpp +++ b/Telegram/SourceFiles/intro/introsignup.cpp @@ -36,29 +36,35 @@ namespace Intro { SignupWidget::SignupWidget(QWidget *parent, Widget::Data *data) : Step(parent, data) , _photo(this, st::introPhotoSize, st::introPhotoIconPosition) -, _first(this, st::introName, lang(lng_signup_firstname)) -, _last(this, st::introName, lang(lng_signup_lastname)) +, _first(this, st::introName, langFactory(lng_signup_firstname)) +, _last(this, st::introName, langFactory(lng_signup_lastname)) , _invertOrder(langFirstNameGoesSecond()) , _checkRequest(this) { subscribe(Lang::Current().updated(), [this] { refreshLang(); }); + if (_invertOrder) { + setTabOrder(_last, _first); + } else { + setTabOrder(_first, _last); + } connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest())); setupPhotoButton(); - if (_invertOrder) { - setTabOrder(_last, _first); - } setErrorCentered(true); - setTitleText([] { return lang(lng_signup_title); }); - setDescriptionText([] { return lang(lng_signup_desc); }); + setTitleText(langFactory(lng_signup_title)); + setDescriptionText(langFactory(lng_signup_desc)); setMouseTracking(true); } void SignupWidget::refreshLang() { - _first->setPlaceholder(lang(lng_signup_firstname)); - _last->setPlaceholder(lang(lng_signup_lastname)); + _invertOrder = langFirstNameGoesSecond(); + if (_invertOrder) { + setTabOrder(_last, _first); + } else { + setTabOrder(_first, _last); + } updateControlsGeometry(); } @@ -79,7 +85,7 @@ void SignupWidget::setupPhotoButton() { } if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) { - showError([] { return lang(lng_bad_photo); }); + showError(langFactory(lng_bad_photo)); return; } auto box = Ui::show(Box(img, PeerId(0))); @@ -155,7 +161,7 @@ void SignupWidget::nameSubmitDone(const MTPauth_Authorization &result) { stopCheck(); auto &d = result.c_auth_authorization(); if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf? - showError([] { return lang(lng_server_error); }); + showError(langFactory(lng_server_error)); return; } finish(d.vuser, _photoImage); @@ -164,7 +170,7 @@ void SignupWidget::nameSubmitDone(const MTPauth_Authorization &result) { bool SignupWidget::nameSubmitFail(const RPCError &error) { if (MTP::isFloodError(error)) { stopCheck(); - showError([] { return lang(lng_flood_error); }); + showError(langFactory(lng_flood_error)); if (_invertOrder) { _first->setFocus(); } else { @@ -185,11 +191,11 @@ bool SignupWidget::nameSubmitFail(const RPCError &error) { goBack(); return true; } else if (err == "FIRSTNAME_INVALID") { - showError([] { return lang(lng_bad_name); }); + showError(langFactory(lng_bad_name)); _first->setFocus(); return true; } else if (err == "LASTNAME_INVALID") { - showError([] { return lang(lng_bad_name); }); + showError(langFactory(lng_bad_name)); _last->setFocus(); return true; } @@ -197,7 +203,7 @@ bool SignupWidget::nameSubmitFail(const RPCError &error) { auto text = err + ": " + error.description(); showError([text] { return text; }); } else { - showError([] { return lang(lng_server_error); }); + showError(langFactory(lng_server_error)); } if (_invertOrder) { _last->setFocus(); diff --git a/Telegram/SourceFiles/intro/introstart.cpp b/Telegram/SourceFiles/intro/introstart.cpp index 6cba84bf0..0b8b576cc 100644 --- a/Telegram/SourceFiles/intro/introstart.cpp +++ b/Telegram/SourceFiles/intro/introstart.cpp @@ -31,7 +31,7 @@ namespace Intro { StartWidget::StartWidget(QWidget *parent, Widget::Data *data) : Step(parent, data, true) { setMouseTracking(true); setTitleText([] { return qsl("Telegram Desktop"); }); - setDescriptionText([] { return lang(lng_intro_about); }); + setDescriptionText(langFactory(lng_intro_about)); show(); } diff --git a/Telegram/SourceFiles/intro/introwidget.cpp b/Telegram/SourceFiles/intro/introwidget.cpp index 72c501b0f..0de491d74 100644 --- a/Telegram/SourceFiles/intro/introwidget.cpp +++ b/Telegram/SourceFiles/intro/introwidget.cpp @@ -56,8 +56,8 @@ constexpr str_const kDefaultCountry = "US"; Widget::Widget(QWidget *parent) : TWidget(parent) , _back(this, object_ptr(this, st::introBackButton), st::introSlideDuration) -, _settings(this, object_ptr(this, lang(lng_menu_settings), st::defaultBoxButton), st::introCoverDuration) -, _next(this, QString(), st::introNextButton) { +, _settings(this, object_ptr(this, langFactory(lng_menu_settings), st::defaultBoxButton), st::introCoverDuration) +, _next(this, base::lambda(), st::introNextButton) { auto country = Platform::SystemCountry(); if (country.isEmpty()) { country = str_const_toString(kDefaultCountry); @@ -98,11 +98,7 @@ Widget::Widget(QWidget *parent) : TWidget(parent) } void Widget::refreshLang() { - if (_settings) _settings->entity()->setText(lang(lng_menu_settings)); - if (_update) _update->entity()->setText(lang(lng_menu_update)); - if (_resetAccount) _resetAccount->entity()->setText(lang(lng_signin_reset_account)); - if (_next) _next->setText(getStep()->nextButtonText()); - updateControlsGeometry(); + InvokeQueued(this, [this] { updateControlsGeometry(); }); } void Widget::createLanguageLink() { @@ -139,7 +135,7 @@ void Widget::createLanguageLink() { void Widget::onCheckUpdateStatus() { if (Sandbox::updatingState() == Application::UpdatingReady) { if (_update) return; - _update.create(this, object_ptr(this, lang(lng_menu_update), st::defaultBoxButton), st::introCoverDuration); + _update.create(this, object_ptr(this, langFactory(lng_menu_update), st::defaultBoxButton), st::introCoverDuration); if (!_a_show.animating()) _update->show(); _update->entity()->setClickedCallback([] { checkReadyUpdate(); @@ -192,7 +188,7 @@ void Widget::historyMove(Direction direction) { _settings->toggleAnimated(!stepHasCover); if (_update) _update->toggleAnimated(!stepHasCover); if (_changeLanguage) _changeLanguage->toggleAnimated(getStep()->hasChangeLanguage()); - _next->setText(getStep()->nextButtonText()); + _next->setText([this] { return getStep()->nextButtonText(); }); if (_resetAccount) _resetAccount->hideAnimated(); getStep()->showAnimated(direction); fixOrder(); @@ -233,7 +229,7 @@ void Widget::appendStep(Step *step) { void Widget::showResetButton() { if (!_resetAccount) { - auto entity = object_ptr(this, lang(lng_signin_reset_account), st::introResetButton); + auto entity = object_ptr(this, langFactory(lng_signin_reset_account), st::introResetButton); _resetAccount.create(this, std::move(entity), st::introErrorDuration); _resetAccount->hideFast(); _resetAccount->entity()->setClickedCallback([this] { resetAccount(); }); @@ -274,7 +270,7 @@ void Widget::resetAccount() { Ui::show(Box(lang(lng_signin_reset_cancelled))); } else { Ui::hideLayer(); - getStep()->showError([] { return lang(lng_server_error); }); + getStep()->showError(langFactory(lng_server_error)); } }).send(); }))); @@ -296,7 +292,7 @@ void Widget::getNearestDC() { void Widget::showControls() { getStep()->show(); _next->show(); - _next->setText(getStep()->nextButtonText()); + _next->setText([this] { return getStep()->nextButtonText(); }); auto hasCover = getStep()->hasCover(); _settings->toggleFast(!hasCover); if (_update) _update->toggleFast(!hasCover); diff --git a/Telegram/SourceFiles/lang/lang_keys.h b/Telegram/SourceFiles/lang/lang_keys.h index 66afd2e2e..655edde80 100644 --- a/Telegram/SourceFiles/lang/lang_keys.h +++ b/Telegram/SourceFiles/lang/lang_keys.h @@ -26,6 +26,10 @@ inline QString lang(LangKey key) { return Lang::Current().getValue(key); } +inline base::lambda langFactory(LangKey key) { + return [key] { return Lang::Current().getValue(key); }; +} + template inline QString langDateMaybeWithYear(QDate date, WithYear withYear, WithoutYear withoutYear) { auto month = date.month(); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index e0e0696f5..5c15a087f 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -82,6 +82,8 @@ MediaView::MediaView(QWidget*) : TWidget(nullptr) , _a_state(animation(this, &MediaView::step_state)) , _dropdown(this, st::mediaviewDropdownMenu) , _dropdownShowTimer(this) { + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); + TextCustomTagsMap custom; custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); _saveMsgText.setRichText(st::mediaviewSaveMsgStyle, lang(lng_mediaview_saved), _textDlgOptions, custom); @@ -148,6 +150,10 @@ MediaView::MediaView(QWidget*) : TWidget(nullptr) connect(_dropdownShowTimer, SIGNAL(timeout()), this, SLOT(onDropdown())); } +void MediaView::refreshLang() { + InvokeQueued(this, [this] { updateThemePreviewGeometry(); }); +} + void MediaView::moveToScreen() { if (App::wnd() && windowHandle() && App::wnd()->windowHandle() && windowHandle()->screen() != App::wnd()->windowHandle()->screen()) { windowHandle()->setScreen(App::wnd()->windowHandle()->screen()); @@ -1468,14 +1474,14 @@ void MediaView::initThemePreview() { _themePreviewId = 0; _themePreview = std::move(result); if (_themePreview) { - _themeApply.create(this, lang(lng_theme_preview_apply), st::themePreviewApplyButton); + _themeApply.create(this, langFactory(lng_theme_preview_apply), st::themePreviewApplyButton); _themeApply->show(); _themeApply->setClickedCallback([this] { auto preview = std::move(_themePreview); close(); Window::Theme::Apply(std::move(preview)); }); - _themeCancel.create(this, lang(lng_cancel), st::themePreviewCancelButton); + _themeCancel.create(this, langFactory(lng_cancel), st::themePreviewCancelButton); _themeCancel->show(); _themeCancel->setClickedCallback([this] { close(); }); updateControls(); diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 18e06f900..4c911dd43 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -153,6 +153,7 @@ private: OverVideo, }; + void refreshLang(); void showSaveMsgFile(); void updateMixerVideoVolume() const; diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index becf8a625..b55a0bbe7 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -58,7 +58,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, P , _history(App::history(_peer->id)) , _channel(peerToChannel(_peer->id)) , _rowWidth(st::msgMinWidth) -, _search(this, st::overviewFilter, lang(lng_dlg_filter)) +, _search(this, st::overviewFilter, langFactory(lng_dlg_filter)) , _cancelSearch(this, st::dialogsCancelSearch) , _itemsToBeLoaded(LinksOverviewPerPage * 2) , _width(st::windowMinWidth) { diff --git a/Telegram/SourceFiles/passcodewidget.cpp b/Telegram/SourceFiles/passcodewidget.cpp index bf7f31a45..492d02ad6 100644 --- a/Telegram/SourceFiles/passcodewidget.cpp +++ b/Telegram/SourceFiles/passcodewidget.cpp @@ -33,8 +33,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "auth_session.h" PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent) -, _passcode(this, st::passcodeInput, lang(lng_passcode_ph)) -, _submit(this, lang(lng_passcode_submit), st::passcodeSubmit) +, _passcode(this, st::passcodeInput, langFactory(lng_passcode_ph)) +, _submit(this, langFactory(lng_passcode_submit), st::passcodeSubmit) , _logout(this, lang(lng_passcode_logout)) { connect(_passcode, SIGNAL(changed()), this, SLOT(onChanged())); connect(_passcode, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); diff --git a/Telegram/SourceFiles/profile/profile_block_settings.cpp b/Telegram/SourceFiles/profile/profile_block_settings.cpp index ead6aade6..c8dcd6f70 100644 --- a/Telegram/SourceFiles/profile/profile_block_settings.cpp +++ b/Telegram/SourceFiles/profile/profile_block_settings.cpp @@ -62,8 +62,8 @@ private: }; void BlockedBoxController::prepare() { - view()->setTitle(lang(lng_blocked_list_title)); - view()->addButton(lang(lng_close), [this] { view()->closeBox(); }); + view()->setTitle(langFactory(lng_blocked_list_title)); + view()->addButton(langFactory(lng_close), [this] { view()->closeBox(); }); view()->setAboutText(lang(lng_contacts_loading)); view()->refreshRows(); diff --git a/Telegram/SourceFiles/profile/profile_cover.cpp b/Telegram/SourceFiles/profile/profile_cover.cpp index c631dd160..ee10cd27f 100644 --- a/Telegram/SourceFiles/profile/profile_cover.cpp +++ b/Telegram/SourceFiles/profile/profile_cover.cpp @@ -59,6 +59,8 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent) , _peerMegagroup(peer->isMegagroup() ? _peerChannel : nullptr) , _userpicButton(this, peer) , _name(this, st::profileNameLabel) { + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); + setAttribute(Qt::WA_OpaquePaintEvent); setAcceptDrops(true); @@ -86,6 +88,10 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent) refreshButtons(); } +void CoverWidget::refreshLang() { + InvokeQueued(this, [this] { moveAndToggleButtons(width()); }); +} + PhotoData *CoverWidget::validatePhoto() const { auto photo = (_peer->photoId && _peer->photoId != UnknownPeerPhotoId) ? App::photo(_peer->photoId) : nullptr; _userpicButton->setPointerCursor(photo != nullptr && photo->date != 0); @@ -408,41 +414,41 @@ void CoverWidget::refreshButtons() { } void CoverWidget::setUserButtons() { - addButton(lang(lng_profile_send_message), SLOT(onSendMessage())); + addButton(langFactory(lng_profile_send_message), SLOT(onSendMessage())); if (_peerUser->botInfo && !_peerUser->botInfo->cantJoinGroups) { - addButton(lang(lng_profile_invite_to_group), SLOT(onAddBotToGroup()), &st::profileAddMemberButton); + addButton(langFactory(lng_profile_invite_to_group), SLOT(onAddBotToGroup()), &st::profileAddMemberButton); } else if (_peerUser->canShareThisContact()) { - addButton(lang(lng_profile_share_contact), SLOT(onShareContact())); + addButton(langFactory(lng_profile_share_contact), SLOT(onShareContact())); } } void CoverWidget::setChatButtons() { if (_peerChat->canEdit()) { - addButton(lang(lng_profile_set_group_photo), SLOT(onSetPhoto())); - addButton(lang(lng_profile_add_participant), SLOT(onAddMember()), &st::profileAddMemberButton); + addButton(langFactory(lng_profile_set_group_photo), SLOT(onSetPhoto())); + addButton(langFactory(lng_profile_add_participant), SLOT(onAddMember()), &st::profileAddMemberButton); } } void CoverWidget::setMegagroupButtons() { if (_peerMegagroup->amIn()) { if (_peerMegagroup->canEditPhoto()) { - addButton(lang(lng_profile_set_group_photo), SLOT(onSetPhoto())); + addButton(langFactory(lng_profile_set_group_photo), SLOT(onSetPhoto())); } } else { - addButton(lang(lng_profile_join_channel), SLOT(onJoin())); + addButton(langFactory(lng_profile_join_channel), SLOT(onJoin())); } if (_peerMegagroup->canAddMembers()) { - addButton(lang(lng_profile_add_participant), SLOT(onAddMember()), &st::profileAddMemberButton); + addButton(langFactory(lng_profile_add_participant), SLOT(onAddMember()), &st::profileAddMemberButton); } } void CoverWidget::setChannelButtons() { if (_peerChannel->amCreator()) { - addButton(lang(lng_profile_set_group_photo), SLOT(onSetPhoto())); + addButton(langFactory(lng_profile_set_group_photo), SLOT(onSetPhoto())); } else if (_peerChannel->amIn()) { - addButton(lang(lng_profile_view_channel), SLOT(onViewChannel())); + addButton(langFactory(lng_profile_view_channel), SLOT(onViewChannel())); } else { - addButton(lang(lng_profile_join_channel), SLOT(onJoin())); + addButton(langFactory(lng_profile_join_channel), SLOT(onJoin())); } } @@ -454,13 +460,13 @@ void CoverWidget::clearButtons() { } } -void CoverWidget::addButton(const QString &text, const char *slot, const style::RoundButton *replacementStyle) { +void CoverWidget::addButton(base::lambda textFactory, const char *slot, const style::RoundButton *replacementStyle) { auto &buttonStyle = _buttons.isEmpty() ? st::profilePrimaryButton : st::profileSecondaryButton; - auto button = new Ui::RoundButton(this, text, buttonStyle); + auto button = new Ui::RoundButton(this, std::move(textFactory), buttonStyle); connect(button, SIGNAL(clicked()), this, slot); button->show(); - auto replacement = replacementStyle ? new Ui::RoundButton(this, QString(), *replacementStyle) : nullptr; + auto replacement = replacementStyle ? new Ui::RoundButton(this, base::lambda(), *replacementStyle) : nullptr; if (replacement) { connect(replacement, SIGNAL(clicked()), this, slot); replacement->hide(); diff --git a/Telegram/SourceFiles/profile/profile_cover.h b/Telegram/SourceFiles/profile/profile_cover.h index 52eb44975..8f1c3b6b2 100644 --- a/Telegram/SourceFiles/profile/profile_cover.h +++ b/Telegram/SourceFiles/profile/profile_cover.h @@ -80,6 +80,8 @@ protected: int resizeGetHeight(int newWidth) override; private: + void refreshLang(); + // Observed notifications. void notifyPeerUpdated(const Notify::PeerUpdate &update); @@ -99,7 +101,7 @@ private: void setChannelButtons(); void clearButtons(); - void addButton(const QString &text, const char *slot, const style::RoundButton *replacementStyle = nullptr); + void addButton(base::lambda textFactory, const char *slot, const style::RoundButton *replacementStyle = nullptr); void paintDivider(Painter &p); diff --git a/Telegram/SourceFiles/profile/profile_fixed_bar.cpp b/Telegram/SourceFiles/profile/profile_fixed_bar.cpp index c49d3a4c2..a6fc48fbe 100644 --- a/Telegram/SourceFiles/profile/profile_fixed_bar.cpp +++ b/Telegram/SourceFiles/profile/profile_fixed_bar.cpp @@ -49,6 +49,8 @@ FixedBar::FixedBar(QWidget *parent, PeerData *peer) : TWidget(parent) , _peerChannel(peer->asChannel()) , _peerMegagroup(peer->isMegagroup() ? _peerChannel : nullptr) , _backButton(this, lang(lng_menu_back)) { + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); + _backButton->moveToLeft(0, 0); connect(_backButton, SIGNAL(clicked()), this, SLOT(onBack())); @@ -97,36 +99,36 @@ void FixedBar::refreshRightActions() { void FixedBar::setUserActions() { if (_peerUser->canShareThisContact()) { - addRightAction(RightActionType::ShareContact, lang(lng_profile_top_bar_share_contact), SLOT(onShareContact())); + addRightAction(RightActionType::ShareContact, langFactory(lng_profile_top_bar_share_contact), SLOT(onShareContact())); } if (_peerUser->isContact()) { - addRightAction(RightActionType::EditContact, lang(lng_profile_edit_contact), SLOT(onEditContact())); - addRightAction(RightActionType::DeleteContact, lang(lng_profile_delete_contact), SLOT(onDeleteContact())); + addRightAction(RightActionType::EditContact, langFactory(lng_profile_edit_contact), SLOT(onEditContact())); + addRightAction(RightActionType::DeleteContact, langFactory(lng_profile_delete_contact), SLOT(onDeleteContact())); } else if (_peerUser->canAddContact()) { - addRightAction(RightActionType::AddContact, lang(lng_profile_add_contact), SLOT(onAddContact())); + addRightAction(RightActionType::AddContact, langFactory(lng_profile_add_contact), SLOT(onAddContact())); } } void FixedBar::setChatActions() { if (_peerChat->canEdit()) { - addRightAction(RightActionType::EditGroup, lang(lng_profile_edit_contact), SLOT(onEditGroup())); + addRightAction(RightActionType::EditGroup, langFactory(lng_profile_edit_contact), SLOT(onEditGroup())); } - addRightAction(RightActionType::LeaveGroup, lang(lng_profile_delete_and_exit), SLOT(onLeaveGroup())); + addRightAction(RightActionType::LeaveGroup, langFactory(lng_profile_delete_and_exit), SLOT(onLeaveGroup())); } void FixedBar::setMegagroupActions() { if (_peerMegagroup->amCreator() || _peerMegagroup->amEditor()) { - addRightAction(RightActionType::EditChannel, lang(lng_profile_edit_contact), SLOT(onEditChannel())); + addRightAction(RightActionType::EditChannel, langFactory(lng_profile_edit_contact), SLOT(onEditChannel())); } } void FixedBar::setChannelActions() { if (_peerChannel->amCreator()) { - addRightAction(RightActionType::EditChannel, lang(lng_profile_edit_contact), SLOT(onEditChannel())); + addRightAction(RightActionType::EditChannel, langFactory(lng_profile_edit_contact), SLOT(onEditChannel())); } } -void FixedBar::addRightAction(RightActionType type, const QString &text, const char *slot) { +void FixedBar::addRightAction(RightActionType type, base::lambda textFactory, const char *slot) { if (_rightActions.size() > _currentAction) { if (_rightActions.at(_currentAction).type == type) { ++_currentAction; @@ -138,7 +140,7 @@ void FixedBar::addRightAction(RightActionType type, const QString &text, const c } _rightActions[_currentAction].type = type; delete _rightActions[_currentAction].button; - _rightActions[_currentAction].button = new Ui::RoundButton(this, text, st::profileFixedBarButton); + _rightActions[_currentAction].button = new Ui::RoundButton(this, std::move(textFactory), st::profileFixedBarButton); connect(_rightActions[_currentAction].button, SIGNAL(clicked()), this, slot); bool showButton = !_animatingMode && (type != RightActionType::ShareContact || !_hideShareContactButton); _rightActions[_currentAction].button->setVisible(showButton); @@ -193,12 +195,7 @@ void FixedBar::onLeaveGroup() { int FixedBar::resizeGetHeight(int newWidth) { int newHeight = 0; - int buttonLeft = newWidth; - for (auto i = _rightActions.cend(), b = _rightActions.cbegin(); i != b;) { - --i; - buttonLeft -= i->button->width(); - i->button->moveToLeft(buttonLeft, 0); - } + updateButtonsGeometry(newWidth); _backButton->resizeToWidth(newWidth); _backButton->moveToLeft(0, 0); @@ -207,6 +204,19 @@ int FixedBar::resizeGetHeight(int newWidth) { return newHeight; } +void FixedBar::updateButtonsGeometry(int newWidth) { + int buttonLeft = newWidth; + for (auto i = _rightActions.cend(), b = _rightActions.cbegin(); i != b;) { + --i; + buttonLeft -= i->button->width(); + i->button->moveToLeft(buttonLeft, 0); + } +} + +void FixedBar::refreshLang() { + InvokeQueued(this, [this] { updateButtonsGeometry(width()); }); +} + void FixedBar::setAnimatingMode(bool enabled) { if (_animatingMode != enabled) { _animatingMode = enabled; diff --git a/Telegram/SourceFiles/profile/profile_fixed_bar.h b/Telegram/SourceFiles/profile/profile_fixed_bar.h index b462eda52..6d6dfd5ef 100644 --- a/Telegram/SourceFiles/profile/profile_fixed_bar.h +++ b/Telegram/SourceFiles/profile/profile_fixed_bar.h @@ -64,6 +64,8 @@ private slots: void onLeaveGroup(); private: + void refreshLang(); + void updateButtonsGeometry(int newWidth); void notifyPeerUpdate(const Notify::PeerUpdate &update); void refreshRightActions(); @@ -83,7 +85,7 @@ private: ShareContact, }; - void addRightAction(RightActionType type, const QString &text, const char *slot); + void addRightAction(RightActionType type, base::lambda textFactory, const char *slot); void applyHideShareContactButton(); PeerData *_peer; diff --git a/Telegram/SourceFiles/settings/settings_cover.cpp b/Telegram/SourceFiles/settings/settings_cover.cpp index 48840c033..f088aa211 100644 --- a/Telegram/SourceFiles/settings/settings_cover.cpp +++ b/Telegram/SourceFiles/settings/settings_cover.cpp @@ -43,8 +43,8 @@ CoverWidget::CoverWidget(QWidget *parent, UserData *self) : BlockWidget(parent, , _userpicButton(this, _self) , _name(this, st::settingsNameLabel) , _editNameInline(this, st::settingsEditButton) -, _setPhoto(this, lang(lng_settings_upload), st::settingsPrimaryButton) -, _editName(this, lang(lng_settings_edit), st::settingsSecondaryButton) { +, _setPhoto(this, langFactory(lng_settings_upload), st::settingsPrimaryButton) +, _editName(this, langFactory(lng_settings_edit), st::settingsSecondaryButton) { setAcceptDrops(true); _name->setSelectable(true); @@ -105,14 +105,7 @@ int CoverWidget::resizeGetHeight(int newWidth) { _cancelPhotoUpload->moveToLeft(_statusPosition.x() + st::settingsStatusFont->width(_statusText) + st::settingsStatusFont->spacew, _statusPosition.y(), newWidth); } - int buttonLeft = _userpicButton->x() + _userpicButton->width() + st::settingsButtonLeft; - int buttonsRight = newWidth - st::settingsButtonSkip; - _setPhoto->moveToLeft(buttonLeft, _userpicButton->y() + st::settingsButtonTop, newWidth); - buttonLeft += _setPhoto->width() + st::settingsButtonSkip; - _editName->moveToLeft(buttonLeft, _setPhoto->y(), newWidth); - _editNameVisible = (buttonLeft + _editName->width() + st::settingsButtonSkip <= newWidth); - _editName->setVisible(_editNameVisible); - + refreshButtonsGeometry(newWidth); refreshNameGeometry(newWidth); newHeight += st::settingsPhotoSize; @@ -127,6 +120,16 @@ int CoverWidget::resizeGetHeight(int newWidth) { return newHeight; } +void CoverWidget::refreshButtonsGeometry(int newWidth) { + int buttonLeft = _userpicButton->x() + _userpicButton->width() + st::settingsButtonLeft; + int buttonsRight = newWidth - st::settingsButtonSkip; + _setPhoto->moveToLeft(buttonLeft, _userpicButton->y() + st::settingsButtonTop, newWidth); + buttonLeft += _setPhoto->width() + st::settingsButtonSkip; + _editName->moveToLeft(buttonLeft, _setPhoto->y(), newWidth); + _editNameVisible = (buttonLeft + _editName->width() + st::settingsButtonSkip <= newWidth); + _editName->setVisible(_editNameVisible); +} + void CoverWidget::refreshNameGeometry(int newWidth) { int infoLeft = _userpicButton->x() + _userpicButton->width(); int nameLeft = infoLeft + st::settingsNameLeft - st::settingsNameLabel.margin.left(); diff --git a/Telegram/SourceFiles/settings/settings_cover.h b/Telegram/SourceFiles/settings/settings_cover.h index ccd507246..cd4ff3d34 100644 --- a/Telegram/SourceFiles/settings/settings_cover.h +++ b/Telegram/SourceFiles/settings/settings_cover.h @@ -72,6 +72,7 @@ private: PhotoData *validatePhoto() const; + void refreshButtonsGeometry(int newWidth); void refreshNameGeometry(int newWidth); void refreshNameText(); void refreshStatusText(); diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp index bb409ed9d..a9c7c1308 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp @@ -51,8 +51,8 @@ private: }; void BlockUserBoxController::prepareViewHook() { - view()->setTitle(lang(lng_blocked_list_add_title)); - view()->addButton(lang(lng_cancel), [this] { view()->closeBox(); }); + view()->setTitle(langFactory(lng_blocked_list_add_title)); + view()->addButton(langFactory(lng_cancel), [this] { view()->closeBox(); }); subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserIsBlocked, [this](const Notify::PeerUpdate &update) { if (auto user = update.peer->asUser()) { @@ -94,9 +94,9 @@ std::unique_ptr BlockUserBoxController::createRow(H } // namespace void BlockedBoxController::prepare() { - view()->setTitle(lang(lng_blocked_list_title)); - view()->addButton(lang(lng_close), [this] { view()->closeBox(); }); - view()->addLeftButton(lang(lng_blocked_list_add), [this] { blockUser(); }); + view()->setTitle(langFactory(lng_blocked_list_title)); + view()->addButton(langFactory(lng_close), [this] { view()->closeBox(); }); + view()->addLeftButton(langFactory(lng_blocked_list_add), [this] { blockUser(); }); view()->setAboutText(lang(lng_contacts_loading)); view()->refreshRows(); diff --git a/Telegram/SourceFiles/ui/countryinput.cpp b/Telegram/SourceFiles/ui/countryinput.cpp index e0024215e..f6fdb9324 100644 --- a/Telegram/SourceFiles/ui/countryinput.cpp +++ b/Telegram/SourceFiles/ui/countryinput.cpp @@ -212,11 +212,11 @@ void CountryInput::setText(const QString &newText) { } CountrySelectBox::CountrySelectBox(QWidget*) -: _select(this, st::contactsMultiSelect, lang(lng_country_ph)) { +: _select(this, st::contactsMultiSelect, langFactory(lng_country_ph)) { } void CountrySelectBox::prepare() { - setTitle(lang(lng_country_select)); + setTitle(langFactory(lng_country_select)); _select->resizeToWidth(st::boxWidth); _select->setQueryChangedCallback([this](const QString &query) { onFilterUpdate(query); }); @@ -224,7 +224,7 @@ void CountrySelectBox::prepare() { _inner = setInnerWidget(object_ptr(this), st::countriesScroll, _select->height()); - addButton(lang(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [this] { closeBox(); }); setDimensions(st::boxWidth, st::boxMaxListHeight); diff --git a/Telegram/SourceFiles/ui/widgets/buttons.cpp b/Telegram/SourceFiles/ui/widgets/buttons.cpp index d56a4e214..a900ad3c1 100644 --- a/Telegram/SourceFiles/ui/widgets/buttons.cpp +++ b/Telegram/SourceFiles/ui/widgets/buttons.cpp @@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "ui/effects/ripple_animation.h" #include "ui/effects/cross_animation.h" +#include "lang/lang_instance.h" namespace Ui { @@ -351,20 +352,21 @@ void RoundButton::Numbers::paint(Painter &p, int x, int y, int outerWidth) { p.setOpacity(1.); } -RoundButton::RoundButton(QWidget *parent, const QString &text, const style::RoundButton &st) : RippleButton(parent, st.ripple) -, _fullText(text) +RoundButton::RoundButton(QWidget *parent, base::lambda textFactory, const style::RoundButton &st) : RippleButton(parent, st.ripple) +, _textFactory(std::move(textFactory)) , _st(st) { - updateText(); + subscribe(Lang::Current().updated(), [this] { refreshText(); }); + refreshText(); } void RoundButton::setTextTransform(TextTransform transform) { _transform = transform; - updateText(); + refreshText(); } -void RoundButton::setText(const QString &text) { - _fullText = text; - updateText(); +void RoundButton::setText(base::lambda textFactory) { + _textFactory = std::move(textFactory); + refreshText(); } void RoundButton::setNumbersText(const QString &numbersText, int numbers) { @@ -376,7 +378,7 @@ void RoundButton::setNumbersText(const QString &numbersText, int numbers) { } _numbers->setText(numbersText, numbers); } - updateText(); + refreshText(); } void RoundButton::setWidthChangedCallback(base::lambda callback) { @@ -408,18 +410,19 @@ void RoundButton::setFullWidth(int newFullWidth) { resizeToText(); } -void RoundButton::updateText() { - if (_transform == TextTransform::ToUpper) { - _text = _fullText.toUpper(); - } else { - _text = _fullText; - } +void RoundButton::refreshText() { + _text = computeFullText(); _textWidth = _text.isEmpty() ? 0 : _st.font->width(_text); resizeToText(); update(); } +QString RoundButton::computeFullText() const { + auto result = _textFactory ? _textFactory() : QString(); + return (_transform == TextTransform::ToUpper) ? result.toUpper() : result; +} + void RoundButton::resizeToText() { int innerWidth = contentWidth(); if (_fullWidthOverride < 0) { @@ -428,11 +431,7 @@ void RoundButton::resizeToText() { resize(innerWidth - _st.width + _st.padding.left() + _st.padding.right(), _st.height + _st.padding.top() + _st.padding.bottom()); } else { if (_st.width < innerWidth + (_st.height - _st.font->height)) { - auto fullText = _fullText; - if (_transform == TextTransform::ToUpper) { - fullText = std::move(fullText).toUpper(); - } - _text = _st.font->elided(fullText, qMax(_st.width - (_st.height - _st.font->height), 1)); + _text = _st.font->elided(computeFullText(), qMax(_st.width - (_st.height - _st.font->height), 1)); _textWidth = _st.font->width(_text); } resize(_st.width + _st.padding.left() + _st.padding.right(), _st.height + _st.padding.top() + _st.padding.bottom()); diff --git a/Telegram/SourceFiles/ui/widgets/buttons.h b/Telegram/SourceFiles/ui/widgets/buttons.h index 3fd0bc721..b9cceafe2 100644 --- a/Telegram/SourceFiles/ui/widgets/buttons.h +++ b/Telegram/SourceFiles/ui/widgets/buttons.h @@ -109,11 +109,11 @@ private: }; -class RoundButton : public RippleButton { +class RoundButton : public RippleButton, private base::Subscriber { public: - RoundButton(QWidget *parent, const QString &text, const style::RoundButton &st); + RoundButton(QWidget *parent, base::lambda textFactory, const style::RoundButton &st); - void setText(const QString &text); + void setText(base::lambda textFactory); void setNumbersText(const QString &numbersText) { setNumbersText(numbersText, numbersText.toInt()); @@ -144,12 +144,14 @@ protected: QPoint prepareRippleStartPosition() const override; private: + void refreshText(); + QString computeFullText() const; void setNumbersText(const QString &numbersText, int numbers); void numbersAnimationCallback(); - void updateText(); void resizeToText(); - QString _text, _fullText; + QString _text; + base::lambda _textFactory; int _textWidth; class Numbers; diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.cpp b/Telegram/SourceFiles/ui/widgets/input_fields.cpp index 230b97c2e..bc12f5af8 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.cpp +++ b/Telegram/SourceFiles/ui/widgets/input_fields.cpp @@ -133,10 +133,12 @@ QString FlatTextarea::tagsMimeType() { return qsl("application/x-td-field-tags"); } -FlatTextarea::FlatTextarea(QWidget *parent, const style::FlatTextarea &st, const QString &pholder, const QString &v, const TagList &tags) : TWidgetHelper(parent) +FlatTextarea::FlatTextarea(QWidget *parent, const style::FlatTextarea &st, base::lambda placeholderFactory, const QString &v, const TagList &tags) : TWidgetHelper(parent) +, _placeholderFactory(std::move(placeholderFactory)) , _placeholderVisible(!v.length()) , _lastTextWithTags { v, tags } , _st(st) { + setCursor(style::cur_text); setAcceptRichText(false); resize(_st.width, _st.font->height); @@ -144,7 +146,8 @@ FlatTextarea::FlatTextarea(QWidget *parent, const style::FlatTextarea &st, const setFont(_st.font->f); setAlignment(_st.align); - setPlaceholder(pholder); + subscribe(Lang::Current().updated(), [this] { refreshPlaceholder(); }); + refreshPlaceholder(); subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.paletteChanged()) { @@ -340,12 +343,12 @@ void FlatTextarea::paintEvent(QPaintEvent *e) { p.setClipRect(r); p.setFont(_st.font); p.setPen(anim::pen(_st.phColor, _st.phFocusColor, _a_placeholderFocused.current(ms, _focused ? 1. : 0.))); - if (_st.phAlign == style::al_topleft && _phAfter > 0) { + if (_st.phAlign == style::al_topleft && _placeholderAfterSymbols > 0) { int skipWidth = placeholderSkipWidth(); - p.drawText(_st.textMrg.left() - _fakeMargin + placeholderLeft + skipWidth, _st.textMrg.top() - _fakeMargin - st::lineWidth + _st.font->ascent, _ph); + p.drawText(_st.textMrg.left() - _fakeMargin + placeholderLeft + skipWidth, _st.textMrg.top() - _fakeMargin - st::lineWidth + _st.font->ascent, _placeholder); } else { QRect phRect(_st.textMrg.left() - _fakeMargin + _st.phPos.x() + placeholderLeft, _st.textMrg.top() - _fakeMargin + _st.phPos.y(), width() - _st.textMrg.left() - _st.textMrg.right(), height() - _st.textMrg.top() - _st.textMrg.bottom()); - p.drawText(phRect, _ph, QTextOption(_st.phAlign)); + p.drawText(phRect, _placeholder, QTextOption(_st.phAlign)); } p.restore(); p.setOpacity(1); @@ -354,12 +357,12 @@ void FlatTextarea::paintEvent(QPaintEvent *e) { } int FlatTextarea::placeholderSkipWidth() const { - if (!_phAfter) { + if (!_placeholderAfterSymbols) { return 0; } auto text = getTextWithTags().text; - auto result = _st.font->width(text.mid(0, _phAfter)); - if (_phAfter > text.size()) { + auto result = _st.font->width(text.mid(0, _placeholderAfterSymbols)); + if (_placeholderAfterSymbols > text.size()) { result += _st.font->spacew; } return result; @@ -1319,20 +1322,25 @@ void FlatTextarea::onRedoAvailable(bool avail) { if (App::wnd()) App::wnd()->updateGlobalMenu(); } -void FlatTextarea::setPlaceholder(const QString &ph, int32 afterSymbols) { - _ph = ph; - if (_phAfter != afterSymbols) { - _phAfter = afterSymbols; +void FlatTextarea::setPlaceholder(base::lambda placeholderFactory, int afterSymbols) { + _placeholderFactory = std::move(placeholderFactory); + if (_placeholderAfterSymbols != afterSymbols) { + _placeholderAfterSymbols = afterSymbols; updatePlaceholder(); } - int skipWidth = placeholderSkipWidth(); - _phelided = _st.font->elided(_ph, width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1 - skipWidth); + refreshPlaceholder(); +} + +void FlatTextarea::refreshPlaceholder() { + auto skipWidth = placeholderSkipWidth(); + auto placeholderText = _placeholderFactory ? _placeholderFactory() : QString(); + _placeholder = _st.font->elided(placeholderText, width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1 - skipWidth); if (_placeholderVisible) update(); } void FlatTextarea::updatePlaceholder() { auto textSize = (getTextWithTags().text.size() + textCursor().block().layout()->preeditAreaText().size()); - auto placeholderVisible = (textSize <= _phAfter); + auto placeholderVisible = (textSize <= _placeholderAfterSymbols); if (_placeholderVisible != placeholderVisible) { _placeholderVisible = placeholderVisible; _a_placeholderVisible.start([this] { update(); }, _placeholderVisible ? 0. : 1., _placeholderVisible ? 1. : 0., _st.phDuration); @@ -1436,7 +1444,7 @@ void FlatTextarea::keyPressEvent(QKeyEvent *e) { } void FlatTextarea::resizeEvent(QResizeEvent *e) { - _phelided = _st.font->elided(_ph, width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1); + refreshPlaceholder(); QTextEdit::resizeEvent(e); checkContentHeight(); } @@ -1461,9 +1469,9 @@ void FlatTextarea::contextMenuEvent(QContextMenuEvent *e) { } } -FlatInput::FlatInput(QWidget *parent, const style::FlatInput &st, const QString &pholder, const QString &v) : TWidgetHelper(v, parent) +FlatInput::FlatInput(QWidget *parent, const style::FlatInput &st, base::lambda placeholderFactory, const QString &v) : TWidgetHelper(v, parent) , _oldtext(v) -, _fullph(pholder) +, _placeholderFactory(std::move(placeholderFactory)) , _placeholderVisible(!v.length()) , _st(st) { setCursor(style::cur_text); @@ -1472,6 +1480,9 @@ FlatInput::FlatInput(QWidget *parent, const style::FlatInput &st, const QString setFont(_st.font->f); setAlignment(_st.align); + subscribe(Lang::Current().updated(), [this] { refreshPlaceholder(); }); + refreshPlaceholder(); + subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.paletteChanged()) { updatePalette(); @@ -1590,7 +1601,7 @@ void FlatInput::paintEvent(QPaintEvent *e) { QRect phRect(placeholderRect()); phRect.moveLeft(phRect.left() + left); phPrepare(p, placeholderFocused); - p.drawText(phRect, _ph, QTextOption(_st.phAlign)); + p.drawText(phRect, _placeholder, QTextOption(_st.phAlign)); p.restore(); } QLineEdit::paintEvent(e); @@ -1617,21 +1628,22 @@ void FlatInput::focusOutEvent(QFocusEvent *e) { } void FlatInput::resizeEvent(QResizeEvent *e) { - updatePlaceholderText(); + refreshPlaceholder(); return QLineEdit::resizeEvent(e); } -void FlatInput::setPlaceholder(const QString &ph) { - _fullph = ph; - updatePlaceholderText(); +void FlatInput::setPlaceholder(base::lambda placeholderFactory) { + _placeholderFactory = std::move(placeholderFactory); + refreshPlaceholder(); } -void FlatInput::updatePlaceholderText() { - int32 availw = width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1; - if (_st.font->width(_fullph) > availw) { - _ph = _st.font->elided(_fullph, availw); +void FlatInput::refreshPlaceholder() { + auto availw = width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1; + auto placeholderText = _placeholderFactory ? _placeholderFactory() : QString(); + if (_st.font->width(placeholderText) > availw) { + _placeholder = _st.font->elided(placeholderText, availw); } else { - _ph = _fullph; + _placeholder = placeholderText; } update(); } @@ -1673,10 +1685,6 @@ void FlatInput::inputMethodEvent(QInputMethodEvent *e) { } } -const QString &FlatInput::placeholder() const { - return _fullph; -} - QRect FlatInput::placeholderRect() const { return QRect(_st.textMrg.left() + _st.phPos.x(), _st.textMrg.top() + _st.phPos.y(), width() - _st.textMrg.left() - _st.textMrg.right(), height() - _st.textMrg.top() - _st.textMrg.bottom()); } @@ -1737,11 +1745,11 @@ void FlatInput::onTextChange(const QString &text) { if (App::wnd()) App::wnd()->updateGlobalMenu(); } -InputArea::InputArea(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val) : TWidget(parent) +InputArea::InputArea(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val) : TWidget(parent) , _st(st) , _inner(this) , _oldtext(val) -, _placeholderFull(ph) { +, _placeholderFactory(std::move(placeholderFactory)) { _inner->setAcceptRichText(false); resize(_st.width, _st.heightMin); @@ -1749,7 +1757,8 @@ InputArea::InputArea(QWidget *parent, const style::InputField &st, const QString _inner->setFont(_st.font->f); - createPlaceholderPath(); + subscribe(Lang::Current().updated(), [this] { refreshPlaceholder(); }); + refreshPlaceholder(); subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.paletteChanged()) { @@ -2446,32 +2455,33 @@ void InputArea::Inner::contextMenuEvent(QContextMenuEvent *e) { } void InputArea::resizeEvent(QResizeEvent *e) { - createPlaceholderPath(); + refreshPlaceholder(); _inner->setGeometry(rect().marginsRemoved(_st.textMargins)); _borderAnimationStart = width() / 2; TWidget::resizeEvent(e); checkContentHeight(); } -void InputArea::createPlaceholderPath() { +void InputArea::refreshPlaceholder() { + auto placeholderText = _placeholderFactory ? _placeholderFactory() : QString(); auto availableWidth = width() - _st.textMargins.left() - _st.textMargins.right() - _st.placeholderMargins.left() - _st.placeholderMargins.right() - 1; if (_st.placeholderScale > 0.) { auto placeholderFont = _st.placeholderFont->f; placeholderFont.setStyleStrategy(QFont::PreferMatch); auto metrics = QFontMetrics(placeholderFont); - _placeholder = metrics.elidedText(_placeholderFull, Qt::ElideRight, availableWidth); + _placeholder = metrics.elidedText(placeholderText, Qt::ElideRight, availableWidth); _placeholderPath = QPainterPath(); if (!_placeholder.isEmpty()) { _placeholderPath.addText(0, QFontMetrics(placeholderFont).ascent(), placeholderFont, _placeholder); } } else { - _placeholder = _st.placeholderFont->elided(_placeholderFull, availableWidth); + _placeholder = _st.placeholderFont->elided(placeholderText, availableWidth); } } -void InputArea::setPlaceholder(const QString &ph) { - _placeholderFull = ph; - createPlaceholderPath(); +void InputArea::setPlaceholder(base::lambda placeholderFactory) { + _placeholderFactory = std::move(placeholderFactory); + refreshPlaceholder(); update(); } @@ -2490,11 +2500,11 @@ void InputArea::setErrorShown(bool error) { } } -InputField::InputField(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val) : TWidget(parent) +InputField::InputField(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val) : TWidget(parent) , _st(st) , _inner(this) , _oldtext(val) -, _placeholderFull(ph) { +, _placeholderFactory(std::move(placeholderFactory)) { _inner->setAcceptRichText(false); resize(_st.width, _st.heightMin); @@ -2507,7 +2517,8 @@ InputField::InputField(QWidget *parent, const style::InputField &st, const QStri _inner->setFont(_st.font->f); _inner->setAlignment(_st.textAlign); - createPlaceholderPath(); + subscribe(Lang::Current().updated(), [this] { refreshPlaceholder(); }); + refreshPlaceholder(); subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.paletteChanged()) { @@ -3211,31 +3222,32 @@ void InputField::Inner::contextMenuEvent(QContextMenuEvent *e) { } void InputField::resizeEvent(QResizeEvent *e) { - createPlaceholderPath(); + refreshPlaceholder(); _inner->setGeometry(rect().marginsRemoved(_st.textMargins)); _borderAnimationStart = width() / 2; TWidget::resizeEvent(e); } -void InputField::createPlaceholderPath() { +void InputField::refreshPlaceholder() { + auto placeholderText = _placeholderFactory ? _placeholderFactory() : QString(); auto availableWidth = width() - _st.textMargins.left() - _st.textMargins.right() - _st.placeholderMargins.left() - _st.placeholderMargins.right() - 1; if (_st.placeholderScale > 0.) { auto placeholderFont = _st.placeholderFont->f; placeholderFont.setStyleStrategy(QFont::PreferMatch); auto metrics = QFontMetrics(placeholderFont); - _placeholder = metrics.elidedText(_placeholderFull, Qt::ElideRight, availableWidth); + _placeholder = metrics.elidedText(placeholderText, Qt::ElideRight, availableWidth); _placeholderPath = QPainterPath(); if (!_placeholder.isEmpty()) { _placeholderPath.addText(0, QFontMetrics(placeholderFont).ascent(), placeholderFont, _placeholder); } } else { - _placeholder = _st.placeholderFont->elided(_placeholderFull, availableWidth); + _placeholder = _st.placeholderFont->elided(placeholderText, availableWidth); } } -void InputField::setPlaceholder(const QString &ph) { - _placeholderFull = ph; - createPlaceholderPath(); +void InputField::setPlaceholder(base::lambda placeholderFactory) { + _placeholderFactory = std::move(placeholderFactory); + refreshPlaceholder(); update(); } @@ -3254,15 +3266,18 @@ void InputField::setErrorShown(bool error) { } } -MaskedInputField::MaskedInputField(QWidget *parent, const style::InputField &st, const QString &placeholder, const QString &val) : TWidgetHelper(val, parent) +MaskedInputField::MaskedInputField(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val) : TWidgetHelper(val, parent) , _st(st) , _oldtext(val) -, _placeholderFull(placeholder) { +, _placeholderFactory(std::move(placeholderFactory)) { resize(_st.width, _st.heightMin); setFont(_st.font); setAlignment(_st.textAlign); + subscribe(Lang::Current().updated(), [this] { refreshPlaceholder(); }); + refreshPlaceholder(); + subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.paletteChanged()) { updatePalette(); @@ -3270,8 +3285,6 @@ MaskedInputField::MaskedInputField(QWidget *parent, const style::InputField &st, }); updatePalette(); - createPlaceholderPath(); - setAttribute(Qt::WA_OpaquePaintEvent); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChange(const QString&))); @@ -3324,7 +3337,7 @@ void MaskedInputField::customUpDown(bool custom) { void MaskedInputField::setTextMargins(const QMargins &mrg) { _textMargins = mrg; - createPlaceholderPath(); + refreshPlaceholder(); } void MaskedInputField::onTouchTimer() { @@ -3501,30 +3514,31 @@ void MaskedInputField::setFocused(bool focused) { } void MaskedInputField::resizeEvent(QResizeEvent *e) { - createPlaceholderPath(); + refreshPlaceholder(); _borderAnimationStart = width() / 2; QLineEdit::resizeEvent(e); } -void MaskedInputField::createPlaceholderPath() { +void MaskedInputField::refreshPlaceholder() { + auto placeholderText = _placeholderFactory ? _placeholderFactory() : QString(); auto availableWidth = width() - _st.textMargins.left() - _st.textMargins.right() - _st.placeholderMargins.left() - _st.placeholderMargins.right() - 1; if (_st.placeholderScale > 0.) { auto placeholderFont = _st.placeholderFont->f; placeholderFont.setStyleStrategy(QFont::PreferMatch); auto metrics = QFontMetrics(placeholderFont); - _placeholder = metrics.elidedText(_placeholderFull, Qt::ElideRight, availableWidth); + _placeholder = metrics.elidedText(placeholderText, Qt::ElideRight, availableWidth); _placeholderPath = QPainterPath(); if (!_placeholder.isEmpty()) { _placeholderPath.addText(0, QFontMetrics(placeholderFont).ascent(), placeholderFont, _placeholder); } } else { - _placeholder = _st.placeholderFont->elided(_placeholderFull, availableWidth); + _placeholder = _st.placeholderFont->elided(placeholderText, availableWidth); } } -void MaskedInputField::setPlaceholder(const QString &ph) { - _placeholderFull = ph; - createPlaceholderPath(); +void MaskedInputField::setPlaceholder(base::lambda placeholderFactory) { + _placeholderFactory = std::move(placeholderFactory); + refreshPlaceholder(); update(); } @@ -3590,10 +3604,6 @@ void MaskedInputField::startPlaceholderAnimation() { } } -const QString &MaskedInputField::placeholder() const { - return _placeholderFull; -} - QRect MaskedInputField::placeholderRect() const { return rect().marginsRemoved(_st.textMargins + _st.placeholderMargins); } @@ -3848,11 +3858,11 @@ void PhonePartInput::onChooseCode(const QString &code) { startPlaceholderAnimation(); } -PasswordInput::PasswordInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val) : MaskedInputField(parent, st, ph, val) { +PasswordInput::PasswordInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val) : MaskedInputField(parent, st, std::move(placeholderFactory), val) { setEchoMode(QLineEdit::Password); } -PortInput::PortInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val) : MaskedInputField(parent, st, ph, val) { +PortInput::PortInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val) : MaskedInputField(parent, st, std::move(placeholderFactory), val) { if (!val.toInt() || val.toInt() > 65535) { setText(QString()); } @@ -3879,7 +3889,7 @@ void PortInput::correctValue(const QString &was, int32 wasCursor, QString &now, setCorrectedText(now, nowCursor, newText, newPos); } -UsernameInput::UsernameInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val, bool isLink) : MaskedInputField(parent, st, ph, val) +UsernameInput::UsernameInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val, bool isLink) : MaskedInputField(parent, st, std::move(placeholderFactory), val) , _linkPlaceholder(isLink ? Messenger::Instance().createInternalLink(QString()) : QString()) { if (!_linkPlaceholder.isEmpty()) { setTextMargins(style::margins(_st.textMargins.left() + _st.font->width(_linkPlaceholder), _st.textMargins.top(), _st.textMargins.right(), _st.textMargins.bottom())); @@ -3916,7 +3926,7 @@ void UsernameInput::correctValue(const QString &was, int32 wasCursor, QString &n setCorrectedText(now, nowCursor, now.mid(from, len), newPos); } -PhoneInput::PhoneInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val) : MaskedInputField(parent, st, ph, val) { +PhoneInput::PhoneInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val) : MaskedInputField(parent, st, std::move(placeholderFactory), val) { QString phone(val); if (phone.isEmpty()) { clearText(); diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.h b/Telegram/SourceFiles/ui/widgets/input_fields.h index 3c0af6c39..1576fbb33 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.h +++ b/Telegram/SourceFiles/ui/widgets/input_fields.h @@ -38,18 +38,18 @@ public: static TagList deserializeTagsList(QByteArray data, int textLength); static QString tagsMimeType(); - FlatTextarea(QWidget *parent, const style::FlatTextarea &st, const QString &ph = QString(), const QString &val = QString(), const TagList &tags = TagList()); + FlatTextarea(QWidget *parent, const style::FlatTextarea &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString(), const TagList &tags = TagList()); - void setMaxLength(int32 maxLength); - void setMinHeight(int32 minHeight); - void setMaxHeight(int32 maxHeight); + void setMaxLength(int maxLength); + void setMinHeight(int minHeight); + void setMaxHeight(int maxHeight); - void setPlaceholder(const QString &ph, int32 afterSymbols = 0); + void setPlaceholder(base::lambda placeholderFactory, int afterSymbols = 0); void updatePlaceholder(); void finishPlaceholder(); QRect getTextRect() const; - int32 fakeMargin() const; + int fakeMargin() const; QSize sizeHint() const override; QSize minimumSizeHint() const override; @@ -152,6 +152,7 @@ protected: private: void updatePalette(); + void refreshPlaceholder(); // "start" and "end" are in coordinates of text where emoji are replaced // by ObjectReplacementCharacter. If "end" = -1 means get text till the end. @@ -177,8 +178,9 @@ private: int _maxLength = -1; SubmitSettings _submitSettings = SubmitSettings::Enter; - QString _ph, _phelided; - int _phAfter = 0; + QString _placeholder; + base::lambda _placeholderFactory; + int _placeholderAfterSymbols = 0; bool _focused = false; bool _placeholderVisible = true; Animation _a_placeholderFocused; @@ -235,11 +237,10 @@ class FlatInput : public TWidgetHelper, private base::Subscriber { Q_OBJECT public: - FlatInput(QWidget *parent, const style::FlatInput &st, const QString &ph = QString(), const QString &val = QString()); + FlatInput(QWidget *parent, const style::FlatInput &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()); void updatePlaceholder(); - void setPlaceholder(const QString &ph); - const QString &placeholder() const; + void setPlaceholder(base::lambda placeholderFactory); QRect placeholderRect() const; QRect getTextRect() const; @@ -286,9 +287,11 @@ protected: private: void updatePalette(); - void updatePlaceholderText(); + void refreshPlaceholder(); - QString _oldtext, _ph, _fullph; + QString _oldtext; + QString _placeholder; + base::lambda _placeholderFactory; bool _customUpDown = false; @@ -315,18 +318,18 @@ class InputArea : public TWidget, private base::Subscriber { Q_OBJECT public: - InputArea(QWidget *parent, const style::InputField &st, const QString &ph = QString(), const QString &val = QString()); + InputArea(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()); void showError(); - void setMaxLength(int32 maxLength) { + void setMaxLength(int maxLength) { _maxLength = maxLength; } const QString &getLastText() const { return _oldtext; } - void setPlaceholder(const QString &ph); + void setPlaceholder(base::lambda placeholderFactory); void setDisplayFocused(bool focused); void finishAnimations(); void setFocusFast() { @@ -337,7 +340,7 @@ public: QSize sizeHint() const override; QSize minimumSizeHint() const override; - QString getText(int32 start = 0, int32 end = -1) const; + QString getText(int start = 0, int end = -1) const; bool hasText() const; bool isUndoAvailable() const; @@ -436,10 +439,10 @@ private: friend class Inner; void updatePalette(); + void refreshPlaceholder(); bool heightAutoupdated(); void checkContentHeight(); - void createPlaceholderPath(); void setErrorShown(bool error); void focusInInner(bool focusByMouse); @@ -464,7 +467,7 @@ private: bool _customUpDown = false; QString _placeholder; - QString _placeholderFull; + base::lambda _placeholderFactory; Animation _a_placeholderShifted; bool _placeholderShifted = false; QPainterPath _placeholderPath; @@ -494,9 +497,9 @@ class InputField : public TWidget, private base::Subscriber { Q_OBJECT public: - InputField(QWidget *parent, const style::InputField &st, const QString &ph = QString(), const QString &val = QString()); + InputField(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()); - void setMaxLength(int32 maxLength) { + void setMaxLength(int maxLength) { _maxLength = maxLength; } @@ -505,7 +508,7 @@ public: const QString &getLastText() const { return _oldtext; } - void setPlaceholder(const QString &ph); + void setPlaceholder(base::lambda placeholderFactory); void setPlaceholderHidden(bool forcePlaceholderHidden); void setDisplayFocused(bool focused); void finishAnimations(); @@ -517,7 +520,7 @@ public: QSize sizeHint() const override; QSize minimumSizeHint() const override; - QString getText(int32 start = 0, int32 end = -1) const; + QString getText(int start = 0, int end = -1) const; bool hasText() const; bool isUndoAvailable() const; @@ -625,8 +628,7 @@ private: friend class Inner; void updatePalette(); - - void createPlaceholderPath(); + void refreshPlaceholder(); void setErrorShown(bool error); void focusInInner(bool focusByMouse); @@ -650,7 +652,7 @@ private: bool _customUpDown = true; QString _placeholder; - QString _placeholderFull; + base::lambda _placeholderFactory; Animation _a_placeholderShifted; bool _placeholderShifted = false; QPainterPath _placeholderPath; @@ -679,7 +681,7 @@ class MaskedInputField : public TWidgetHelper, private base::Subscrib Q_OBJECT public: - MaskedInputField(QWidget *parent, const style::InputField &st, const QString &placeholder = QString(), const QString &val = QString()); + MaskedInputField(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()); void showError(); @@ -692,7 +694,7 @@ public: const QString &getLastText() const { return _oldtext; } - void setPlaceholder(const QString &ph); + void setPlaceholder(base::lambda placeholderFactory); void setPlaceholderHidden(bool forcePlaceholderHidden); void setDisplayFocused(bool focused); void finishAnimations(); @@ -746,7 +748,7 @@ protected: void contextMenuEvent(QContextMenuEvent *e) override; void inputMethodEvent(QInputMethodEvent *e) override; - virtual void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) { + virtual void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) { } void setCorrectedText(QString &now, int &nowCursor, const QString &newText, int newPos); @@ -758,7 +760,6 @@ protected: } void placeholderAdditionalPrepare(Painter &p, TimeMs ms); - const QString &placeholder() const; QRect placeholderRect() const; void setTextMargins(const QMargins &mrg); @@ -766,7 +767,7 @@ protected: private: void updatePalette(); - void createPlaceholderPath(); + void refreshPlaceholder(); void setErrorShown(bool error); void setFocused(bool focused); @@ -784,7 +785,7 @@ private: bool _customUpDown = false; QString _placeholder; - QString _placeholderFull; + base::lambda _placeholderFactory; Animation _a_placeholderShifted; bool _placeholderShifted = false; QPainterPath _placeholderPath; @@ -824,7 +825,7 @@ signals: void addedToNumber(const QString &added); protected: - void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override; + void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override; private: bool _nosignal; @@ -847,7 +848,7 @@ signals: protected: void keyPressEvent(QKeyEvent *e) override; - void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override; + void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override; void paintAdditionalPlaceholder(Painter &p, TimeMs ms) override; private: @@ -858,25 +859,25 @@ private: class PasswordInput : public MaskedInputField { public: - PasswordInput(QWidget *parent, const style::InputField &st, const QString &ph = QString(), const QString &val = QString()); + PasswordInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory = base::lambda(), const QString &val = QString()); }; class PortInput : public MaskedInputField { public: - PortInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val); + PortInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val); protected: - void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override; + void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override; }; class UsernameInput : public MaskedInputField { public: - UsernameInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val, bool isLink); + UsernameInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val, bool isLink); protected: - void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override; + void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override; void paintAdditionalPlaceholder(Painter &p, TimeMs ms) override; private: @@ -886,14 +887,14 @@ private: class PhoneInput : public MaskedInputField { public: - PhoneInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val); + PhoneInput(QWidget *parent, const style::InputField &st, base::lambda placeholderFactory, const QString &val); void clearText(); protected: void focusInEvent(QFocusEvent *e) override; - void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override; + void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override; void paintAdditionalPlaceholder(Painter &p, TimeMs ms) override; private: diff --git a/Telegram/SourceFiles/ui/widgets/multi_select.cpp b/Telegram/SourceFiles/ui/widgets/multi_select.cpp index c560c2963..38aecd493 100644 --- a/Telegram/SourceFiles/ui/widgets/multi_select.cpp +++ b/Telegram/SourceFiles/ui/widgets/multi_select.cpp @@ -325,10 +325,10 @@ void MultiSelect::Inner::Item::setOver(bool over) { } } -MultiSelect::MultiSelect(QWidget *parent, const style::MultiSelect &st, const QString &placeholder) : TWidget(parent) +MultiSelect::MultiSelect(QWidget *parent, const style::MultiSelect &st, base::lambda placeholderFactory) : TWidget(parent) , _st(st) , _scroll(this, _st.scroll) { - _inner = _scroll->setOwnedWidget(object_ptr(this, st, placeholder, [this](int activeTop, int activeBottom) { + _inner = _scroll->setOwnedWidget(object_ptr(this, st, std::move(placeholderFactory), [this](int activeTop, int activeBottom) { scrollTo(activeTop, activeBottom); })); _scroll->installEventFilter(this); @@ -443,10 +443,10 @@ int MultiSelect::resizeGetHeight(int newWidth) { return newHeight; } -MultiSelect::Inner::Inner(QWidget *parent, const style::MultiSelect &st, const QString &placeholder, ScrollCallback callback) : TWidget(parent) +MultiSelect::Inner::Inner(QWidget *parent, const style::MultiSelect &st, base::lambda placeholder, ScrollCallback callback) : TWidget(parent) , _st(st) , _scrollCallback(std::move(callback)) -, _field(this, _st.field, placeholder) +, _field(this, _st.field, std::move(placeholder)) , _cancel(this, _st.fieldCancel) { _field->customUpDown(true); connect(_field, SIGNAL(focused()), this, SLOT(onFieldFocused())); diff --git a/Telegram/SourceFiles/ui/widgets/multi_select.h b/Telegram/SourceFiles/ui/widgets/multi_select.h index 8c86ed2b8..7724362e1 100644 --- a/Telegram/SourceFiles/ui/widgets/multi_select.h +++ b/Telegram/SourceFiles/ui/widgets/multi_select.h @@ -30,7 +30,7 @@ class ScrollArea; class MultiSelect : public TWidget { public: - MultiSelect(QWidget *parent, const style::MultiSelect &st, const QString &placeholder = QString()); + MultiSelect(QWidget *parent, const style::MultiSelect &st, base::lambda placeholderFactory = base::lambda()); QString getQuery() const; void setInnerFocus(); @@ -82,7 +82,7 @@ class MultiSelect::Inner : public TWidget { public: using ScrollCallback = base::lambda; - Inner(QWidget *parent, const style::MultiSelect &st, const QString &placeholder, ScrollCallback callback); + Inner(QWidget *parent, const style::MultiSelect &st, base::lambda placeholderFactory, ScrollCallback callback); QString getQuery() const; bool setInnerFocus(); diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index a53eba58f..276aee7b3 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -486,7 +486,9 @@ Notification::Notification(Manager *manager, History *history, PeerData *peer, P , _started(GetTickCount()) #endif // Q_OS_WIN , _close(this, st::notifyClose) -, _reply(this, lang(lng_notification_reply), st::defaultBoxButton) { +, _reply(this, langFactory(lng_notification_reply), st::defaultBoxButton) { + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); + auto position = computePosition(st::notifyMinHeight); updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight); @@ -507,7 +509,7 @@ Notification::Notification(Manager *manager, History *history, PeerData *peer, P showReplyField(); }); _replyPadding = st::notifyMinHeight - st::notifyPhotoPos.y() - st::notifyPhotoSize; - _reply->moveToRight(_replyPadding, height() - _reply->height() - _replyPadding); + updateReplyGeometry(); _reply->hide(); prepareActionsCache(); @@ -528,6 +530,14 @@ Notification::Notification(Manager *manager, History *history, PeerData *peer, P show(); } +void Notification::updateReplyGeometry() { + _reply->moveToRight(_replyPadding, height() - _reply->height() - _replyPadding); +} + +void Notification::refreshLang() { + InvokeQueued(this, [this] { updateReplyGeometry(); }); +} + void Notification::prepareActionsCache() { auto replyCache = myGrab(_reply); auto fadeWidth = st::notifyFadeRight.width(); @@ -743,7 +753,7 @@ void Notification::showReplyField() { _background->setGeometry(0, st::notifyMinHeight, width(), st::notifySendReply.height + st::notifyBorderWidth); _background->show(); - _replyArea.create(this, st::notifyReplyArea, lang(lng_message_ph), QString()); + _replyArea.create(this, st::notifyReplyArea, langFactory(lng_message_ph), QString()); _replyArea->resize(width() - st::notifySendReply.width - 2 * st::notifyBorderWidth, st::notifySendReply.height); _replyArea->moveToLeft(st::notifyBorderWidth, st::notifyMinHeight); _replyArea->show(); diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index 800b7c139..34bdc4e49 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -220,6 +220,8 @@ private slots: void onReplyCancel(); private: + void refreshLang(); + void updateReplyGeometry(); bool canReply() const; void unlinkHistoryInManager(); diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor.cpp index fc1b6993a..0d0437fbe 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor.cpp @@ -581,10 +581,10 @@ ThemeExportBox::ThemeExportBox(QWidget*, const QByteArray &paletteContent, const } void ThemeExportBox::prepare() { - setTitle(lang(lng_theme_editor_background_image)); + setTitle(langFactory(lng_theme_editor_background_image)); - addButton(lang(lng_theme_editor_export), [this] { exportTheme(); }); - addButton(lang(lng_cancel), [this] { closeBox(); }); + addButton(langFactory(lng_theme_editor_export), [this] { exportTheme(); }); + addButton(langFactory(lng_cancel), [this] { closeBox(); }); auto height = st::settingsSmallSkip + st::settingsBackgroundSize + st::settingsSmallSkip + _tileBackground->height(); @@ -704,7 +704,7 @@ void ThemeExportBox::exportTheme() { Editor::Editor(QWidget*, const QString &path) : _scroll(this, st::settingsScroll) , _close(this, st::contactsMultiSelect.fieldCancel) -, _select(this, st::contactsMultiSelect, lang(lng_country_ph)) +, _select(this, st::contactsMultiSelect, langFactory(lng_country_ph)) , _leftShadow(this) , _topShadow(this) , _export(this, lang(lng_theme_editor_export_button).toUpper(), st::dialogsUpdateButton) { diff --git a/Telegram/SourceFiles/window/themes/window_theme_warning.cpp b/Telegram/SourceFiles/window/themes/window_theme_warning.cpp index 35db9b554..aa2feba2f 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_warning.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_warning.cpp @@ -36,8 +36,8 @@ constexpr int kWaitBeforeRevertMs = 15999; WarningWidget::WarningWidget(QWidget *parent) : TWidget(parent) , _secondsLeft(kWaitBeforeRevertMs / 1000) -, _keepChanges(this, lang(lng_theme_keep_changes), st::defaultBoxButton) -, _revert(this, lang(lng_theme_revert), st::defaultBoxButton) { +, _keepChanges(this, langFactory(lng_theme_keep_changes), st::defaultBoxButton) +, _revert(this, langFactory(lng_theme_revert), st::defaultBoxButton) { _keepChanges->setClickedCallback([] { Window::Theme::KeepApplied(); }); _revert->setClickedCallback([] { Window::Theme::Revert(); }); _timer.setTimeoutHandler([this] { handleTimer(); }); @@ -85,10 +85,18 @@ void WarningWidget::paintEvent(QPaintEvent *e) { void WarningWidget::resizeEvent(QResizeEvent *e) { _inner = QRect((width() - st::themeWarningWidth) / 2, (height() - st::themeWarningHeight) / 2, st::themeWarningWidth, st::themeWarningHeight); _outer = _inner.marginsAdded(st::boxRoundShadow.extend); + updateControlsGeometry(); + update(); +} + +void WarningWidget::updateControlsGeometry() { auto left = _inner.x() + _inner.width() - st::boxButtonPadding.right() - _keepChanges->width(); _keepChanges->moveToLeft(left, _inner.y() + _inner.height() - st::boxButtonPadding.bottom() - _keepChanges->height()); _revert->moveToLeft(left - st::boxButtonPadding.left() - _revert->width(), _keepChanges->y()); - update(); +} + +void WarningWidget::refreshLang() { + InvokeQueued(this, [this] { updateControlsGeometry(); }); } void WarningWidget::handleTimer() { diff --git a/Telegram/SourceFiles/window/themes/window_theme_warning.h b/Telegram/SourceFiles/window/themes/window_theme_warning.h index f634b6924..ae450d715 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_warning.h +++ b/Telegram/SourceFiles/window/themes/window_theme_warning.h @@ -44,6 +44,8 @@ protected: void resizeEvent(QResizeEvent *e) override; private: + void refreshLang(); + void updateControlsGeometry(); void setSecondsLeft(int secondsLeft); void startAnimation(bool hiding); void updateText(); diff --git a/Telegram/SourceFiles/window/top_bar_widget.cpp b/Telegram/SourceFiles/window/top_bar_widget.cpp index f916a63ab..537bc54d0 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.cpp +++ b/Telegram/SourceFiles/window/top_bar_widget.cpp @@ -39,14 +39,16 @@ namespace Window { TopBarWidget::TopBarWidget(QWidget *parent, gsl::not_null controller) : TWidget(parent) , _controller(controller) -, _clearSelection(this, lang(lng_selected_clear), st::topBarClearButton) -, _forward(this, lang(lng_selected_forward), st::defaultActiveButton) -, _delete(this, lang(lng_selected_delete), st::defaultActiveButton) +, _clearSelection(this, langFactory(lng_selected_clear), st::topBarClearButton) +, _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton) +, _delete(this, langFactory(lng_selected_delete), st::defaultActiveButton) , _info(this, nullptr, st::topBarInfoButton) -, _mediaType(this, lang(lng_media_type), st::topBarButton) +, _mediaType(this, langFactory(lng_media_type), st::topBarButton) , _call(this, st::topBarCall) , _search(this, st::topBarSearch) , _menuToggle(this, st::topBarMenuToggle) { + subscribe(Lang::Current().updated(), [this] { refreshLang(); }); + _forward->setClickedCallback([this] { onForwardSelection(); }); _forward->setWidthChangedCallback([this] { updateControlsGeometry(); }); _delete->setClickedCallback([this] { onDeleteSelection(); }); @@ -89,6 +91,10 @@ TopBarWidget::TopBarWidget(QWidget *parent, gsl::not_null c updateControlsVisibility(); } +void TopBarWidget::refreshLang() { + InvokeQueued(this, [this] { updateControlsGeometry(); }); +} + void TopBarWidget::onForwardSelection() { if (App::main()) App::main()->forwardSelectedItems(); } diff --git a/Telegram/SourceFiles/window/top_bar_widget.h b/Telegram/SourceFiles/window/top_bar_widget.h index 3b43715dc..d2ba6fa65 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.h +++ b/Telegram/SourceFiles/window/top_bar_widget.h @@ -65,6 +65,7 @@ signals: void clicked(); private: + void refreshLang(); void updateControlsGeometry(); void selectedShowCallback();