mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Retranslate Settings when language is changed.
Also suggest user to change language from 'en' to his for one time.
This commit is contained in:
parent
f5dfeb0c50
commit
3f0b57ec11
17 changed files with 183 additions and 59 deletions
|
@ -87,9 +87,9 @@ void LanguageBox::Inner::languageChanged(int languageIndex) {
|
|||
}
|
||||
|
||||
void LanguageBox::prepare() {
|
||||
refreshLangItems();
|
||||
refreshLang();
|
||||
subscribe(Lang::Current().updated(), [this] {
|
||||
refreshLangItems();
|
||||
refreshLang();
|
||||
});
|
||||
|
||||
_inner = setInnerWidget(object_ptr<Inner>(this, &_languages), st::boxLayerScroll);
|
||||
|
@ -100,7 +100,7 @@ void LanguageBox::prepare() {
|
|||
});
|
||||
}
|
||||
|
||||
void LanguageBox::refreshLangItems() {
|
||||
void LanguageBox::refreshLang() {
|
||||
clearButtons();
|
||||
addButton(lang(lng_box_ok), [this] { closeBox(); });
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ private:
|
|||
|
||||
void refresh();
|
||||
void refreshLanguages();
|
||||
void refreshLangItems();
|
||||
void refreshLang();
|
||||
|
||||
Languages _languages;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "messenger.h"
|
||||
#include "apiwrap.h"
|
||||
#include "auth_session.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
|
||||
namespace Lang {
|
||||
|
||||
|
@ -35,12 +36,11 @@ CloudManager::CloudManager(Instance &langpack, gsl::not_null<MTP::Instance*> mtp
|
|||
}
|
||||
|
||||
void CloudManager::requestLangPackDifference() {
|
||||
auto &langpack = Lang::Current();
|
||||
if (langpack.isCustom() || _langPackRequestId) {
|
||||
if (_langpack.isCustom() || _langPackRequestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto version = langpack.version();
|
||||
auto version = _langpack.version();
|
||||
if (version > 0) {
|
||||
_langPackRequestId = request(MTPlangpack_GetDifference(MTP_int(version))).done([this](const MTPLangPackDifference &result) {
|
||||
_langPackRequestId = 0;
|
||||
|
@ -60,24 +60,24 @@ void CloudManager::requestLangPackDifference() {
|
|||
|
||||
void CloudManager::applyLangPackDifference(const MTPLangPackDifference &difference) {
|
||||
Expects(difference.type() == mtpc_langPackDifference);
|
||||
auto ¤t = Lang::Current();
|
||||
if (current.isCustom()) {
|
||||
if (_langpack.isCustom()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &langpack = difference.c_langPackDifference();
|
||||
switchLangPackId(qs(langpack.vlang_code));
|
||||
if (current.version() < langpack.vfrom_version.v) {
|
||||
requestLangPackDifference();
|
||||
} else if (!langpack.vstrings.v.isEmpty()) {
|
||||
current.applyDifference(langpack);
|
||||
Local::writeLangPack();
|
||||
auto fullLangPackUpdated = (langpack.vfrom_version.v == 0);
|
||||
if (fullLangPackUpdated) {
|
||||
Lang::Current().updated().notify();
|
||||
auto langpackId = qs(langpack.vlang_code);
|
||||
if (needToApplyLangPack(langpackId)) {
|
||||
applyLangPackData(langpack);
|
||||
} else if (_langpack.id().isEmpty()) {
|
||||
_offerSwitchToId = langpackId;
|
||||
if (langpack.vfrom_version.v == 0) {
|
||||
_offerSwitchToData = std::make_unique<MTPLangPackDifference>(difference);
|
||||
} else {
|
||||
_offerSwitchToData.reset();
|
||||
}
|
||||
offerSwitchLangPack();
|
||||
} else {
|
||||
LOG(("Lang Info: Up to date."));
|
||||
LOG(("Lang Warning: Ignoring update for '%1' because our language is '%2'").arg(langpackId).arg(_langpack.id()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,21 +99,98 @@ void CloudManager::requestLanguageList() {
|
|||
}).send();
|
||||
}
|
||||
|
||||
bool CloudManager::needToApplyLangPack(const QString &id) {
|
||||
auto currentId = _langpack.id();
|
||||
if (currentId == id) {
|
||||
return true;
|
||||
} else if (currentId.isEmpty() && id == DefaultLanguageId()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CloudManager::offerSwitchLangPack() {
|
||||
Expects(!_offerSwitchToId.isEmpty());
|
||||
Expects(_offerSwitchToId != DefaultLanguageId());
|
||||
|
||||
if (!showOfferSwitchBox()) {
|
||||
subscribe(languageListChanged(), [this] {
|
||||
showOfferSwitchBox();
|
||||
});
|
||||
requestLanguageList();
|
||||
}
|
||||
}
|
||||
|
||||
QString CloudManager::findOfferedLanguageName() {
|
||||
for_const (auto &language, _languages) {
|
||||
if (language.id == _offerSwitchToId) {
|
||||
return language.name;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool CloudManager::showOfferSwitchBox() {
|
||||
auto name = findOfferedLanguageName();
|
||||
if (name.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Ui::show(Box<ConfirmBox>("Do you want to switch your language to " + name + "? You can always change your language in Settings.", "Change", lang(lng_cancel), [this] {
|
||||
Ui::hideLayer();
|
||||
if (_offerSwitchToId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (_offerSwitchToData) {
|
||||
t_assert(_offerSwitchToData->type() == mtpc_langPackDifference);
|
||||
applyLangPackData(base::take(_offerSwitchToData)->c_langPackDifference());
|
||||
} else {
|
||||
switchToLanguage(_offerSwitchToId);
|
||||
}
|
||||
}, [this] {
|
||||
Ui::hideLayer();
|
||||
changeIdAndReInitConnection(DefaultLanguageId());
|
||||
Local::writeLangPack();
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CloudManager::applyLangPackData(const MTPDlangPackDifference &data) {
|
||||
switchLangPackId(qs(data.vlang_code));
|
||||
if (_langpack.version() < data.vfrom_version.v) {
|
||||
requestLangPackDifference();
|
||||
} 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."));
|
||||
}
|
||||
}
|
||||
|
||||
void CloudManager::switchToLanguage(const QString &id) {
|
||||
switchLangPackId(id);
|
||||
requestLangPackDifference();
|
||||
}
|
||||
|
||||
void CloudManager::switchLangPackId(const QString &id) {
|
||||
auto ¤t = Lang::Current();
|
||||
if (current.id() != id) {
|
||||
current.switchToId(id);
|
||||
|
||||
auto mtproto = requestMTP();
|
||||
mtproto->reInitConnection(mtproto->mainDcId());
|
||||
auto currentId = _langpack.id();
|
||||
auto notChanged = (currentId == id) || (currentId.isEmpty() && id == DefaultLanguageId());
|
||||
if (!notChanged) {
|
||||
changeIdAndReInitConnection(id);
|
||||
}
|
||||
}
|
||||
|
||||
void CloudManager::changeIdAndReInitConnection(const QString &id) {
|
||||
_langpack.switchToId(id);
|
||||
|
||||
auto mtproto = requestMTP();
|
||||
mtproto->reInitConnection(mtproto->mainDcId());
|
||||
}
|
||||
|
||||
CloudManager &CurrentCloudManager() {
|
||||
auto result = Messenger::Instance().langCloudManager();
|
||||
t_assert(result != nullptr);
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Lang {
|
|||
|
||||
class Instance;
|
||||
|
||||
class CloudManager : private MTP::Sender {
|
||||
class CloudManager : private MTP::Sender, private base::Subscriber {
|
||||
public:
|
||||
CloudManager(Instance &langpack, gsl::not_null<MTP::Instance*> mtproto);
|
||||
|
||||
|
@ -53,8 +53,14 @@ public:
|
|||
void switchToLanguage(const QString &id);
|
||||
|
||||
private:
|
||||
void applyLangPack(const MTPUpdates &updates);
|
||||
void offerSwitchLangPack();
|
||||
bool showOfferSwitchBox();
|
||||
QString findOfferedLanguageName();
|
||||
|
||||
bool needToApplyLangPack(const QString &id);
|
||||
void applyLangPackData(const MTPDlangPackDifference &data);
|
||||
void switchLangPackId(const QString &id);
|
||||
void changeIdAndReInitConnection(const QString &id);
|
||||
|
||||
Instance &_langpack;
|
||||
Languages _languages;
|
||||
|
@ -62,6 +68,9 @@ private:
|
|||
mtpRequestId _langPackRequestId = 0;
|
||||
mtpRequestId _languagesRequestId = 0;
|
||||
|
||||
QString _offerSwitchToId;
|
||||
std::unique_ptr<MTPLangPackDifference> _offerSwitchToData;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator==(const CloudManager::Language &a, const CloudManager::Language &b) {
|
||||
|
|
|
@ -230,6 +230,10 @@ bool ValueParser::parse() {
|
|||
|
||||
} // namespace
|
||||
|
||||
QString DefaultLanguageId() {
|
||||
return str_const_toString(kDefaultLanguage);
|
||||
}
|
||||
|
||||
void Instance::switchToId(const QString &id) {
|
||||
reset();
|
||||
_id = id;
|
||||
|
@ -260,16 +264,12 @@ void Instance::fillDefaults() {
|
|||
}
|
||||
}
|
||||
|
||||
QString Instance::DefaultLanguageId() {
|
||||
return str_const_toString(kDefaultLanguage);
|
||||
}
|
||||
|
||||
QString Instance::cloudLangCode() const {
|
||||
if (isCustom() || id().isEmpty()) {
|
||||
if (_systemLanguage.isEmpty()) {
|
||||
_systemLanguage = Platform::SystemLanguage();
|
||||
if (_systemLanguage.isEmpty()) {
|
||||
_systemLanguage = Instance::DefaultLanguageId();
|
||||
_systemLanguage = DefaultLanguageId();
|
||||
}
|
||||
}
|
||||
return _systemLanguage;
|
||||
|
@ -410,7 +410,9 @@ void Instance::fillFromLegacy(int legacyId, const QString &legacyPath) {
|
|||
}
|
||||
|
||||
void Instance::applyDifference(const MTPDlangPackDifference &difference) {
|
||||
Expects(qs(difference.vlang_code) == _id);
|
||||
auto updateLanguageId = qs(difference.vlang_code);
|
||||
auto isValidUpdate = (updateLanguageId == _id) || (_id.isEmpty() && updateLanguageId == DefaultLanguageId());
|
||||
Expects(isValidUpdate);
|
||||
Expects(difference.vfrom_version.v <= _version);
|
||||
|
||||
_version = difference.vversion.v;
|
||||
|
|
|
@ -28,6 +28,11 @@ constexpr auto kLegacyLanguageNone = -2;
|
|||
constexpr auto kLegacyCustomLanguage = -1;
|
||||
constexpr auto kLegacyDefaultLanguage = 0;
|
||||
|
||||
QString DefaultLanguageId();
|
||||
|
||||
class Instance;
|
||||
Instance &Current();
|
||||
|
||||
class Instance {
|
||||
public:
|
||||
Instance() {
|
||||
|
@ -41,7 +46,6 @@ public:
|
|||
Instance(Instance &&other) = default;
|
||||
Instance &operator=(Instance &&other) = default;
|
||||
|
||||
static QString DefaultLanguageId();
|
||||
QString cloudLangCode() const;
|
||||
|
||||
QString id() const {
|
||||
|
@ -93,6 +97,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
Instance &Current();
|
||||
|
||||
} // namespace Lang
|
||||
|
|
|
@ -5690,11 +5690,11 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
|||
////// Cloud langpacks
|
||||
case mtpc_updateLangPack: {
|
||||
auto &langpack = update.c_updateLangPack();
|
||||
Messenger::Instance().langCloudManager()->applyLangPackDifference(langpack.vdifference);
|
||||
Lang::CurrentCloudManager().applyLangPackDifference(langpack.vdifference);
|
||||
} break;
|
||||
|
||||
case mtpc_updateLangPackTooLong: {
|
||||
Messenger::Instance().langCloudManager()->requestLangPackDifference();
|
||||
Lang::CurrentCloudManager().requestLangPackDifference();
|
||||
} break;
|
||||
|
||||
}
|
||||
|
|
|
@ -43,10 +43,6 @@ LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &t
|
|||
connect(_link, SIGNAL(clicked()), parent, slot);
|
||||
}
|
||||
|
||||
void LabeledLink::setLink(const QString &text) {
|
||||
_link.create(this, text);
|
||||
}
|
||||
|
||||
Ui::LinkButton *LabeledLink::link() const {
|
||||
return _link;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@ public:
|
|||
};
|
||||
LabeledLink(QWidget *parent, const QString &label, const QString &text, Type type, const char *slot);
|
||||
|
||||
void setLink(const QString &text);
|
||||
|
||||
Ui::LinkButton *link() const;
|
||||
|
||||
int naturalWidth() const override;
|
||||
|
|
|
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#include "settings/settings_inner_widget.h"
|
||||
|
||||
#include "lang/lang_instance.h"
|
||||
#include "styles/style_settings.h"
|
||||
#include "settings/settings_cover.h"
|
||||
#include "settings/settings_block_widget.h"
|
||||
|
@ -37,10 +38,11 @@ namespace Settings {
|
|||
InnerWidget::InnerWidget(QWidget *parent) : LayerInner(parent)
|
||||
, _self(App::self()) {
|
||||
refreshBlocks();
|
||||
subscribe(Global::RefSelfChanged(), [this]() { selfUpdated(); });
|
||||
subscribe(Global::RefSelfChanged(), [this] { fullRebuild(); });
|
||||
subscribe(Lang::Current().updated(), [this] { fullRebuild(); });
|
||||
}
|
||||
|
||||
void InnerWidget::selfUpdated() {
|
||||
void InnerWidget::fullRebuild() {
|
||||
_self = App::self();
|
||||
refreshBlocks();
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ protected:
|
|||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
void selfUpdated();
|
||||
void fullRebuild();
|
||||
void refreshBlocks();
|
||||
|
||||
// Returns the new height value.
|
||||
|
|
|
@ -37,7 +37,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
namespace Settings {
|
||||
|
||||
LocalPasscodeState::LocalPasscodeState(QWidget *parent) : TWidget(parent)
|
||||
, _edit(this, lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on), st::boxLinkButton)
|
||||
, _edit(this, GetEditPasscodeText(), st::boxLinkButton)
|
||||
, _turnOff(this, lang(lng_passcode_turn_off), st::boxLinkButton) {
|
||||
updateControls();
|
||||
connect(_edit, SIGNAL(clicked()), this, SLOT(onEdit()));
|
||||
|
@ -60,11 +60,15 @@ void LocalPasscodeState::onTurnOff() {
|
|||
}
|
||||
|
||||
void LocalPasscodeState::updateControls() {
|
||||
_edit->setText(lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on));
|
||||
_edit->setText(GetEditPasscodeText());
|
||||
_edit->moveToLeft(0, 0);
|
||||
_turnOff->setVisible(Global::LocalPasscode());
|
||||
}
|
||||
|
||||
QString LocalPasscodeState::GetEditPasscodeText() {
|
||||
return lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on);
|
||||
}
|
||||
|
||||
CloudPasswordState::CloudPasswordState(QWidget *parent) : TWidget(parent)
|
||||
, _edit(this, lang(lng_cloud_password_set), st::boxLinkButton)
|
||||
, _turnOff(this, lang(lng_passcode_turn_off), st::boxLinkButton) {
|
||||
|
@ -169,6 +173,10 @@ PrivacyWidget::PrivacyWidget(QWidget *parent, UserData *self) : BlockWidget(pare
|
|||
subscribe(Global::RefLocalPasscodeChanged(), [this]() { autoLockUpdated(); });
|
||||
}
|
||||
|
||||
QString PrivacyWidget::GetAutoLockText() {
|
||||
return (Global::AutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, Global::AutoLock() / 60) : lng_passcode_autolock_hours(lt_count, Global::AutoLock() / 3600);
|
||||
}
|
||||
|
||||
void PrivacyWidget::createControls() {
|
||||
style::margins marginSmall(0, 0, 0, st::settingsSmallSkip);
|
||||
style::margins marginSkip(0, 0, 0, st::settingsSkip);
|
||||
|
@ -180,7 +188,7 @@ void PrivacyWidget::createControls() {
|
|||
addChildRow(_groupsInvitePrivacy, marginSmall, lang(lng_settings_groups_invite_privacy), SLOT(onGroupsInvitePrivacy()));
|
||||
addChildRow(_localPasscodeState, marginSmall);
|
||||
auto label = lang(psIdleSupported() ? lng_passcode_autolock_away : lng_passcode_autolock_inactive);
|
||||
auto value = (Global::AutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, Global::AutoLock() / 60) : lng_passcode_autolock_hours(lt_count, Global::AutoLock() / 3600);
|
||||
auto value = GetAutoLockText();
|
||||
addChildRow(_autoLock, marginSmall, slidedPadding, label, value, LabeledLink::Type::Primary, SLOT(onAutoLock()));
|
||||
if (!Global::LocalPasscode()) {
|
||||
_autoLock->hideFast();
|
||||
|
@ -192,7 +200,7 @@ void PrivacyWidget::createControls() {
|
|||
|
||||
void PrivacyWidget::autoLockUpdated() {
|
||||
if (Global::LocalPasscode()) {
|
||||
auto value = (Global::AutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, Global::AutoLock() / 60) : lng_passcode_autolock_hours(lt_count, Global::AutoLock() / 3600);
|
||||
auto value = GetAutoLockText();
|
||||
_autoLock->entity()->link()->setText(value);
|
||||
resizeToWidth(width());
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ private slots:
|
|||
void onTurnOff();
|
||||
|
||||
private:
|
||||
static QString GetEditPasscodeText();
|
||||
|
||||
void updateControls();
|
||||
|
||||
object_ptr<Ui::LinkButton> _edit;
|
||||
|
@ -94,6 +96,8 @@ private slots:
|
|||
void onSelfDestruction();
|
||||
|
||||
private:
|
||||
static QString GetAutoLockText();
|
||||
|
||||
void createControls();
|
||||
void autoLockUpdated();
|
||||
|
||||
|
|
|
@ -197,13 +197,23 @@ void codesFeedString(const QString &text) {
|
|||
} // namespace
|
||||
|
||||
Widget::Widget(QWidget *parent) {
|
||||
setTitle(lang(lng_menu_settings));
|
||||
refreshLang();
|
||||
subscribe(Lang::Current().updated(), [this] {
|
||||
refreshLang();
|
||||
});
|
||||
|
||||
_inner = setInnerWidget(object_ptr<InnerWidget>(this));
|
||||
setCloseClickHandler([]() {
|
||||
Ui::hideSettingsAndLayer();
|
||||
});
|
||||
}
|
||||
|
||||
void Widget::refreshLang() {
|
||||
setTitle(lang(lng_menu_settings));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void Widget::showFinished() {
|
||||
_inner->showFinished();
|
||||
}
|
||||
|
|
|
@ -26,12 +26,14 @@ namespace Settings {
|
|||
|
||||
class InnerWidget;
|
||||
|
||||
class Widget : public Layer {
|
||||
class Widget : public Layer, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Widget(QWidget*);
|
||||
|
||||
void refreshLang();
|
||||
|
||||
void showFinished() override;
|
||||
void parentResized() override;
|
||||
|
||||
|
|
|
@ -39,22 +39,32 @@ Checkbox::Checkbox(QWidget *parent, const QString &text, bool checked, const sty
|
|||
, _st(st)
|
||||
, _text(_st.style, text, _checkboxOptions)
|
||||
, _checked(checked) {
|
||||
if (_st.width <= 0) {
|
||||
resizeToWidth(_text.maxWidth() - _st.width);
|
||||
} else {
|
||||
resizeToWidth(_st.width);
|
||||
}
|
||||
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
|
||||
resizeToText();
|
||||
|
||||
connect(this, SIGNAL(clicked()), this, SLOT(onClicked()));
|
||||
|
||||
setCursor(style::cur_pointer);
|
||||
}
|
||||
|
||||
void Checkbox::setText(const QString &text) {
|
||||
_text.setText(_st.style, text, _checkboxOptions);
|
||||
resizeToText();
|
||||
update();
|
||||
}
|
||||
|
||||
bool Checkbox::checked() const {
|
||||
return _checked;
|
||||
}
|
||||
|
||||
void Checkbox::resizeToText() {
|
||||
if (_st.width <= 0) {
|
||||
resizeToWidth(_text.maxWidth() - _st.width);
|
||||
} else {
|
||||
resizeToWidth(_st.width);
|
||||
}
|
||||
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
|
||||
}
|
||||
|
||||
void Checkbox::setChecked(bool checked, NotifyAboutChange notify) {
|
||||
if (_checked != checked) {
|
||||
_checked = checked;
|
||||
|
|
|
@ -31,6 +31,8 @@ class Checkbox : public RippleButton {
|
|||
public:
|
||||
Checkbox(QWidget *parent, const QString &text, bool checked = false, const style::Checkbox &st = st::defaultCheckbox);
|
||||
|
||||
void setText(const QString &text);
|
||||
|
||||
bool checked() const;
|
||||
enum class NotifyAboutChange {
|
||||
Notify,
|
||||
|
@ -61,6 +63,8 @@ signals:
|
|||
void changed();
|
||||
|
||||
private:
|
||||
void resizeToText();
|
||||
|
||||
const style::Checkbox &_st;
|
||||
|
||||
Text _text;
|
||||
|
|
Loading…
Add table
Reference in a new issue