Realtime UI translation in Intro.

Also support realtime translation testing by F7-F6-F7-F8 keys.
This commit is contained in:
John Preston 2017-05-30 16:54:05 +03:00
parent d47a38dfcf
commit 5fc4f4ed36
18 changed files with 266 additions and 89 deletions

View File

@ -88,6 +88,8 @@ CodeWidget::CodeWidget(QWidget *parent, Widget::Data *data) : Step(parent, data)
, _callTimeout(getData()->callTimeout) , _callTimeout(getData()->callTimeout)
, _callLabel(this, st::introDescription) , _callLabel(this, st::introDescription)
, _checkRequest(this) { , _checkRequest(this) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
connect(_code, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_code, SIGNAL(changed()), this, SLOT(onInputChange()));
connect(_callTimer, SIGNAL(timeout()), this, SLOT(onSendCall())); connect(_callTimer, SIGNAL(timeout()), this, SLOT(onSendCall()));
connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest())); connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
@ -96,12 +98,19 @@ CodeWidget::CodeWidget(QWidget *parent, Widget::Data *data) : Step(parent, data)
_code->setDigitsCountMax(getData()->codeLength); _code->setDigitsCountMax(getData()->codeLength);
setErrorBelowLink(true); setErrorBelowLink(true);
setTitleText(App::formatPhone(getData()->phone)); setTitleText([text = App::formatPhone(getData()->phone)] { return text; });
updateDescText(); updateDescText();
} }
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() { void CodeWidget::updateDescText() {
setDescriptionText(lang(getData()->codeByTelegram ? lng_code_telegram : lng_code_desc)); setDescriptionText([byTelegram = getData()->codeByTelegram] { return lang(byTelegram ? lng_code_telegram : lng_code_desc); });
if (getData()->codeByTelegram) { if (getData()->codeByTelegram) {
_noTelegramCode->show(); _noTelegramCode->show();
_callTimer->stop(); _callTimer->stop();
@ -140,15 +149,19 @@ void CodeWidget::updateCallText() {
void CodeWidget::resizeEvent(QResizeEvent *e) { void CodeWidget::resizeEvent(QResizeEvent *e) {
Step::resizeEvent(e); Step::resizeEvent(e);
updateControlsGeometry();
}
void CodeWidget::updateControlsGeometry() {
_code->moveToLeft(contentLeft(), contentTop() + st::introStepFieldTop); _code->moveToLeft(contentLeft(), contentTop() + st::introStepFieldTop);
auto linkTop = _code->y() + _code->height() + st::introLinkTop; auto linkTop = _code->y() + _code->height() + st::introLinkTop;
_noTelegramCode->moveToLeft(contentLeft() + st::buttonRadius, linkTop); _noTelegramCode->moveToLeft(contentLeft() + st::buttonRadius, linkTop);
_callLabel->moveToLeft(contentLeft() + st::buttonRadius, linkTop); _callLabel->moveToLeft(contentLeft() + st::buttonRadius, linkTop);
} }
void CodeWidget::showCodeError(const QString &text) { void CodeWidget::showCodeError(base::lambda<QString()> textFactory) {
if (!text.isEmpty()) _code->showError(); if (textFactory) _code->showError();
showError(text); showError(std::move(textFactory));
} }
void CodeWidget::setInnerFocus() { void CodeWidget::setInnerFocus() {
@ -208,7 +221,7 @@ void CodeWidget::codeSubmitDone(const MTPauth_Authorization &result) {
_sentRequest = 0; _sentRequest = 0;
auto &d = result.c_auth_authorization(); auto &d = result.c_auth_authorization();
if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf? if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf?
showCodeError(lang(lng_server_error)); showCodeError([] { return lang(lng_server_error); });
return; return;
} }
cSetLoggedPhoneNumber(getData()->phone); cSetLoggedPhoneNumber(getData()->phone);
@ -219,7 +232,7 @@ bool CodeWidget::codeSubmitFail(const RPCError &error) {
if (MTP::isFloodError(error)) { if (MTP::isFloodError(error)) {
stopCheck(); stopCheck();
_sentRequest = 0; _sentRequest = 0;
showCodeError(lang(lng_flood_error)); showCodeError([] { return lang(lng_flood_error); });
return true; return true;
} }
if (MTP::isDefaultHandledError(error)) return false; if (MTP::isDefaultHandledError(error)) return false;
@ -231,7 +244,7 @@ bool CodeWidget::codeSubmitFail(const RPCError &error) {
goBack(); goBack();
return true; return true;
} else if (err == qstr("PHONE_CODE_EMPTY") || err == qstr("PHONE_CODE_INVALID")) { } else if (err == qstr("PHONE_CODE_EMPTY") || err == qstr("PHONE_CODE_INVALID")) {
showCodeError(lang(lng_bad_code)); showCodeError([] { return lang(lng_bad_code); });
return true; return true;
} else if (err == qstr("PHONE_NUMBER_UNOCCUPIED")) { // success, need to signUp } else if (err == qstr("PHONE_NUMBER_UNOCCUPIED")) { // success, need to signUp
getData()->code = _sentCode; getData()->code = _sentCode;
@ -244,9 +257,10 @@ bool CodeWidget::codeSubmitFail(const RPCError &error) {
return true; return true;
} }
if (cDebug()) { // internal server error if (cDebug()) { // internal server error
showCodeError(err + ": " + error.description()); auto text = err + ": " + error.description();
showCodeError([text] { return text; });
} else { } else {
showCodeError(lang(lng_server_error)); showCodeError([] { return lang(lng_server_error); });
} }
return false; return false;
} }
@ -324,7 +338,7 @@ void CodeWidget::onNoTelegramCode() {
void CodeWidget::noTelegramCodeDone(const MTPauth_SentCode &result) { void CodeWidget::noTelegramCodeDone(const MTPauth_SentCode &result) {
if (result.type() != mtpc_auth_sentCode) { if (result.type() != mtpc_auth_sentCode) {
showCodeError(lang(lng_server_error)); showCodeError([] { return lang(lng_server_error); });
return; return;
} }
@ -344,15 +358,16 @@ void CodeWidget::noTelegramCodeDone(const MTPauth_SentCode &result) {
bool CodeWidget::noTelegramCodeFail(const RPCError &error) { bool CodeWidget::noTelegramCodeFail(const RPCError &error) {
if (MTP::isFloodError(error)) { if (MTP::isFloodError(error)) {
showCodeError(lang(lng_flood_error)); showCodeError([] { return lang(lng_flood_error); });
return true; return true;
} }
if (MTP::isDefaultHandledError(error)) return false; if (MTP::isDefaultHandledError(error)) return false;
if (cDebug()) { // internal server error if (cDebug()) { // internal server error
showCodeError(error.type() + ": " + error.description()); auto text = error.type() + ": " + error.description();
showCodeError([text] { return text; });
} else { } else {
showCodeError(lang(lng_server_error)); showCodeError([] { return lang(lng_server_error); });
} }
return false; return false;
} }

View File

@ -78,11 +78,13 @@ private slots:
private: private:
void updateCallText(); void updateCallText();
void refreshLang();
void updateControlsGeometry();
void codeSubmitDone(const MTPauth_Authorization &result); void codeSubmitDone(const MTPauth_Authorization &result);
bool codeSubmitFail(const RPCError &error); bool codeSubmitFail(const RPCError &error);
void showCodeError(const QString &text); void showCodeError(base::lambda<QString()> textFactory);
void callDone(const MTPauth_SentCode &v); void callDone(const MTPauth_SentCode &v);
void gotPassword(const MTPaccount_Password &result); void gotPassword(const MTPaccount_Password &result);

View File

@ -48,8 +48,8 @@ PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, dat
connect(_code, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_code, SIGNAL(changed()), this, SLOT(onInputChange()));
connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest())); connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
setTitleText(lang(lng_phone_title)); setTitleText([] { return lang(lng_phone_title); });
setDescriptionText(lang(lng_phone_desc)); setDescriptionText([] { return lang(lng_phone_desc); });
subscribe(getData()->updated, [this] { countryChanged(); }); subscribe(getData()->updated, [this] { countryChanged(); });
setErrorCentered(true); setErrorCentered(true);
@ -76,9 +76,9 @@ void PhoneWidget::updateSignupGeometry() {
} }
} }
void PhoneWidget::showPhoneError(const QString &text) { void PhoneWidget::showPhoneError(base::lambda<QString()> textFactory) {
_phone->showError(); _phone->showError();
showError(text); showError(std::move(textFactory));
} }
void PhoneWidget::hidePhoneError() { void PhoneWidget::hidePhoneError() {
@ -90,7 +90,7 @@ void PhoneWidget::hidePhoneError() {
} }
void PhoneWidget::showSignup() { void PhoneWidget::showSignup() {
showPhoneError(lang(lng_bad_phone_noreg)); showPhoneError([] { return lang(lng_bad_phone_noreg); });
if (!_signup) { 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 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<Ui::FlatLabel>(this, signupText, Ui::FlatLabel::InitType::Rich, st::introDescription); auto inner = object_ptr<Ui::FlatLabel>(this, signupText, Ui::FlatLabel::InitType::Rich, st::introDescription);
@ -121,7 +121,7 @@ void PhoneWidget::submit() {
if (_sentRequest || isHidden()) return; if (_sentRequest || isHidden()) return;
if (!App::isValidPhone(fullNumber())) { if (!App::isValidPhone(fullNumber())) {
showPhoneError(lang(lng_bad_phone)); showPhoneError([] { return lang(lng_bad_phone); });
_phone->setFocus(); _phone->setFocus();
return; return;
} }
@ -172,7 +172,7 @@ void PhoneWidget::phoneSubmitDone(const MTPauth_SentCode &result) {
_sentRequest = 0; _sentRequest = 0;
if (result.type() != mtpc_auth_sentCode) { if (result.type() != mtpc_auth_sentCode) {
showPhoneError(lang(lng_server_error)); showPhoneError([] { return lang(lng_server_error); });
return; return;
} }
@ -203,7 +203,7 @@ bool PhoneWidget::phoneSubmitFail(const RPCError &error) {
if (MTP::isFloodError(error)) { if (MTP::isFloodError(error)) {
stopCheck(); stopCheck();
_sentRequest = 0; _sentRequest = 0;
showPhoneError(lang(lng_flood_error)); showPhoneError([] { return lang(lng_flood_error); });
return true; return true;
} }
if (MTP::isDefaultHandledError(error)) return false; if (MTP::isDefaultHandledError(error)) return false;
@ -215,13 +215,14 @@ bool PhoneWidget::phoneSubmitFail(const RPCError &error) {
Ui::show(Box<InformBox>(lang(lng_error_phone_flood))); Ui::show(Box<InformBox>(lang(lng_error_phone_flood)));
return true; return true;
} else if (err == qstr("PHONE_NUMBER_INVALID")) { // show error } else if (err == qstr("PHONE_NUMBER_INVALID")) { // show error
showPhoneError(lang(lng_bad_phone)); showPhoneError([] { return lang(lng_bad_phone); });
return true; return true;
} }
if (cDebug()) { // internal server error if (cDebug()) { // internal server error
showPhoneError(err + ": " + error.description()); auto text = err + ": " + error.description();
showPhoneError([text] { return text; });
} else { } else {
showPhoneError(lang(lng_server_error)); showPhoneError([] { return lang(lng_server_error); });
} }
return false; return false;
} }

View File

@ -53,6 +53,10 @@ public:
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
bool hasChangeLanguageNoCover() const override {
return true;
}
private slots: private slots:
void onInputChange(); void onInputChange();
void onCheckRequest(); void onCheckRequest();
@ -70,7 +74,7 @@ private:
QString fullNumber() const; QString fullNumber() const;
void stopCheck(); void stopCheck();
void showPhoneError(const QString &text); void showPhoneError(base::lambda<QString()> textFactory);
void hidePhoneError(); void hidePhoneError();
void showSignup(); void showSignup();

View File

@ -43,13 +43,15 @@ PwdCheckWidget::PwdCheckWidget(QWidget *parent, Widget::Data *data) : Step(paren
, _toRecover(this, lang(lng_signin_recover)) , _toRecover(this, lang(lng_signin_recover))
, _toPassword(this, lang(lng_signin_try_password)) , _toPassword(this, lang(lng_signin_try_password))
, _checkRequest(this) { , _checkRequest(this) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest())); connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
connect(_toRecover, SIGNAL(clicked()), this, SLOT(onToRecover())); connect(_toRecover, SIGNAL(clicked()), this, SLOT(onToRecover()));
connect(_toPassword, SIGNAL(clicked()), this, SLOT(onToPassword())); connect(_toPassword, SIGNAL(clicked()), this, SLOT(onToPassword()));
connect(_pwdField, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_pwdField, SIGNAL(changed()), this, SLOT(onInputChange()));
connect(_codeField, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_codeField, SIGNAL(changed()), this, SLOT(onInputChange()));
setTitleText(lang(lng_signin_title)); setTitleText([] { return lang(lng_signin_title); });
updateDescriptionText(); updateDescriptionText();
setErrorBelowLink(true); setErrorBelowLink(true);
@ -64,8 +66,20 @@ PwdCheckWidget::PwdCheckWidget(QWidget *parent, Widget::Data *data) : Step(paren
setMouseTracking(true); setMouseTracking(true);
} }
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();
}
void PwdCheckWidget::resizeEvent(QResizeEvent *e) { void PwdCheckWidget::resizeEvent(QResizeEvent *e) {
Step::resizeEvent(e); Step::resizeEvent(e);
updateControlsGeometry();
}
void PwdCheckWidget::updateControlsGeometry() {
_pwdField->moveToLeft(contentLeft(), contentTop() + st::introPasswordTop); _pwdField->moveToLeft(contentLeft(), contentTop() + st::introPasswordTop);
_pwdHint->moveToLeft(contentLeft() + st::buttonRadius, contentTop() + st::introPasswordHintTop); _pwdHint->moveToLeft(contentLeft() + st::buttonRadius, contentTop() + st::introPasswordHintTop);
_codeField->moveToLeft(contentLeft(), contentTop() + st::introStepFieldTop); _codeField->moveToLeft(contentLeft(), contentTop() + st::introStepFieldTop);
@ -121,7 +135,7 @@ void PwdCheckWidget::pwdSubmitDone(bool recover, const MTPauth_Authorization &re
} }
auto &d = result.c_auth_authorization(); auto &d = result.c_auth_authorization();
if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf? if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf?
showError(lang(lng_server_error)); showError([] { return lang(lng_server_error); });
return; return;
} }
finish(d.vuser); finish(d.vuser);
@ -131,7 +145,7 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) {
if (MTP::isFloodError(error)) { if (MTP::isFloodError(error)) {
_sentRequest = 0; _sentRequest = 0;
stopCheck(); stopCheck();
showError(lang(lng_flood_error)); showError([] { return lang(lng_flood_error); });
_pwdField->showError(); _pwdField->showError();
return true; return true;
} }
@ -141,7 +155,7 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) {
stopCheck(); stopCheck();
auto &err = error.type(); auto &err = error.type();
if (err == qstr("PASSWORD_HASH_INVALID")) { if (err == qstr("PASSWORD_HASH_INVALID")) {
showError(lang(lng_signin_bad_password)); showError([] { return lang(lng_signin_bad_password); });
_pwdField->selectAll(); _pwdField->selectAll();
_pwdField->showError(); _pwdField->showError();
return true; return true;
@ -149,9 +163,10 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) {
goBack(); goBack();
} }
if (cDebug()) { // internal server error if (cDebug()) { // internal server error
showError(err + ": " + error.description()); auto text = err + ": " + error.description();
showError([text] { return text; });
} else { } else {
showError(lang(lng_server_error)); showError([] { return lang(lng_server_error); });
} }
_pwdField->setFocus(); _pwdField->setFocus();
return false; return false;
@ -159,7 +174,7 @@ bool PwdCheckWidget::pwdSubmitFail(const RPCError &error) {
bool PwdCheckWidget::codeSubmitFail(const RPCError &error) { bool PwdCheckWidget::codeSubmitFail(const RPCError &error) {
if (MTP::isFloodError(error)) { if (MTP::isFloodError(error)) {
showError(lang(lng_flood_error)); showError([] { return lang(lng_flood_error); });
_codeField->showError(); _codeField->showError();
return true; return true;
} }
@ -179,15 +194,16 @@ bool PwdCheckWidget::codeSubmitFail(const RPCError &error) {
onToPassword(); onToPassword();
return true; return true;
} else if (err == qstr("CODE_INVALID")) { } else if (err == qstr("CODE_INVALID")) {
showError(lang(lng_signin_wrong_code)); showError([] { return lang(lng_signin_wrong_code); });
_codeField->selectAll(); _codeField->selectAll();
_codeField->showError(); _codeField->showError();
return true; return true;
} }
if (cDebug()) { // internal server error if (cDebug()) { // internal server error
showError(err + ": " + error.description()); auto text = err + ": " + error.description();
showError([text] { return text; });
} else { } else {
showError(lang(lng_server_error)); showError([] { return lang(lng_server_error); });
} }
_codeField->setFocus(); _codeField->setFocus();
return false; return false;
@ -253,7 +269,11 @@ void PwdCheckWidget::showReset() {
} }
void PwdCheckWidget::updateDescriptionText() { void PwdCheckWidget::updateDescriptionText() {
setDescriptionText(_pwdField->isHidden() ? lng_signin_recover_desc(lt_email, _emailPattern) : lang(lng_signin_desc)); auto pwdHidden = _pwdField->isHidden();
auto emailPattern = _emailPattern;
setDescriptionText([pwdHidden, emailPattern] {
return pwdHidden ? lng_signin_recover_desc(lt_email, emailPattern) : lang(lng_signin_desc);
});
} }
void PwdCheckWidget::onInputChange() { void PwdCheckWidget::onInputChange() {

View File

@ -54,6 +54,8 @@ private slots:
private: private:
void showReset(); void showReset();
void refreshLang();
void updateControlsGeometry();
void pwdSubmitDone(bool recover, const MTPauth_Authorization &result); void pwdSubmitDone(bool recover, const MTPauth_Authorization &result);
bool pwdSubmitFail(const RPCError &error); bool pwdSubmitFail(const RPCError &error);

View File

@ -40,6 +40,8 @@ SignupWidget::SignupWidget(QWidget *parent, Widget::Data *data) : Step(parent, d
, _last(this, st::introName, lang(lng_signup_lastname)) , _last(this, st::introName, lang(lng_signup_lastname))
, _invertOrder(langFirstNameGoesSecond()) , _invertOrder(langFirstNameGoesSecond())
, _checkRequest(this) { , _checkRequest(this) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest())); connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
setupPhotoButton(); setupPhotoButton();
@ -49,11 +51,17 @@ SignupWidget::SignupWidget(QWidget *parent, Widget::Data *data) : Step(parent, d
} }
setErrorCentered(true); setErrorCentered(true);
setTitleText(lang(lng_signup_title)); setTitleText([] { return lang(lng_signup_title); });
setDescriptionText(lang(lng_signup_desc)); setDescriptionText([] { return lang(lng_signup_desc); });
setMouseTracking(true); setMouseTracking(true);
} }
void SignupWidget::refreshLang() {
_first->setPlaceholder(lang(lng_signup_firstname));
_last->setPlaceholder(lang(lng_signup_lastname));
updateControlsGeometry();
}
void SignupWidget::setupPhotoButton() { void SignupWidget::setupPhotoButton() {
_photo->setClickedCallback(App::LambdaDelayed(st::defaultActiveButton.ripple.hideDuration, this, [this] { _photo->setClickedCallback(App::LambdaDelayed(st::defaultActiveButton.ripple.hideDuration, this, [this] {
auto imgExtensions = cImgExtensions(); auto imgExtensions = cImgExtensions();
@ -71,7 +79,7 @@ void SignupWidget::setupPhotoButton() {
} }
if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) { if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) {
showError(lang(lng_bad_photo)); showError([] { return lang(lng_bad_photo); });
return; return;
} }
auto box = Ui::show(Box<PhotoCropBox>(img, PeerId(0))); auto box = Ui::show(Box<PhotoCropBox>(img, PeerId(0)));
@ -82,7 +90,10 @@ void SignupWidget::setupPhotoButton() {
void SignupWidget::resizeEvent(QResizeEvent *e) { void SignupWidget::resizeEvent(QResizeEvent *e) {
Step::resizeEvent(e); Step::resizeEvent(e);
updateControlsGeometry();
}
void SignupWidget::updateControlsGeometry() {
auto photoRight = contentLeft() + st::introNextButton.width; auto photoRight = contentLeft() + st::introNextButton.width;
auto photoTop = contentTop() + st::introPhotoTop; auto photoTop = contentTop() + st::introPhotoTop;
_photo->moveToLeft(photoRight - _photo->width(), photoTop); _photo->moveToLeft(photoRight - _photo->width(), photoTop);
@ -144,7 +155,7 @@ void SignupWidget::nameSubmitDone(const MTPauth_Authorization &result) {
stopCheck(); stopCheck();
auto &d = result.c_auth_authorization(); auto &d = result.c_auth_authorization();
if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf? if (d.vuser.type() != mtpc_user || !d.vuser.c_user().is_self()) { // wtf?
showError(lang(lng_server_error)); showError([] { return lang(lng_server_error); });
return; return;
} }
finish(d.vuser, _photoImage); finish(d.vuser, _photoImage);
@ -153,7 +164,7 @@ void SignupWidget::nameSubmitDone(const MTPauth_Authorization &result) {
bool SignupWidget::nameSubmitFail(const RPCError &error) { bool SignupWidget::nameSubmitFail(const RPCError &error) {
if (MTP::isFloodError(error)) { if (MTP::isFloodError(error)) {
stopCheck(); stopCheck();
showError(lang(lng_flood_error)); showError([] { return lang(lng_flood_error); });
if (_invertOrder) { if (_invertOrder) {
_first->setFocus(); _first->setFocus();
} else { } else {
@ -174,18 +185,19 @@ bool SignupWidget::nameSubmitFail(const RPCError &error) {
goBack(); goBack();
return true; return true;
} else if (err == "FIRSTNAME_INVALID") { } else if (err == "FIRSTNAME_INVALID") {
showError(lang(lng_bad_name)); showError([] { return lang(lng_bad_name); });
_first->setFocus(); _first->setFocus();
return true; return true;
} else if (err == "LASTNAME_INVALID") { } else if (err == "LASTNAME_INVALID") {
showError(lang(lng_bad_name)); showError([] { return lang(lng_bad_name); });
_last->setFocus(); _last->setFocus();
return true; return true;
} }
if (cDebug()) { // internal server error if (cDebug()) { // internal server error
showError(err + ": " + error.description()); auto text = err + ": " + error.description();
showError([text] { return text; });
} else { } else {
showError(lang(lng_server_error)); showError([] { return lang(lng_server_error); });
} }
if (_invertOrder) { if (_invertOrder) {
_last->setFocus(); _last->setFocus();
@ -196,7 +208,7 @@ bool SignupWidget::nameSubmitFail(const RPCError &error) {
} }
void SignupWidget::onInputChange() { void SignupWidget::onInputChange() {
showError(QString()); hideError();
} }
void SignupWidget::submit() { void SignupWidget::submit() {
@ -219,7 +231,7 @@ void SignupWidget::submit() {
} }
} }
showError(QString()); hideError();
_firstName = _first->getLastText().trimmed(); _firstName = _first->getLastText().trimmed();
_lastName = _last->getLastText().trimmed(); _lastName = _last->getLastText().trimmed();

View File

@ -52,6 +52,8 @@ private slots:
private: private:
void setupPhotoButton(); void setupPhotoButton();
void refreshLang();
void updateControlsGeometry();
void nameSubmitDone(const MTPauth_Authorization &result); void nameSubmitDone(const MTPauth_Authorization &result);
bool nameSubmitFail(const RPCError &error); bool nameSubmitFail(const RPCError &error);

View File

@ -30,8 +30,8 @@ namespace Intro {
StartWidget::StartWidget(QWidget *parent, Widget::Data *data) : Step(parent, data, true) { StartWidget::StartWidget(QWidget *parent, Widget::Data *data) : Step(parent, data, true) {
setMouseTracking(true); setMouseTracking(true);
setTitleText(qsl("Telegram Desktop")); setTitleText([] { return qsl("Telegram Desktop"); });
setDescriptionText(lang(lng_intro_about)); setDescriptionText([] { return lang(lng_intro_about); });
show(); show();
} }

View File

@ -71,14 +71,17 @@ Widget::Widget(QWidget *parent) : TWidget(parent)
_settings->entity()->setClickedCallback([] { App::wnd()->showSettings(); }); _settings->entity()->setClickedCallback([] { App::wnd()->showSettings(); });
subscribe(Lang::CurrentCloudManager().firstLanguageSuggestion(), [this] { createLanguageLink(); });
createLanguageLink();
getNearestDC(); getNearestDC();
appendStep(new StartWidget(this, getData())); appendStep(new StartWidget(this, getData()));
fixOrder(); fixOrder();
subscribe(Lang::CurrentCloudManager().firstLanguageSuggestion(), [this] { createLanguageLink(); });
createLanguageLink();
if (_changeLanguage) _changeLanguage->finishAnimation();
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
show(); show();
showControls(); showControls();
getStep()->showFast(); getStep()->showFast();
@ -94,14 +97,26 @@ Widget::Widget(QWidget *parent) : TWidget(parent)
#endif // !TDESKTOP_DISABLE_AUTOUPDATE #endif // !TDESKTOP_DISABLE_AUTOUPDATE
} }
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();
}
void Widget::createLanguageLink() { void Widget::createLanguageLink() {
if (_changeLanguage) return; if (_changeLanguage) return;
auto createLink = [this](const QString &text, const QString &languageId) { auto createLink = [this](const QString &text, const QString &languageId) {
_changeLanguage.create(this, object_ptr<Ui::LinkButton>(this, text), st::introCoverDuration); _changeLanguage.create(this, object_ptr<Ui::LinkButton>(this, text), st::introCoverDuration);
_changeLanguage->show();
_changeLanguage->hideFast();
_changeLanguage->entity()->setClickedCallback([this, languageId] { _changeLanguage->entity()->setClickedCallback([this, languageId] {
Lang::CurrentCloudManager().switchToLanguage(languageId); Lang::CurrentCloudManager().switchToLanguage(languageId);
}); });
_changeLanguage->toggleAnimated(getStep()->hasChangeLanguage());
updateControlsGeometry();
}; };
auto currentId = Lang::Current().id(); auto currentId = Lang::Current().id();
@ -124,7 +139,7 @@ void Widget::createLanguageLink() {
void Widget::onCheckUpdateStatus() { void Widget::onCheckUpdateStatus() {
if (Sandbox::updatingState() == Application::UpdatingReady) { if (Sandbox::updatingState() == Application::UpdatingReady) {
if (_update) return; if (_update) return;
_update.create(this, object_ptr<Ui::RoundButton>(this, lang(lng_menu_update).toUpper(), st::defaultBoxButton), st::introCoverDuration); _update.create(this, object_ptr<Ui::RoundButton>(this, lang(lng_menu_update), st::defaultBoxButton), st::introCoverDuration);
if (!_a_show.animating()) _update->show(); if (!_a_show.animating()) _update->show();
_update->entity()->setClickedCallback([] { _update->entity()->setClickedCallback([] {
checkReadyUpdate(); checkReadyUpdate();
@ -176,7 +191,7 @@ void Widget::historyMove(Direction direction) {
auto stepHasCover = getStep()->hasCover(); auto stepHasCover = getStep()->hasCover();
_settings->toggleAnimated(!stepHasCover); _settings->toggleAnimated(!stepHasCover);
if (_update) _update->toggleAnimated(!stepHasCover); if (_update) _update->toggleAnimated(!stepHasCover);
if (_changeLanguage) _changeLanguage->toggleAnimated(stepHasCover); if (_changeLanguage) _changeLanguage->toggleAnimated(getStep()->hasChangeLanguage());
_next->setText(getStep()->nextButtonText()); _next->setText(getStep()->nextButtonText());
if (_resetAccount) _resetAccount->hideAnimated(); if (_resetAccount) _resetAccount->hideAnimated();
getStep()->showAnimated(direction); getStep()->showAnimated(direction);
@ -259,7 +274,7 @@ void Widget::resetAccount() {
Ui::show(Box<InformBox>(lang(lng_signin_reset_cancelled))); Ui::show(Box<InformBox>(lang(lng_signin_reset_cancelled)));
} else { } else {
Ui::hideLayer(); Ui::hideLayer();
getStep()->showError(lang(lng_server_error)); getStep()->showError([] { return lang(lng_server_error); });
} }
}).send(); }).send();
}))); })));
@ -285,7 +300,7 @@ void Widget::showControls() {
auto hasCover = getStep()->hasCover(); auto hasCover = getStep()->hasCover();
_settings->toggleFast(!hasCover); _settings->toggleFast(!hasCover);
if (_update) _update->toggleFast(!hasCover); if (_update) _update->toggleFast(!hasCover);
if (_changeLanguage) _changeLanguage->toggleFast(hasCover); if (_changeLanguage) _changeLanguage->toggleFast(getStep()->hasChangeLanguage());
_back->toggleFast(getStep()->hasBack()); _back->toggleFast(getStep()->hasBack());
} }
@ -372,9 +387,6 @@ void Widget::resizeEvent(QResizeEvent *e) {
updateControlsGeometry(); updateControlsGeometry();
} }
void Widget::moveControls() {
}
void Widget::updateControlsGeometry() { void Widget::updateControlsGeometry() {
auto shown = _coverShownAnimation.current(1.); auto shown = _coverShownAnimation.current(1.);
@ -468,13 +480,30 @@ void Widget::Step::updateLabelsPosition() {
} }
} }
void Widget::Step::setTitleText(QString richText) { void Widget::Step::setTitleText(base::lambda<QString()> richTitleTextFactory) {
_title->setRichText(richText); _titleTextFactory = std::move(richTitleTextFactory);
refreshTitle();
updateLabelsPosition(); updateLabelsPosition();
} }
void Widget::Step::setDescriptionText(QString richText) { void Widget::Step::refreshTitle() {
_description->entity()->setRichText(richText); _title->setRichText(_titleTextFactory());
}
void Widget::Step::setDescriptionText(base::lambda<QString()> richDescriptionTextFactory) {
_descriptionTextFactory = std::move(richDescriptionTextFactory);
refreshDescription();
updateLabelsPosition();
}
void Widget::Step::refreshDescription() {
_description->entity()->setRichText(_descriptionTextFactory());
}
void Widget::Step::refreshLang() {
refreshTitle();
refreshDescription();
refreshError();
updateLabelsPosition(); updateLabelsPosition();
} }
@ -650,16 +679,21 @@ void Widget::Step::setErrorBelowLink(bool below) {
} }
} }
void Widget::Step::showError(const QString &text) { void Widget::Step::showError(base::lambda<QString()> textFactory) {
_errorText = text; _errorTextFactory = std::move(textFactory);
if (_errorText.isEmpty()) { refreshError();
updateLabelsPosition();
}
void Widget::Step::refreshError() {
if (!_errorTextFactory) {
if (_error) _error->hideAnimated(); if (_error) _error->hideAnimated();
} else { } else {
if (!_error) { if (!_error) {
_error.create(this, object_ptr<Ui::FlatLabel>(this, _errorCentered ? st::introErrorCentered : st::introError), st::introErrorDuration); _error.create(this, object_ptr<Ui::FlatLabel>(this, _errorCentered ? st::introErrorCentered : st::introError), st::introErrorDuration);
_error->hideFast(); _error->hideFast();
} }
_error->entity()->setText(text); _error->entity()->setText(_errorTextFactory());
updateLabelsPosition(); updateLabelsPosition();
_error->showAnimated(); _error->showAnimated();
} }
@ -679,6 +713,7 @@ Widget::Step::Step(QWidget *parent, Data *data, bool hasCover) : TWidget(parent)
} }
} }
}); });
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
} }
void Widget::Step::prepareShowAnimated(Step *after) { void Widget::Step::prepareShowAnimated(Step *after) {
@ -755,7 +790,7 @@ bool Widget::Step::hasBack() const {
void Widget::Step::activate() { void Widget::Step::activate() {
_title->show(); _title->show();
_description->show(); _description->show();
if (!_errorText.isEmpty()) { if (_errorTextFactory) {
_error->showFast(); _error->showFast();
} }
} }

View File

@ -111,6 +111,9 @@ public:
bool animating() const; bool animating() const;
bool hasCover() const; bool hasCover() const;
bool hasChangeLanguage() const {
return hasCover() || hasChangeLanguageNoCover();
}
virtual bool hasBack() const; virtual bool hasBack() const;
virtual void activate(); virtual void activate();
virtual void cancelled(); virtual void cancelled();
@ -124,9 +127,9 @@ public:
void setErrorCentered(bool centered); void setErrorCentered(bool centered);
void setErrorBelowLink(bool below); void setErrorBelowLink(bool below);
void showError(const QString &text); void showError(base::lambda<QString()> textFactory);
void hideError() { void hideError() {
showError(QString()); showError(base::lambda<QString()>());
} }
~Step(); ~Step();
@ -135,8 +138,8 @@ public:
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
void setTitleText(QString richText); void setTitleText(base::lambda<QString()> richTitleTextFactory);
void setDescriptionText(QString richText); void setDescriptionText(base::lambda<QString()> richDescriptionTextFactory);
bool paintAnimated(Painter &p, QRect clip); bool paintAnimated(Painter &p, QRect clip);
void fillSentCodeData(const MTPauth_SentCodeType &type); void fillSentCodeData(const MTPauth_SentCodeType &type);
@ -161,6 +164,9 @@ public:
void showResetButton() { void showResetButton() {
if (_showResetCallback) _showResetCallback(); if (_showResetCallback) _showResetCallback();
} }
virtual bool hasChangeLanguageNoCover() const {
return false;
}
private: private:
struct CoverAnimation { struct CoverAnimation {
@ -178,6 +184,10 @@ public:
}; };
void updateLabelsPosition(); void updateLabelsPosition();
void paintContentSnapshot(Painter &p, const QPixmap &snapshot, float64 alpha, float64 howMuchHidden); void paintContentSnapshot(Painter &p, const QPixmap &snapshot, float64 alpha, float64 howMuchHidden);
void refreshError();
void refreshTitle();
void refreshDescription();
void refreshLang();
CoverAnimation prepareCoverAnimation(Step *step); CoverAnimation prepareCoverAnimation(Step *step);
QPixmap prepareContentSnapshot(); QPixmap prepareContentSnapshot();
@ -193,11 +203,13 @@ public:
base::lambda<void()> _showResetCallback; base::lambda<void()> _showResetCallback;
object_ptr<Ui::FlatLabel> _title; object_ptr<Ui::FlatLabel> _title;
base::lambda<QString()> _titleTextFactory;
object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _description; object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _description;
base::lambda<QString()> _descriptionTextFactory;
bool _errorCentered = false; bool _errorCentered = false;
bool _errorBelowLink = false; bool _errorBelowLink = false;
QString _errorText; base::lambda<QString()> _errorTextFactory;
object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _error = { nullptr }; object_ptr<Ui::WidgetFadeWrap<Ui::FlatLabel>> _error = { nullptr };
Animation _a_show; Animation _a_show;
@ -208,6 +220,7 @@ public:
}; };
private: private:
void refreshLang();
void animationCallback(); void animationCallback();
void createLanguageLink(); void createLanguageLink();
@ -219,7 +232,6 @@ private:
void fixOrder(); void fixOrder();
void showControls(); void showControls();
void hideControls(); void hideControls();
void moveControls();
QRect calculateStepRect() const; QRect calculateStepRect() const;
void showResetButton(); void showResetButton();

View File

@ -59,8 +59,7 @@ void CloudManager::requestLangPackDifference() {
} }
void CloudManager::setSuggestedLanguage(const QString &langCode) { void CloudManager::setSuggestedLanguage(const QString &langCode) {
if (_langpack.id().isEmpty() if (!langCode.isEmpty()
&& !langCode.isEmpty()
&& langCode != Lang::DefaultLanguageId()) { && langCode != Lang::DefaultLanguageId()) {
_suggestedLanguage = langCode; _suggestedLanguage = langCode;
} else { } else {
@ -71,7 +70,7 @@ void CloudManager::setSuggestedLanguage(const QString &langCode) {
_languageWasSuggested = true; _languageWasSuggested = true;
_firstLanguageSuggestion.notify(); _firstLanguageSuggestion.notify();
if (AuthSession::Exists() && !_suggestedLanguage.isEmpty()) { if (AuthSession::Exists() && _langpack.id().isEmpty() && !_suggestedLanguage.isEmpty()) {
_offerSwitchToId = _suggestedLanguage; _offerSwitchToId = _suggestedLanguage;
offerSwitchLangPack(); offerSwitchLangPack();
} }
@ -174,10 +173,6 @@ void CloudManager::applyLangPackData(const MTPDlangPackDifference &data) {
} else if (!data.vstrings.v.isEmpty()) { } else if (!data.vstrings.v.isEmpty()) {
_langpack.applyDifference(data); _langpack.applyDifference(data);
Local::writeLangPack(); Local::writeLangPack();
auto fullLangPackUpdated = (data.vfrom_version.v == 0);
if (fullLangPackUpdated) {
_langpack.updated().notify();
}
} else { } else {
LOG(("Lang Info: Up to date.")); LOG(("Lang Info: Up to date."));
} }

View File

@ -230,6 +230,21 @@ bool ValueParser::parse() {
return true; return true;
} }
QString PrepareTestValue(const QString &current, QChar filler) {
auto size = current.size();
auto result = QString(size + 1, filler);
auto inCommand = false;
for (auto i = 0; i != size; ++i) {
auto ch = current[i];
auto newInCommand = (ch.unicode() == TextCommand) ? (!inCommand) : inCommand;
if (inCommand || newInCommand || ch.isSpace()) {
result[i + 1] = ch;
}
inCommand = newInCommand;
}
return result;
}
} // namespace } // namespace
QString DefaultLanguageId() { QString DefaultLanguageId() {
@ -239,6 +254,12 @@ QString DefaultLanguageId() {
void Instance::switchToId(const QString &id) { void Instance::switchToId(const QString &id) {
reset(); reset();
_id = id; _id = id;
if (_id == qstr("TEST_X") || _id == qstr("TEST_0")) {
for (auto &value : _values) {
value = PrepareTestValue(value, _id[5]);
}
_updated.notify();
}
} }
void Instance::chooseCustomFile() { void Instance::chooseCustomFile() {
@ -263,7 +284,7 @@ void Instance::switchToCustomFile(const QString &filePath) {
reset(); reset();
fillFromCustomFile(filePath); fillFromCustomFile(filePath);
Local::writeLangPack(); Local::writeLangPack();
updated().notify(); _updated.notify();
} }
void Instance::reset() { void Instance::reset() {
@ -488,6 +509,7 @@ void Instance::applyDifference(const MTPDlangPackDifference &difference) {
resetValue(key); resetValue(key);
}); });
} }
_updated.notify();
} }
std::map<LangKey, QString> Instance::ParseStrings(const MTPVector<MTPLangPackString> &strings) { std::map<LangKey, QString> Instance::ParseStrings(const MTPVector<MTPLangPackString> &strings) {

View File

@ -55,7 +55,7 @@ public:
return _id; return _id;
} }
bool isCustom() const { bool isCustom() const {
return id() == qstr("custom"); return (_id == qstr("custom") || _id == qstr("TEST_X") || _id == qstr("TEST_0"));
} }
int version() const { int version() const {
return _version; return _version;

View File

@ -27,6 +27,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "base/zlib_help.h" #include "base/zlib_help.h"
#include "lang/lang_cloud_manager.h"
#include "lang/lang_instance.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "messenger.h" #include "messenger.h"
@ -54,6 +56,29 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "auth_session.h" #include "auth_session.h"
#include "window/window_controller.h" #include "window/window_controller.h"
namespace {
// Code for testing languages is F7-F6-F7-F8
void FeedLangTestingKey(int key) {
static auto codeState = 0;
if ((codeState == 0 && key == Qt::Key_F7)
|| (codeState == 1 && key == Qt::Key_F6)
|| (codeState == 2 && key == Qt::Key_F7)
|| (codeState == 3 && key == Qt::Key_F8)) {
++codeState;
} else {
codeState = 0;
}
if (codeState == 4) {
codeState = 0;
auto testLanguageId = (Lang::Current().id() == qstr("TEST_X")) ? qsl("TEST_0") : qsl("TEST_X");
Lang::CurrentCloudManager().switchToLanguage(testLanguageId);
}
}
} // namespace
ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : TWidget(parent) ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : TWidget(parent)
, _reconnect(this, QString()) { , _reconnect(this, QString()) {
set(text, reconnect); set(text, reconnect);
@ -568,8 +593,13 @@ void MainWindow::setInnerFocus() {
bool MainWindow::eventFilter(QObject *object, QEvent *e) { bool MainWindow::eventFilter(QObject *object, QEvent *e) {
switch (e->type()) { switch (e->type()) {
case QEvent::MouseButtonPress:
case QEvent::KeyPress: case QEvent::KeyPress:
if (cDebug() && e->type() == QEvent::KeyPress && object == windowHandle()) {
auto key = static_cast<QKeyEvent*>(e)->key();
FeedLangTestingKey(key);
}
[[fallthrough]];
case QEvent::MouseButtonPress:
case QEvent::TouchBegin: case QEvent::TouchBegin:
case QEvent::Wheel: case QEvent::Wheel:
psUserActionDone(); psUserActionDone();

View File

@ -198,9 +198,7 @@ void codesFeedString(const QString &text) {
Widget::Widget(QWidget *parent) { Widget::Widget(QWidget *parent) {
refreshLang(); refreshLang();
subscribe(Lang::Current().updated(), [this] { subscribe(Lang::Current().updated(), [this] { refreshLang(); });
refreshLang();
});
_inner = setInnerWidget(object_ptr<InnerWidget>(this)); _inner = setInnerWidget(object_ptr<InnerWidget>(this));
setCloseClickHandler([]() { setCloseClickHandler([]() {

View File

@ -1621,6 +1621,11 @@ void FlatInput::resizeEvent(QResizeEvent *e) {
return QLineEdit::resizeEvent(e); return QLineEdit::resizeEvent(e);
} }
void FlatInput::setPlaceholder(const QString &ph) {
_fullph = ph;
updatePlaceholderText();
}
void FlatInput::updatePlaceholderText() { void FlatInput::updatePlaceholderText() {
int32 availw = width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1; int32 availw = width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1;
if (_st.font->width(_fullph) > availw) { if (_st.font->width(_fullph) > availw) {
@ -2464,6 +2469,12 @@ void InputArea::createPlaceholderPath() {
} }
} }
void InputArea::setPlaceholder(const QString &ph) {
_placeholderFull = ph;
createPlaceholderPath();
update();
}
void InputArea::showError() { void InputArea::showError() {
setErrorShown(true); setErrorShown(true);
if (!hasFocus()) { if (!hasFocus()) {
@ -3222,6 +3233,12 @@ void InputField::createPlaceholderPath() {
} }
} }
void InputField::setPlaceholder(const QString &ph) {
_placeholderFull = ph;
createPlaceholderPath();
update();
}
void InputField::showError() { void InputField::showError() {
setErrorShown(true); setErrorShown(true);
if (!hasFocus()) { if (!hasFocus()) {
@ -3505,6 +3522,12 @@ void MaskedInputField::createPlaceholderPath() {
} }
} }
void MaskedInputField::setPlaceholder(const QString &ph) {
_placeholderFull = ph;
createPlaceholderPath();
update();
}
void MaskedInputField::contextMenuEvent(QContextMenuEvent *e) { void MaskedInputField::contextMenuEvent(QContextMenuEvent *e) {
if (auto menu = createStandardContextMenu()) { if (auto menu = createStandardContextMenu()) {
(new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos()); (new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos());

View File

@ -238,6 +238,7 @@ public:
FlatInput(QWidget *parent, const style::FlatInput &st, const QString &ph = QString(), const QString &val = QString()); FlatInput(QWidget *parent, const style::FlatInput &st, const QString &ph = QString(), const QString &val = QString());
void updatePlaceholder(); void updatePlaceholder();
void setPlaceholder(const QString &ph);
const QString &placeholder() const; const QString &placeholder() const;
QRect placeholderRect() const; QRect placeholderRect() const;
@ -325,6 +326,7 @@ public:
const QString &getLastText() const { const QString &getLastText() const {
return _oldtext; return _oldtext;
} }
void setPlaceholder(const QString &ph);
void setDisplayFocused(bool focused); void setDisplayFocused(bool focused);
void finishAnimations(); void finishAnimations();
void setFocusFast() { void setFocusFast() {
@ -503,6 +505,7 @@ public:
const QString &getLastText() const { const QString &getLastText() const {
return _oldtext; return _oldtext;
} }
void setPlaceholder(const QString &ph);
void setPlaceholderHidden(bool forcePlaceholderHidden); void setPlaceholderHidden(bool forcePlaceholderHidden);
void setDisplayFocused(bool focused); void setDisplayFocused(bool focused);
void finishAnimations(); void finishAnimations();
@ -689,6 +692,7 @@ public:
const QString &getLastText() const { const QString &getLastText() const {
return _oldtext; return _oldtext;
} }
void setPlaceholder(const QString &ph);
void setPlaceholderHidden(bool forcePlaceholderHidden); void setPlaceholderHidden(bool forcePlaceholderHidden);
void setDisplayFocused(bool focused); void setDisplayFocused(bool focused);
void finishAnimations(); void finishAnimations();