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

View File

@ -78,11 +78,13 @@ private slots:
private:
void updateCallText();
void refreshLang();
void updateControlsGeometry();
void codeSubmitDone(const MTPauth_Authorization &result);
bool codeSubmitFail(const RPCError &error);
void showCodeError(const QString &text);
void showCodeError(base::lambda<QString()> textFactory);
void callDone(const MTPauth_SentCode &v);
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(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
setTitleText(lang(lng_phone_title));
setDescriptionText(lang(lng_phone_desc));
setTitleText([] { return lang(lng_phone_title); });
setDescriptionText([] { return lang(lng_phone_desc); });
subscribe(getData()->updated, [this] { countryChanged(); });
setErrorCentered(true);
@ -76,9 +76,9 @@ void PhoneWidget::updateSignupGeometry() {
}
}
void PhoneWidget::showPhoneError(const QString &text) {
void PhoneWidget::showPhoneError(base::lambda<QString()> textFactory) {
_phone->showError();
showError(text);
showError(std::move(textFactory));
}
void PhoneWidget::hidePhoneError() {
@ -90,7 +90,7 @@ void PhoneWidget::hidePhoneError() {
}
void PhoneWidget::showSignup() {
showPhoneError(lang(lng_bad_phone_noreg));
showPhoneError([] { return lang(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<Ui::FlatLabel>(this, signupText, Ui::FlatLabel::InitType::Rich, st::introDescription);
@ -121,7 +121,7 @@ void PhoneWidget::submit() {
if (_sentRequest || isHidden()) return;
if (!App::isValidPhone(fullNumber())) {
showPhoneError(lang(lng_bad_phone));
showPhoneError([] { return lang(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(lang(lng_server_error));
showPhoneError([] { return lang(lng_server_error); });
return;
}
@ -203,7 +203,7 @@ bool PhoneWidget::phoneSubmitFail(const RPCError &error) {
if (MTP::isFloodError(error)) {
stopCheck();
_sentRequest = 0;
showPhoneError(lang(lng_flood_error));
showPhoneError([] { return lang(lng_flood_error); });
return true;
}
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)));
return true;
} else if (err == qstr("PHONE_NUMBER_INVALID")) { // show error
showPhoneError(lang(lng_bad_phone));
showPhoneError([] { return lang(lng_bad_phone); });
return true;
}
if (cDebug()) { // internal server error
showPhoneError(err + ": " + error.description());
auto text = err + ": " + error.description();
showPhoneError([text] { return text; });
} else {
showPhoneError(lang(lng_server_error));
showPhoneError([] { return lang(lng_server_error); });
}
return false;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -230,6 +230,21 @@ bool ValueParser::parse() {
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
QString DefaultLanguageId() {
@ -239,6 +254,12 @@ QString DefaultLanguageId() {
void Instance::switchToId(const QString &id) {
reset();
_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() {
@ -263,7 +284,7 @@ void Instance::switchToCustomFile(const QString &filePath) {
reset();
fillFromCustomFile(filePath);
Local::writeLangPack();
updated().notify();
_updated.notify();
}
void Instance::reset() {
@ -488,6 +509,7 @@ void Instance::applyDifference(const MTPDlangPackDifference &difference) {
resetValue(key);
});
}
_updated.notify();
}
std::map<LangKey, QString> Instance::ParseStrings(const MTPVector<MTPLangPackString> &strings) {

View File

@ -55,7 +55,7 @@ public:
return _id;
}
bool isCustom() const {
return id() == qstr("custom");
return (_id == qstr("custom") || _id == qstr("TEST_X") || _id == qstr("TEST_0"));
}
int version() const {
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/buttons.h"
#include "base/zlib_help.h"
#include "lang/lang_cloud_manager.h"
#include "lang/lang_instance.h"
#include "lang/lang_keys.h"
#include "shortcuts.h"
#include "messenger.h"
@ -54,6 +56,29 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "auth_session.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)
, _reconnect(this, QString()) {
set(text, reconnect);
@ -568,8 +593,13 @@ void MainWindow::setInnerFocus() {
bool MainWindow::eventFilter(QObject *object, QEvent *e) {
switch (e->type()) {
case QEvent::MouseButtonPress:
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::Wheel:
psUserActionDone();

View File

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

View File

@ -1621,6 +1621,11 @@ void FlatInput::resizeEvent(QResizeEvent *e) {
return QLineEdit::resizeEvent(e);
}
void FlatInput::setPlaceholder(const QString &ph) {
_fullph = ph;
updatePlaceholderText();
}
void FlatInput::updatePlaceholderText() {
int32 availw = width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1;
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() {
setErrorShown(true);
if (!hasFocus()) {
@ -3222,6 +3233,12 @@ void InputField::createPlaceholderPath() {
}
}
void InputField::setPlaceholder(const QString &ph) {
_placeholderFull = ph;
createPlaceholderPath();
update();
}
void InputField::showError() {
setErrorShown(true);
if (!hasFocus()) {
@ -3505,6 +3522,12 @@ void MaskedInputField::createPlaceholderPath() {
}
}
void MaskedInputField::setPlaceholder(const QString &ph) {
_placeholderFull = ph;
createPlaceholderPath();
update();
}
void MaskedInputField::contextMenuEvent(QContextMenuEvent *e) {
if (auto menu = createStandardContextMenu()) {
(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());
void updatePlaceholder();
void setPlaceholder(const QString &ph);
const QString &placeholder() const;
QRect placeholderRect() const;
@ -325,6 +326,7 @@ public:
const QString &getLastText() const {
return _oldtext;
}
void setPlaceholder(const QString &ph);
void setDisplayFocused(bool focused);
void finishAnimations();
void setFocusFast() {
@ -503,6 +505,7 @@ public:
const QString &getLastText() const {
return _oldtext;
}
void setPlaceholder(const QString &ph);
void setPlaceholderHidden(bool forcePlaceholderHidden);
void setDisplayFocused(bool focused);
void finishAnimations();
@ -689,6 +692,7 @@ public:
const QString &getLastText() const {
return _oldtext;
}
void setPlaceholder(const QString &ph);
void setPlaceholderHidden(bool forcePlaceholderHidden);
void setDisplayFocused(bool focused);
void finishAnimations();