diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 4e93f0dcb..c06c6e297 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -306,6 +306,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_section_privacy" = "Privacy and Security"; +"lng_local_storage_title" = "Local storage"; "lng_settings_no_data_cached" = "No cached data found!"; "lng_settings_images_cached" = "{count:_not_used_|# image|# images}, {size}"; "lng_settings_audios_cached" = "{count:_not_used_|# voice message|# voice messages}, {size}"; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 90e864638..7bdfb5c8c 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -188,8 +188,9 @@ namespace App { namespace { bool loggedOut() { - if (cHasPasscode()) { - cSetHasPasscode(false); + if (Global::LocalPasscode()) { + Global::SetLocalPasscode(false); + Global::RefLocalPasscodeChanged().notify(); } if (audioPlayer()) { audioPlayer()->stopAndClear(); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 61d2fc6c9..04422b048 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -339,7 +339,9 @@ void Application::closeApplication() { _updateReply = 0; if (_updateChecker) _updateChecker->deleteLater(); _updateChecker = 0; - if (_updateThread) _updateThread->quit(); + if (_updateThread) { + _updateThread->quit(); + } _updateThread = 0; #endif @@ -738,7 +740,8 @@ AppClass::AppClass() : QObject() Local::ReadMapState state = Local::readMap(QByteArray()); if (state == Local::ReadMapPassNeeded) { - cSetHasPasscode(true); + Global::SetLocalPasscode(true); + Global::RefLocalPasscodeChanged().notify(); DEBUG_LOG(("Application Info: passcode needed...")); } else { DEBUG_LOG(("Application Info: local map read...")); diff --git a/Telegram/SourceFiles/autoupdater.h b/Telegram/SourceFiles/autoupdater.h index 3687a405d..a7f27a539 100644 --- a/Telegram/SourceFiles/autoupdater.h +++ b/Telegram/SourceFiles/autoupdater.h @@ -66,11 +66,11 @@ private: bool checkReadyUpdate(); -#else +#else // TDESKTOP_DISABLE_AUTOUPDATE class UpdateChecker : public QObject { Q_OBJECT }; -#endif +#endif // TDESKTOP_DISABLE_AUTOUPDATE QString countBetaVersionSignature(uint64 version); diff --git a/Telegram/SourceFiles/boxes/autolockbox.cpp b/Telegram/SourceFiles/boxes/autolockbox.cpp index acb20f47d..238941a3a 100644 --- a/Telegram/SourceFiles/boxes/autolockbox.cpp +++ b/Telegram/SourceFiles/boxes/autolockbox.cpp @@ -41,7 +41,7 @@ _close(this, lang(lng_box_ok), st::defaultBoxButton) { _options.reserve(cnt); for (int32 i = 0; i < cnt; ++i) { int32 v = opts[i]; - _options.push_back(new Radiobutton(this, qsl("autolock"), v, (v % 3600) ? lng_passcode_autolock_minutes(lt_count, v / 60) : lng_passcode_autolock_hours(lt_count, v / 3600), (cAutoLock() == v), st::langsButton)); + _options.push_back(new Radiobutton(this, qsl("autolock"), v, (v % 3600) ? lng_passcode_autolock_minutes(lt_count, v / 60) : lng_passcode_autolock_hours(lt_count, v / 3600), (Global::AutoLock() == v), st::langsButton)); _options.back()->move(st::boxPadding.left() + st::boxOptionListPadding.left(), y); y += _options.back()->height() + st::boxOptionListPadding.top(); connect(_options.back(), SIGNAL(changed()), this, SLOT(onChange())); @@ -73,8 +73,9 @@ void AutoLockBox::onChange() { for (int32 i = 0, l = _options.size(); i < l; ++i) { int32 v = _options[i]->val(); if (_options[i]->checked()) { - cSetAutoLock(v); + Global::SetAutoLock(v); Local::writeUserSettings(); + Global::RefLocalPasscodeChanged().notify(); } } App::wnd()->checkAutoLock(); diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 69dfca7de..dfeb7adff 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -85,3 +85,5 @@ aboutRevokePublicLabel: flatLabel(labelDefFlat) { width: 320px; textFg: windowTextFg; } + +localStorageBoxSkip: 10px; diff --git a/Telegram/SourceFiles/boxes/localstoragebox.cpp b/Telegram/SourceFiles/boxes/localstoragebox.cpp new file mode 100644 index 000000000..29b3e6279 --- /dev/null +++ b/Telegram/SourceFiles/boxes/localstoragebox.cpp @@ -0,0 +1,131 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "boxes/localstoragebox.h" + +#include "localstorage.h" +#include "ui/flatbutton.h" +#include "lang.h" +#include "styles/style_boxes.h" +#include "mainwindow.h" + +LocalStorageBox::LocalStorageBox() : AbstractBox() +, _clear(this, lang(lng_local_storage_clear), st::defaultBoxLinkButton) +, _close(this, lang(lng_box_ok), st::defaultBoxButton) { + connect(_clear, SIGNAL(clicked()), this, SLOT(onClear())); + connect(_close, SIGNAL(clicked()), this, SLOT(onClose())); + + connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); + connect(App::wnd(), SIGNAL(tempDirCleared(int)), this, SLOT(onTempDirCleared(int))); + connect(App::wnd(), SIGNAL(tempDirClearFailed(int)), this, SLOT(onTempDirClearFailed(int))); + + checkLocalStoredCounts(); + prepare(); +} + +void LocalStorageBox::updateControls() { + int rowsHeight = 0; + if (_imagesCount > 0 && _audiosCount > 0) { + rowsHeight = 2 * (st::linkFont->height + st::localStorageBoxSkip); + } else { + rowsHeight = st::linkFont->height + st::localStorageBoxSkip; + } + _clear->setVisible(_imagesCount > 0 || _audiosCount > 0); + setMaxHeight(st::boxTitleHeight + st::localStorageBoxSkip + rowsHeight + _clear->height() + st::boxButtonPadding.top() + _close->height() + st::boxButtonPadding.bottom()); + _clear->moveToLeft(st::boxPadding.left(), st::boxTitleHeight + st::localStorageBoxSkip + rowsHeight); + _close->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _close->height()); + update(); +} + +void LocalStorageBox::showAll() { + showChildren(); + _clear->setVisible(_imagesCount > 0 || _audiosCount > 0); +} + +void LocalStorageBox::checkLocalStoredCounts() { + int imagesCount = Local::hasImages() + Local::hasStickers() + Local::hasWebFiles(); + int audiosCount = Local::hasAudios(); + if (imagesCount != _imagesCount || audiosCount != _audiosCount) { + _imagesCount = imagesCount; + _audiosCount = audiosCount; + if (_imagesCount > 0 || _audiosCount > 0) { + _state = State::Normal; + } + updateControls(); + } +} + +void LocalStorageBox::paintEvent(QPaintEvent *e) { + Painter p(this); + if (paint(p)) return; + + paintTitle(p, lang(lng_local_storage_title)); + + p.setFont(st::boxTextFont); + p.setPen(st::windowTextFg); + checkLocalStoredCounts(); + int top = st::boxTitleHeight + st::localStorageBoxSkip; + if (_imagesCount > 0) { + auto text = lng_settings_images_cached(lt_count, _imagesCount, lt_size, formatSizeText(Local::storageImagesSize() + Local::storageStickersSize() + Local::storageWebFilesSize())); + p.drawTextLeft(st::boxPadding.left(), top, width(), text); + top += st::boxTextFont->height + st::localStorageBoxSkip; + } + if (_audiosCount > 0) { + auto text = lng_settings_audios_cached(lt_count, _audiosCount, lt_size, formatSizeText(Local::storageAudiosSize())); + p.drawTextLeft(st::boxPadding.left(), top, width(), text); + top += st::boxTextFont->height + st::localStorageBoxSkip; + } else if (_imagesCount <= 0) { + p.drawTextLeft(st::boxPadding.left(), top, width(), lang(lng_settings_no_data_cached)); + top += st::boxTextFont->height + st::localStorageBoxSkip; + } + auto text = ([this]() -> QString { + switch (_state) { + case State::Clearing: return lang(lng_local_storage_clearing); + case State::Cleared: return lang(lng_local_storage_cleared); + case State::ClearFailed: return lang(lng_local_storage_clear_failed); + } + return QString(); + })(); + if (!text.isEmpty()) { + p.drawTextLeft(st::boxPadding.left(), top, width(), text); + top += st::boxTextFont->height + st::localStorageBoxSkip; + } +} + +void LocalStorageBox::onClear() { + App::wnd()->tempDirDelete(Local::ClearManagerStorage); + _state = State::Clearing; + updateControls(); +} + +void LocalStorageBox::onTempDirCleared(int task) { + if (task & Local::ClearManagerStorage) { + _state = State::Cleared; + } + updateControls(); +} + +void LocalStorageBox::onTempDirClearFailed(int task) { + if (task & Local::ClearManagerStorage) { + _state = State::ClearFailed; + } + updateControls(); +} diff --git a/Telegram/SourceFiles/boxes/localstoragebox.h b/Telegram/SourceFiles/boxes/localstoragebox.h new file mode 100644 index 000000000..ef175bfec --- /dev/null +++ b/Telegram/SourceFiles/boxes/localstoragebox.h @@ -0,0 +1,62 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "abstractbox.h" + +class BoxButton; +class LinkButton; + +class LocalStorageBox : public AbstractBox { + Q_OBJECT + +public: + LocalStorageBox(); + +private slots: + void onClear(); + void onTempDirCleared(int task); + void onTempDirClearFailed(int task); + +protected: + void paintEvent(QPaintEvent *e) override; + + void showAll() override; + +private: + void updateControls(); + void checkLocalStoredCounts(); + + enum class State { + Normal, + Clearing, + Cleared, + ClearFailed, + }; + State _state = State::Normal; + + ChildWidget _clear; + ChildWidget _close; + + int _imagesCount = -1; + int _audiosCount = -1; + +}; diff --git a/Telegram/SourceFiles/boxes/passcodebox.cpp b/Telegram/SourceFiles/boxes/passcodebox.cpp index 49ffdf9a1..32ccd9e8a 100644 --- a/Telegram/SourceFiles/boxes/passcodebox.cpp +++ b/Telegram/SourceFiles/boxes/passcodebox.cpp @@ -39,7 +39,7 @@ PasscodeBox::PasscodeBox(bool turningOff) : AbstractBox(st::boxWidth) , _saveButton(this, lang(_turningOff ? lng_passcode_remove_button : lng_settings_save), st::defaultBoxButton) , _cancelButton(this, lang(lng_cancel), st::cancelBoxButton) , _oldPasscode(this, st::defaultInputField, lang(lng_passcode_enter_old)) -, _newPasscode(this, st::defaultInputField, lang(cHasPasscode() ? lng_passcode_enter_new : lng_passcode_enter_first)) +, _newPasscode(this, st::defaultInputField, lang(Global::LocalPasscode() ? lng_passcode_enter_new : lng_passcode_enter_first)) , _reenterPasscode(this, st::defaultInputField, lang(lng_passcode_confirm_new)) , _passwordHint(this, st::defaultInputField, lang(lng_cloud_password_hint)) , _recoverEmail(this, st::defaultInputField, lang(lng_cloud_password_email)) @@ -86,7 +86,7 @@ void PasscodeBox::init() { _boxTitle = lang(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove); setMaxHeight(st::boxTitleHeight + st::passcodePadding.top() + _oldPasscode.height() + st::passcodeSkip + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeSkip : 0) + _aboutHeight + st::passcodePadding.bottom() + st::boxButtonPadding.top() + _saveButton.height() + st::boxButtonPadding.bottom()); } else { - bool has = _cloudPwd ? (!_curSalt.isEmpty()) : cHasPasscode(); + bool has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode(); if (has) { _oldPasscode.show(); _boxTitle = lang(_cloudPwd ? lng_cloud_password_change : lng_passcode_change); @@ -117,7 +117,7 @@ void PasscodeBox::init() { } void PasscodeBox::showAll() { - bool has = _cloudPwd ? (!_curSalt.isEmpty()) : cHasPasscode(); + bool has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode(); if (_turningOff) { _oldPasscode.show(); if (_cloudPwd && _hasRecovery) { @@ -125,9 +125,10 @@ void PasscodeBox::showAll() { } else { _recover.hide(); } - _passwordHint.hide(); _newPasscode.hide(); _reenterPasscode.hide(); + _passwordHint.hide(); + _recoverEmail.hide(); } else { if (has) { _oldPasscode.show(); @@ -159,7 +160,7 @@ void PasscodeBox::showAll() { } void PasscodeBox::onSubmit() { - bool has = _cloudPwd ? (!_curSalt.isEmpty()) : cHasPasscode(); + bool has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode(); if (_oldPasscode.hasFocus()) { if (_turningOff) { onSave(); @@ -230,7 +231,7 @@ void PasscodeBox::paintEvent(QPaintEvent *e) { } void PasscodeBox::resizeEvent(QResizeEvent *e) { - bool has = _cloudPwd ? (!_curSalt.isEmpty()) : cHasPasscode(); + bool has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode(); int32 w = st::boxWidth - st::boxPadding.left() - st::boxPadding.right(); _oldPasscode.resize(w, _oldPasscode.height()); _oldPasscode.moveToLeft(st::boxPadding.left(), st::boxTitleHeight + st::passcodePadding.top()); @@ -323,7 +324,7 @@ void PasscodeBox::onSave(bool force) { if (_setRequest) return; QString old = _oldPasscode.text(), pwd = _newPasscode.text(), conf = _reenterPasscode.text(); - bool has = _cloudPwd ? (!_curSalt.isEmpty()) : cHasPasscode(); + bool has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode(); if (!_cloudPwd && (_turningOff || has)) { if (!passcodeCanTry()) { _oldError = lang(lng_flood_error); diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 567389058..f64038d52 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -653,6 +653,10 @@ struct Data { base::Observable ChooseCustomLang; + int AutoLock = 3600; + bool LocalPasscode = false; + base::Observable LocalPasscodeChanged; + }; } // namespace internal @@ -757,4 +761,8 @@ DefineRefVar(Global, base::Observable, ConnectionTypeChanged); DefineRefVar(Global, base::Observable, ChooseCustomLang); +DefineVar(Global, int, AutoLock); +DefineVar(Global, bool, LocalPasscode); +DefineRefVar(Global, base::Observable, LocalPasscodeChanged); + } // namespace Global diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 217389402..3150fd647 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -318,6 +318,10 @@ DeclareRefVar(base::Observable, ConnectionTypeChanged); DeclareRefVar(base::Observable, ChooseCustomLang); +DeclareVar(int, AutoLock); +DeclareVar(bool, LocalPasscode); +DeclareRefVar(base::Observable, LocalPasscodeChanged); + } // namespace Global namespace Adaptive { diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index fc0121fa2..7dc2cf020 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -1165,7 +1165,8 @@ namespace { stream >> v; if (!_checkStreamStatus(stream)) return false; - cSetAutoLock(v); + Global::SetAutoLock(v); + Global::RefLocalPasscodeChanged().notify(); } break; case dbiReplaceEmojis: { @@ -1569,7 +1570,7 @@ namespace { data.stream << quint32(dbiSendKey) << qint32(cCtrlEnter() ? dbiskCtrlEnter : dbiskEnter); data.stream << quint32(dbiTileBackground) << qint32(Window::chatBackground()->tile() ? 1 : 0); data.stream << quint32(dbiAdaptiveForWide) << qint32(Global::AdaptiveForWide() ? 1 : 0); - data.stream << quint32(dbiAutoLock) << qint32(cAutoLock()); + data.stream << quint32(dbiAutoLock) << qint32(Global::AutoLock()); data.stream << quint32(dbiReplaceEmojis) << qint32(cReplaceEmojis() ? 1 : 0); data.stream << quint32(dbiDefaultAttach) << qint32(cDefaultAttach()); data.stream << quint32(dbiSoundNotify) << qint32(Global::SoundNotify()); @@ -2298,7 +2299,8 @@ namespace Local { _mapChanged = true; _writeMap(WriteMapNow); - cSetHasPasscode(!passcode.isEmpty()); + Global::SetLocalPasscode(!passcode.isEmpty()); + Global::RefLocalPasscodeChanged().notify(); } ReadMapState readMap(const QByteArray &pass) { @@ -4167,11 +4169,22 @@ namespace Local { void ClearManager::start() { moveToThread(data->thread); connect(data->thread, SIGNAL(started()), this, SLOT(onStart())); + connect(data->thread, SIGNAL(finished()), data->thread, SLOT(deleteLater())); + connect(data->thread, SIGNAL(finished()), this, SLOT(deleteLater())); data->thread->start(); } + void ClearManager::stop() { + { + QMutexLocker lock(&data->mutex); + data->tasks.clear(); + } + auto thread = data->thread; + thread->quit(); + thread->wait(); + } + ClearManager::~ClearManager() { - data->thread->deleteLater(); delete data; } @@ -4231,11 +4244,11 @@ namespace Local { } { QMutexLocker lock(&data->mutex); - if (data->tasks.at(0) == task) { + if (!data->tasks.isEmpty() && data->tasks.at(0) == task) { data->tasks.pop_front(); - if (data->tasks.isEmpty()) { - data->working = false; - } + } + if (data->tasks.isEmpty()) { + data->working = false; } if (result) { emit succeed(task, data->working ? 0 : this); diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index ca59fe65b..46a53a177 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -81,16 +81,18 @@ namespace Local { bool addTask(int task); bool hasTask(ClearManagerTask task); void start(); - ~ClearManager(); - - public slots: - void onStart(); + void stop(); signals: void succeed(int task, void *manager); void failed(int task, void *manager); + private slots: + void onStart(); + private: + ~ClearManager(); + ClearManagerData *data; }; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index d84ee853e..99a5e89b1 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -588,10 +588,10 @@ void MainWindow::checkAutoLockIn(int msec) { } void MainWindow::checkAutoLock() { - if (!cHasPasscode() || App::passcoded()) return; + if (!Global::LocalPasscode() || App::passcoded()) return; App::app()->checkLocalTime(); - uint64 ms = getms(true), idle = psIdleTime(), should = cAutoLock() * 1000ULL; + uint64 ms = getms(true), idle = psIdleTime(), should = Global::AutoLock() * 1000ULL; if (idle >= should || (_shouldLockAt > 0 && ms > _shouldLockAt + 3000ULL)) { setupPasscode(true); } else { @@ -608,6 +608,7 @@ void MainWindow::setupIntro(bool anim) { if (_mediaView) { _mediaView->clearData(); } + Ui::hideSettingsAndLayer(true); QPixmap bg = anim ? grabInner() : QPixmap(); @@ -1350,8 +1351,8 @@ void MainWindow::tempDirDelete(int task) { if (_clearManager->addTask(task)) { return; } else { - _clearManager->deleteLater(); - _clearManager = 0; + _clearManager->stop(); + _clearManager = nullptr; } } _clearManager = new Local::ClearManager(); @@ -1363,16 +1364,16 @@ void MainWindow::tempDirDelete(int task) { void MainWindow::onClearFinished(int task, void *manager) { if (manager && manager == _clearManager) { - _clearManager->deleteLater(); - _clearManager = 0; + _clearManager->stop(); + _clearManager = nullptr; } emit tempDirCleared(task); } void MainWindow::onClearFailed(int task, void *manager) { if (manager && manager == _clearManager) { - _clearManager->deleteLater(); - _clearManager = 0; + _clearManager->stop(); + _clearManager = nullptr; } emit tempDirClearFailed(task); } @@ -1918,7 +1919,10 @@ void MainWindow::updateIsActive(int timeout) { MainWindow::~MainWindow() { notifyClearFast(); - delete _clearManager; + if (_clearManager) { + _clearManager->stop(); + _clearManager = nullptr; + } delete _connecting; delete _mediaView; delete trayIcon; diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 3196e7e8a..8b1e9ff71 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -75,9 +75,6 @@ bool gCompressPastedImage = true; QString gTimeFormat = qsl("hh:mm"); -int32 gAutoLock = 3600; -bool gHasPasscode = false; - bool gHasAudioPlayer = true; bool gHasAudioCapture = true; diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index a1edfbe3c..d36815245 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -121,9 +121,6 @@ DeclareSetting(DBIScale, ConfigScale); DeclareSetting(bool, CompressPastedImage); DeclareSetting(QString, TimeFormat); -DeclareSetting(int32, AutoLock); -DeclareSetting(bool, HasPasscode); - DeclareSetting(bool, HasAudioPlayer); DeclareSetting(bool, HasAudioCapture); diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index 90178514f..db2d6d930 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -104,22 +104,25 @@ settingsBlocksTop: 7px; settingsBlocksBottom: 20px; settingsBlockMarginTop: 14px; settingsBlockMarginRight: 10px; -settingsBlockMarginBottom: 16px; +settingsBlockMarginBottom: 10px; settingsBlockTitleHeight: 31px; -settingsBlockTitleFont: font(14px semibold); +settingsBlockTitleFont: font(15px semibold); settingsBlockTitleFg: #333333; settingsBlockTitleTop: 0px; -settingsBlockLabel: flatLabel(labelDefFlat) { +settingsPrimaryLabel: flatLabel(labelDefFlat) { + font: boxTextFont; +} +settingsBlockLabel: flatLabel(settingsPrimaryLabel) { textFg: windowSubTextFg; } -settingsBlockOneLineTextPart: flatLabel(labelDefFlat) { +settingsBlockOneLineTextPart: flatLabel(settingsPrimaryLabel) { width: 0px; // No need to set minWidth in one-line text. margin: margins(5px, 5px, 5px, 5px); maxHeight: 20px; } settingsSubSkip: 4px; settingsSmallSkip: 10px; -settingsSkip: 15px; +settingsSkip: 14px; settingsLargeSkip: 23px; settingsActionPadding: margins(0px, 4px, 0px, 5px); diff --git a/Telegram/SourceFiles/settings/settings_advanced_widget.cpp b/Telegram/SourceFiles/settings/settings_advanced_widget.cpp index 34835e522..e95e5b560 100644 --- a/Telegram/SourceFiles/settings/settings_advanced_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced_widget.cpp @@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "boxes/connectionbox.h" #include "boxes/confirmbox.h" #include "boxes/aboutbox.h" +#include "boxes/localstoragebox.h" #include "mainwindow.h" namespace Settings { @@ -43,14 +44,22 @@ void AdvancedWidget::createControls() { style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); style::margins marginLarge(0, 0, 0, st::settingsLargeSkip); - if (self()) { - addChildRow(_manageLocalStorage, marginSmall, lang(lng_settings_manage_local_storage), SLOT(onManageLocalStorage())); - } + style::margins marginLocalStorage = ([&marginSmall, &marginLarge]() { #ifndef TDESKTOP_DISABLE_NETWORK_PROXY - addChildRow(_connectionType, marginLarge, lang(lng_connection_type), lang(lng_connection_auto_connecting)); - connectionTypeUpdated(); - connect(_connectionType->link(), SIGNAL(clicked()), this, SLOT(onConnectionType())); + return marginSmall; +#else // TDESKTOP_DISABLE_NETWORK_PROXY + return marginLarge; #endif // TDESKTOP_DISABLE_NETWORK_PROXY + })(); + if (self()) { + addChildRow(_manageLocalStorage, marginLocalStorage, lang(lng_settings_manage_local_storage), SLOT(onManageLocalStorage())); + } + +#ifndef TDESKTOP_DISABLE_NETWORK_PROXY + addChildRow(_connectionType, marginLarge, lang(lng_connection_type), lang(lng_connection_auto_connecting), LabeledLink::Type::Primary, SLOT(onConnectionType())); + connectionTypeUpdated(); +#endif // TDESKTOP_DISABLE_NETWORK_PROXY + if (self()) { addChildRow(_askQuestion, marginSmall, lang(lng_settings_ask_question), SLOT(onAskQuestion())); } @@ -61,7 +70,7 @@ void AdvancedWidget::createControls() { } void AdvancedWidget::onManageLocalStorage() { - + Ui::showLayer(new LocalStorageBox()); } #ifndef TDESKTOP_DISABLE_NETWORK_PROXY diff --git a/Telegram/SourceFiles/settings/settings_background_widget.cpp b/Telegram/SourceFiles/settings/settings_background_widget.cpp index 22d7d27a2..61c7cf27f 100644 --- a/Telegram/SourceFiles/settings/settings_background_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_background_widget.cpp @@ -33,8 +33,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Settings { BackgroundRow::BackgroundRow(QWidget *parent) : TWidget(parent) -, _chooseFromGallery(this, lang(lng_settings_bg_from_gallery)) -, _chooseFromFile(this, lang(lng_settings_bg_from_file)) +, _chooseFromGallery(this, lang(lng_settings_bg_from_gallery), st::defaultBoxLinkButton) +, _chooseFromFile(this, lang(lng_settings_bg_from_file), st::defaultBoxLinkButton) , _radial(animation(this, &BackgroundRow::step_radial)) { Window::chatBackground()->initIfEmpty(); @@ -87,8 +87,8 @@ int BackgroundRow::resizeGetHeight(int newWidth) { _chooseFromGallery->resizeToWidth(qMin(linkWidth, _chooseFromGallery->naturalWidth())); _chooseFromFile->resizeToWidth(qMin(linkWidth, _chooseFromFile->naturalWidth())); - _chooseFromGallery->moveToLeft(linkLeft, 0); - _chooseFromFile->moveToLeft(linkLeft, _chooseFromGallery->height() + st::settingsSmallSkip); + _chooseFromGallery->moveToLeft(linkLeft, 0, newWidth); + _chooseFromFile->moveToLeft(linkLeft, _chooseFromGallery->height() + st::settingsSmallSkip, newWidth); return st::settingsBackgroundSize; } diff --git a/Telegram/SourceFiles/settings/settings_block_widget.cpp b/Telegram/SourceFiles/settings/settings_block_widget.cpp index 5dfaab86c..2d143ac84 100644 --- a/Telegram/SourceFiles/settings/settings_block_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_block_widget.cpp @@ -43,10 +43,10 @@ int BlockWidget::resizeGetHeight(int newWidth) { int x = contentLeft(), result = contentTop(); int availw = newWidth - x; for_const (auto &row, _rows) { - row.child->moveToLeft(x + row.margin.left(), result + row.margin.top()); - auto availRowWidth = availw - row.margin.left() - row.margin.right(); + row.child->moveToLeft(x + row.margin.left(), result + row.margin.top(), newWidth); + auto availRowWidth = availw - row.margin.left() - row.margin.right() - x; auto natural = row.child->naturalWidth(); - auto rowWidth = (natural < 0) ? (availRowWidth - x) : qMin(natural, availRowWidth); + auto rowWidth = (natural < 0) ? availRowWidth : qMin(natural, availRowWidth); if (row.child->width() != rowWidth) { row.child->resizeToWidth(rowWidth); } @@ -85,17 +85,17 @@ void BlockWidget::rowHeightUpdated() { } void BlockWidget::createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot, bool checked) { - child = new Checkbox(this, text, checked); + child = new Checkbox(this, text, checked, st::defaultBoxCheckbox); connect(child, SIGNAL(changed()), this, slot); } void BlockWidget::createChildRow(ChildWidget &child, style::margins &margin, const QString &group, int value, const QString &text, const char *slot, bool checked) { - child = new Radiobutton(this, group, value, text, checked); + child = new Radiobutton(this, group, value, text, checked, st::defaultRadiobutton); connect(child, SIGNAL(changed()), this, slot); } -void BlockWidget::createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot) { - child = new LinkButton(this, text); +void BlockWidget::createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot, const style::linkButton &st) { + child = new LinkButton(this, text, st); connect(child, SIGNAL(clicked()), this, slot); } diff --git a/Telegram/SourceFiles/settings/settings_block_widget.h b/Telegram/SourceFiles/settings/settings_block_widget.h index f7c949b00..2118db484 100644 --- a/Telegram/SourceFiles/settings/settings_block_widget.h +++ b/Telegram/SourceFiles/settings/settings_block_widget.h @@ -89,7 +89,7 @@ private: } void createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot, bool checked); void createChildRow(ChildWidget &child, style::margins &margin, const QString &group, int value, const QString &text, const char *slot, bool checked); - void createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot); + void createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot, const style::linkButton &st = st::defaultBoxLinkButton); void addCreatedRow(TWidget *child, const style::margins &margin); void rowHeightUpdated(); diff --git a/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp b/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp index 31ecab39b..53ae1053a 100644 --- a/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp @@ -27,59 +27,19 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/flatlabel.h" #include "localstorage.h" #include "mainwidget.h" +#include "mainwindow.h" #include "boxes/emojibox.h" #include "boxes/stickersetbox.h" #include "boxes/downloadpathbox.h" #include "boxes/connectionbox.h" +#include "boxes/confirmbox.h" namespace Settings { -ChatSettingsWidget::ChatSettingsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_chat_settings)) { - createControls(); - - subscribe(Global::RefDownloadPathChanged(), [this]() { - _downloadPath->entity()->link()->setText(downloadPathText()); - resizeToWidth(width()); - }); -} - -QString ChatSettingsWidget::downloadPathText() const { - if (Global::DownloadPath().isEmpty()) { - return lang(lng_download_path_default); - } else if (Global::DownloadPath() == qsl("tmp")) { - return lang(lng_download_path_temp); - } - return QDir::toNativeSeparators(Global::DownloadPath()); -}; - - -void ChatSettingsWidget::createControls() { - style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); - style::margins marginSkip(0, 0, 0, st::settingsSkip); - style::margins marginSub(0, 0, 0, st::settingsSubSkip); - style::margins slidedPadding(0, marginSub.bottom() / 2, 0, marginSub.bottom() - (marginSub.bottom() / 2)); - - addChildRow(_replaceEmoji, marginSub, lang(lng_settings_replace_emojis), SLOT(onReplaceEmoji()), cReplaceEmojis()); - style::margins marginList(st::defaultCheckbox.textPosition.x(), 0, 0, st::settingsSkip); - addChildRow(_viewList, marginList, slidedPadding, lang(lng_settings_view_emojis), SLOT(onViewList())); - - addChildRow(_dontAskDownloadPath, marginSub, lang(lng_download_path_dont_ask), SLOT(onDontAskDownloadPath()), !Global::AskDownloadPath()); - style::margins marginPath(st::defaultCheckbox.textPosition.x(), 0, 0, st::settingsSkip); - addChildRow(_downloadPath, marginPath, slidedPadding, lang(lng_download_path_label), downloadPathText()); - connect(_downloadPath->entity()->link(), SIGNAL(clicked()), this, SLOT(onDownloadPath())); - if (Global::AskDownloadPath()) { - _downloadPath->hideFast(); - } - - addChildRow(_sendByEnter, marginSmall, qsl("send_key"), 0, lang(lng_settings_send_enter), SLOT(onSendByEnter()), !cCtrlEnter()); - addChildRow(_sendByCtrlEnter, marginSkip, qsl("send_key"), 1, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter), SLOT(onSendByCtrlEnter()), cCtrlEnter()); - addChildRow(_automaticMediaDownloadSettings, marginSmall, lang(lng_media_auto_settings), SLOT(onAutomaticMediaDownloadSettings())); - addChildRow(_manageStickerSets, marginSmall, lang(lng_stickers_you_have), SLOT(onManageStickerSets())); -} - -LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &text) : TWidget(parent) -, _label(this, label, FlatLabel::InitType::Simple) -, _link(this, text) { +LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &text, Type type, const char *slot) : TWidget(parent) +, _label(this, label, FlatLabel::InitType::Simple, (type == Type::Primary) ? st::settingsPrimaryLabel : st::labelDefFlat) +, _link(this, text, (type == Type::Primary) ? st::defaultBoxLinkButton : st::btnDefLink) { + connect(_link, SIGNAL(clicked()), parent, slot); } void LabeledLink::setLink(const QString &text) { @@ -92,12 +52,130 @@ int LabeledLink::naturalWidth() const { } int LabeledLink::resizeGetHeight(int newWidth) { - _label->moveToLeft(0, 0); + _label->moveToLeft(0, 0, newWidth); _link->resizeToWidth(newWidth - st::normalFont->spacew - _label->width()); - _link->moveToLeft(_label->width() + st::normalFont->spacew, 0); + _link->moveToLeft(_label->width() + st::normalFont->spacew, 0, newWidth); return _label->height(); } +DownloadPathState::DownloadPathState(QWidget *parent) : TWidget(parent) +, _path(this, lang(lng_download_path_label), downloadPathText(), LabeledLink::Type::Secondary, SLOT(onDownloadPath())) +, _clear(this, lang(lng_download_path_clear)) { + connect(_clear, SIGNAL(clicked()), this, SLOT(onClear())); + connect(App::wnd(), SIGNAL(tempDirCleared(int)), this, SLOT(onTempDirCleared(int))); + connect(App::wnd(), SIGNAL(tempDirClearFailed(int)), this, SLOT(onTempDirClearFailed(int))); + subscribe(Global::RefDownloadPathChanged(), [this]() { + _path->link()->setText(downloadPathText()); + resizeToWidth(width()); + }); + switch (App::wnd()->tempDirState()) { + case MainWindow::TempDirEmpty: _state = State::Empty; break; + case MainWindow::TempDirExists: _state = State::Exists; break; + case MainWindow::TempDirRemoving: _state = State::Clearing; break; + } + updateControls(); +} + +int DownloadPathState::resizeGetHeight(int newWidth) { + _path->resizeToWidth(qMin(newWidth, _path->naturalWidth())); + _path->moveToLeft(0, 0, newWidth); + _clear->moveToRight(0, 0, newWidth); + return _path->height(); +} + +void DownloadPathState::paintEvent(QPaintEvent *e) { + Painter p(this); + + auto text = ([this]() -> QString { + switch (_state) { + case State::Clearing: return lang(lng_download_path_clearing); + case State::Cleared: return lang(lng_download_path_cleared); + case State::ClearFailed: return lang(lng_download_path_clear_failed); + } + return QString(); + })(); + if (!text.isEmpty()) { + p.setFont(st::linkFont); + p.setPen(st::windowTextFg); + p.drawTextRight(0, 0, width(), text); + } +} + +void DownloadPathState::updateControls() { + _clear->setVisible(_state == State::Exists); + update(); +} + +QString DownloadPathState::downloadPathText() const { + if (Global::DownloadPath().isEmpty()) { + return lang(lng_download_path_default); + } else if (Global::DownloadPath() == qsl("tmp")) { + return lang(lng_download_path_temp); + } + return QDir::toNativeSeparators(Global::DownloadPath()); +}; + +void DownloadPathState::onDownloadPath() { + Ui::showLayer(new DownloadPathBox()); +} + +void DownloadPathState::onClear() { + ConfirmBox *box = new ConfirmBox(lang(lng_sure_clear_downloads)); + connect(box, SIGNAL(confirmed()), this, SLOT(onClearSure())); + Ui::showLayer(box); +} + +void DownloadPathState::onClearSure() { + Ui::hideLayer(); + App::wnd()->tempDirDelete(Local::ClearManagerDownloads); + _state = State::Clearing; + updateControls(); +} + +void DownloadPathState::onTempDirCleared(int task) { + if (task & Local::ClearManagerDownloads) { + _state = State::Cleared; + } + updateControls(); +} + +void DownloadPathState::onTempDirClearFailed(int task) { + if (task & Local::ClearManagerDownloads) { + _state = State::ClearFailed; + } + updateControls(); +} + +ChatSettingsWidget::ChatSettingsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_chat_settings)) { + createControls(); +} + +void ChatSettingsWidget::createControls() { + style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); + style::margins marginSkip(0, 0, 0, st::settingsSkip); + style::margins marginSub(0, 0, 0, st::settingsSubSkip); + style::margins slidedPadding(0, marginSub.bottom() / 2, 0, marginSub.bottom() - (marginSub.bottom() / 2)); + + addChildRow(_replaceEmoji, marginSub, lang(lng_settings_replace_emojis), SLOT(onReplaceEmoji()), cReplaceEmojis()); + style::margins marginList(st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip); + addChildRow(_viewList, marginList, slidedPadding, lang(lng_settings_view_emojis), SLOT(onViewList()), st::btnDefLink); + if (!cReplaceEmojis()) { + _viewList->hideFast(); + } + + addChildRow(_dontAskDownloadPath, marginSub, lang(lng_download_path_dont_ask), SLOT(onDontAskDownloadPath()), !Global::AskDownloadPath()); + style::margins marginPath(st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip); + addChildRow(_downloadPath, marginPath, slidedPadding); + if (Global::AskDownloadPath()) { + _downloadPath->hideFast(); + } + + addChildRow(_sendByEnter, marginSmall, qsl("send_key"), 0, lang(lng_settings_send_enter), SLOT(onSendByEnter()), !cCtrlEnter()); + addChildRow(_sendByCtrlEnter, marginSkip, qsl("send_key"), 1, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter), SLOT(onSendByCtrlEnter()), cCtrlEnter()); + addChildRow(_automaticMediaDownloadSettings, marginSmall, lang(lng_media_auto_settings), SLOT(onAutomaticMediaDownloadSettings())); + addChildRow(_manageStickerSets, marginSmall, lang(lng_stickers_you_have), SLOT(onManageStickerSets())); +} + void ChatSettingsWidget::onReplaceEmoji() { cSetReplaceEmojis(_replaceEmoji->checked()); Local::writeUserSettings(); @@ -123,10 +201,6 @@ void ChatSettingsWidget::onDontAskDownloadPath() { } } -void ChatSettingsWidget::onDownloadPath() { - Ui::showLayer(new DownloadPathBox()); -} - void ChatSettingsWidget::onSendByEnter() { if (_sendByEnter->checked()) { cSetCtrlEnter(false); diff --git a/Telegram/SourceFiles/settings/settings_chat_settings_widget.h b/Telegram/SourceFiles/settings/settings_chat_settings_widget.h index 6656c7811..7b4a1fc9d 100644 --- a/Telegram/SourceFiles/settings/settings_chat_settings_widget.h +++ b/Telegram/SourceFiles/settings/settings_chat_settings_widget.h @@ -28,7 +28,11 @@ namespace Settings { class LabeledLink : public TWidget { public: - LabeledLink(QWidget *parent, const QString &label, const QString &text); + enum class Type { + Primary, + Secondary, + }; + LabeledLink(QWidget *parent, const QString &label, const QString &text, Type type, const char *slot); void setLink(const QString &text); @@ -47,6 +51,42 @@ private: }; +class DownloadPathState : public TWidget, public base::Subscriber { + Q_OBJECT + +public: + DownloadPathState(QWidget *parent); + +protected: + int resizeGetHeight(int newWidth) override; + + void paintEvent(QPaintEvent *e) override; + +private slots: + void onDownloadPath(); + void onClear(); + void onClearSure(); + void onTempDirCleared(int task); + void onTempDirClearFailed(int task); + +private: + QString downloadPathText() const; + void updateControls(); + + enum class State { + Empty, + Exists, + Clearing, + Cleared, + ClearFailed, + }; + State _state = State::Empty; + + ChildWidget _path; + ChildWidget _clear; + +}; + class ChatSettingsWidget : public BlockWidget { Q_OBJECT @@ -57,7 +97,6 @@ private slots: void onReplaceEmoji(); void onViewList(); void onDontAskDownloadPath(); - void onDownloadPath(); void onSendByEnter(); void onSendByCtrlEnter(); void onAutomaticMediaDownloadSettings(); @@ -65,12 +104,11 @@ private slots: private: void createControls(); - QString downloadPathText() const; ChildWidget _replaceEmoji = { nullptr }; ChildWidget> _viewList = { nullptr }; ChildWidget _dontAskDownloadPath = { nullptr }; - ChildWidget> _downloadPath = { nullptr }; + ChildWidget> _downloadPath = { nullptr }; ChildWidget _sendByEnter = { nullptr }; ChildWidget _sendByCtrlEnter = { nullptr }; ChildWidget _automaticMediaDownloadSettings = { nullptr }; diff --git a/Telegram/SourceFiles/settings/settings_cover.cpp b/Telegram/SourceFiles/settings/settings_cover.cpp index d6c689d91..11047c067 100644 --- a/Telegram/SourceFiles/settings/settings_cover.cpp +++ b/Telegram/SourceFiles/settings/settings_cover.cpp @@ -97,19 +97,19 @@ int CoverWidget::resizeGetHeight(int newWidth) { newHeight += st::settingsMarginTop; - _userpicButton->moveToLeft(contentLeft() + st::settingsPhotoLeft, newHeight); + _userpicButton->moveToLeft(contentLeft() + st::settingsPhotoLeft, newHeight, newWidth); int infoLeft = _userpicButton->x() + _userpicButton->width(); _statusPosition = QPoint(infoLeft + st::settingsStatusLeft, _userpicButton->y() + st::settingsStatusTop); if (_cancelPhotoUpload) { - _cancelPhotoUpload->moveToLeft(_statusPosition.x() + st::settingsStatusFont->width(_statusText) + st::settingsStatusFont->spacew, _statusPosition.y()); + _cancelPhotoUpload->moveToLeft(_statusPosition.x() + st::settingsStatusFont->width(_statusText) + st::settingsStatusFont->spacew, _statusPosition.y(), newWidth); } int buttonLeft = _userpicButton->x() + _userpicButton->width() + st::settingsButtonLeft; int buttonsRight = newWidth - st::settingsButtonSkip; - _setPhoto->moveToLeft(buttonLeft, _userpicButton->y() + st::settingsButtonTop); + _setPhoto->moveToLeft(buttonLeft, _userpicButton->y() + st::settingsButtonTop, newWidth); buttonLeft += _setPhoto->width() + st::settingsButtonSkip; - _editName->moveToLeft(buttonLeft, _setPhoto->y()); + _editName->moveToLeft(buttonLeft, _setPhoto->y(), newWidth); _editNameVisible = (buttonLeft + _editName->width() + st::settingsButtonSkip <= newWidth); _editName->setVisible(_editNameVisible); @@ -139,9 +139,9 @@ void CoverWidget::refreshNameGeometry(int newWidth) { int marginsAdd = st::settingsNameLabel.margin.left() + st::settingsNameLabel.margin.right(); _name->resizeToWidth(qMin(nameWidth - marginsAdd, _name->naturalWidth()) + marginsAdd); - _name->moveToLeft(nameLeft, nameTop); + _name->moveToLeft(nameLeft, nameTop, newWidth); - _editNameInline->moveToLeft(nameLeft + _name->width(), nameTop); + _editNameInline->moveToLeft(nameLeft + _name->width(), nameTop, newWidth); _editNameInline->setVisible(editNameInlineVisible); } diff --git a/Telegram/SourceFiles/settings/settings_general_widget.cpp b/Telegram/SourceFiles/settings/settings_general_widget.cpp index 5b799e72c..80516272f 100644 --- a/Telegram/SourceFiles/settings/settings_general_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_general_widget.cpp @@ -45,7 +45,7 @@ QString currentVersion() { result += " alpha"; } if (cBetaVersion()) { - result += qsl(" beta %1").arg(cBetaVersion()); + result += qsl(" beta %1").arg(cBetaVersion() % 1000); } return result; } @@ -83,10 +83,10 @@ int UpdateStateRow::resizeGetHeight(int newWidth) { auto restartLeft = labelWidth(lang(lng_settings_update_ready)); _check->resizeToWidth(qMin(newWidth, _check->naturalWidth())); - _check->moveToLeft(checkLeft, 0); + _check->moveToLeft(checkLeft, 0, newWidth); _restart->resizeToWidth(qMin(newWidth, _restart->naturalWidth())); - _restart->moveToLeft(restartLeft, 0); + _restart->moveToLeft(restartLeft, 0, newWidth); return _check->height(); } @@ -112,6 +112,7 @@ void UpdateStateRow::paintEvent(QPaintEvent *e) { void UpdateStateRow::onCheck() { if (!cAutoUpdate()) return; + setState(State::Check); cSetLastUpdateCheck(0); Sandbox::startUpdateCheck(); } @@ -120,11 +121,11 @@ void UpdateStateRow::setState(State state, bool force) { if (_state != state || force) { _state = state; switch (state) { - case State::None: - case State::Latest: _check->show(); _restart->hide(); break; + case State::None: _check->show(); _restart->hide(); break; case State::Ready: _check->hide(); _restart->show(); break; case State::Check: case State::Download: + case State::Latest: case State::Fail: _check->hide(); _restart->hide(); break; } resizeToWidth(width()); @@ -167,7 +168,7 @@ void UpdateStateRow::onFailed() { #endif // TDESKTOP_DISABLE_AUTOUPDATE GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_general)) -, _changeLanguage(this, lang(lng_settings_change_lang)) { +, _changeLanguage(this, lang(lng_settings_change_lang), st::defaultBoxLinkButton) { connect(_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage())); subscribe(Global::RefChooseCustomLang(), [this]() { chooseCustomLang(); }); FileDialog::registerObserver(this, &GeneralWidget::notifyFileQueryUpdated); @@ -175,7 +176,7 @@ GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(pare } int GeneralWidget::resizeGetHeight(int newWidth) { - _changeLanguage->moveToRight(contentLeft(), st::settingsBlockMarginTop + st::settingsBlockTitleTop + st::settingsBlockTitleFont->ascent - st::btnDefLink.font->ascent); + _changeLanguage->moveToRight(contentLeft(), st::settingsBlockMarginTop + st::settingsBlockTitleTop + st::settingsBlockTitleFont->ascent - st::btnDefLink.font->ascent, newWidth); return BlockWidget::resizeGetHeight(newWidth); } @@ -187,7 +188,7 @@ void GeneralWidget::refreshControls() { #ifndef TDESKTOP_DISABLE_AUTOUPDATE addChildRow(_updateAutomatically, marginSub, lng_settings_update_automatically(lt_version, currentVersion()), SLOT(onUpdateAutomatically()), cAutoUpdate()); - style::margins marginLink(st::defaultCheckbox.textPosition.x(), 0, 0, st::settingsSkip); + style::margins marginLink(st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip); addChildRow(_updateRow, marginLink, slidedPadding); connect(_updateRow->entity(), SIGNAL(restart()), this, SLOT(onRestart())); #endif // TDESKTOP_DISABLE_AUTOUPDATE diff --git a/Telegram/SourceFiles/settings/settings_info_widget.cpp b/Telegram/SourceFiles/settings/settings_info_widget.cpp index 1510ca6d9..88acf95b4 100644 --- a/Telegram/SourceFiles/settings/settings_info_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_info_widget.cpp @@ -45,6 +45,9 @@ void InfoWidget::createControls() { addChildRow(_mobileNumber, margin, slidedPadding); addChildRow(_username, margin, slidedPadding); addChildRow(_link, margin, slidedPadding); + if (self()->username.isEmpty()) { + _link->hideFast(); + } refreshControls(); } @@ -75,7 +78,7 @@ void InfoWidget::refreshUsername() { usernameText.text = '@' + self()->username; copyText = lang(lng_context_copy_mention); } - usernameText.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, usernameText.text.size())); + usernameText.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, usernameText.text.size(), qsl("https://telegram.me/") + self()->username)); setLabeledText(_username, lang(lng_profile_username), usernameText, TextWithEntities(), copyText); if (auto text = _username->entity()->textLabel()) { text->setClickHandlerHook(func(this, &InfoWidget::usernameClickHandlerHook)); @@ -106,10 +109,6 @@ bool InfoWidget::usernameClickHandlerHook(const ClickHandlerPtr &handler, Qt::Mo return false; } -InfoWidget::LabeledWidget::LabeledWidget(QWidget *parent) : TWidget(parent) { - resize(width(), st::labelDefFlat.font->height); -} - void InfoWidget::setLabeledText(ChildWidget &row, const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text) { if (textWithEntities.text.isEmpty()) { row->slideUp(); @@ -119,6 +118,9 @@ void InfoWidget::setLabeledText(ChildWidget &row, const QString &la } } +InfoWidget::LabeledWidget::LabeledWidget(QWidget *parent) : TWidget(parent) { +} + void InfoWidget::LabeledWidget::setLabeledText(const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text) { _label.destroy(); _text.destroy(); @@ -129,6 +131,7 @@ void InfoWidget::LabeledWidget::setLabeledText(const QString &label, const TextW _label->show(); setLabelText(_text, textWithEntities, copyText); setLabelText(_shortText, shortTextWithEntities, copyText); + resizeToWidth(width()); } void InfoWidget::LabeledWidget::setLabelText(ChildWidget &text, const TextWithEntities &textWithEntities, const QString ©Text) { @@ -161,7 +164,7 @@ void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { int InfoWidget::LabeledWidget::naturalWidth() const { if (!_text) return -1; - return _label->naturalWidth() + st::normalFont->spacew + (_shortText ? _shortText : _text)->naturalWidth(); + return _label->naturalWidth() + st::normalFont->spacew + _text->naturalWidth(); } int InfoWidget::LabeledWidget::resizeGetHeight(int newWidth) { @@ -170,7 +173,7 @@ int InfoWidget::LabeledWidget::resizeGetHeight(int newWidth) { if (!_label) return 0; - _label->moveToLeft(0, st::settingsBlockOneLineTextPart.margin.top()); + _label->moveToLeft(0, st::settingsBlockOneLineTextPart.margin.top(), newWidth); auto labelNatural = _label->naturalWidth(); t_assert(labelNatural >= 0); @@ -186,10 +189,10 @@ int InfoWidget::LabeledWidget::resizeGetHeight(int newWidth) { textWidth = -(marginLeft + marginRight); } _text->resizeToWidth(textWidth + marginLeft + marginRight); - _text->moveToLeft(textLeft - marginLeft, 0); + _text->moveToLeft(textLeft - marginLeft, 0, newWidth); if (_shortText) { _shortText->resizeToWidth(textWidth + marginLeft + marginRight); - _shortText->moveToLeft(textLeft - marginLeft, 0); + _shortText->moveToLeft(textLeft - marginLeft, 0, newWidth); if (doesNotFit) { _shortText->show(); _text->hide(); diff --git a/Telegram/SourceFiles/settings/settings_inner_widget.cpp b/Telegram/SourceFiles/settings/settings_inner_widget.cpp index cab185df3..34fcab0e8 100644 --- a/Telegram/SourceFiles/settings/settings_inner_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_inner_widget.cpp @@ -102,25 +102,25 @@ int InnerWidget::resizeGetHeight(int newWidth) { block->resizeToWidth(newWidth); } - int result = refreshBlocksPositions(); + int result = refreshBlocksPositions(newWidth); return result; } -int InnerWidget::refreshBlocksPositions() { +int InnerWidget::refreshBlocksPositions(int newWidth) { int result = (_cover ? _cover->height() : 0) + st::settingsBlocksTop; for_const (auto block, _blocks) { if (block->isHidden()) { continue; } - block->moveToLeft(0, result); + block->moveToLeft(0, result, newWidth); result += block->height(); } return result; } void InnerWidget::onBlockHeightUpdated() { - int newHeight = refreshBlocksPositions(); + int newHeight = refreshBlocksPositions(width()); if (newHeight != height()) { resize(width(), newHeight); emit heightUpdated(); diff --git a/Telegram/SourceFiles/settings/settings_inner_widget.h b/Telegram/SourceFiles/settings/settings_inner_widget.h index a71d2b20f..570c7958e 100644 --- a/Telegram/SourceFiles/settings/settings_inner_widget.h +++ b/Telegram/SourceFiles/settings/settings_inner_widget.h @@ -57,7 +57,7 @@ private: void refreshBlocks(); // Returns the new height value. - int refreshBlocksPositions(); + int refreshBlocksPositions(int newWidth); ChildWidget _cover = { nullptr }; QList _blocks; diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index 4f7b45585..86c34889c 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -45,7 +45,7 @@ NotificationsWidget::NotificationsWidget(QWidget *parent, UserData *self) : Bloc } void NotificationsWidget::createControls() { - style::margins margin(0, 0, 0, st::settingsSmallSkip); + style::margins margin(0, 0, 0, st::settingsSkip); style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2)); addChildRow(_desktopNotifications, margin, lang(lng_settings_desktop_notify), SLOT(onDesktopNotifications()), Global::DesktopNotify()); addChildRow(_showSenderName, margin, slidedPadding, lang(lng_settings_show_name), SLOT(onShowSenderName()), Global::NotifyView() <= dbinvShowName); diff --git a/Telegram/SourceFiles/settings/settings_privacy_widget.cpp b/Telegram/SourceFiles/settings/settings_privacy_widget.cpp index 972ea269d..03c08e540 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_widget.cpp @@ -21,32 +21,181 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "settings/settings_privacy_widget.h" +#include "ui/widgets/widget_slide_wrap.h" #include "styles/style_settings.h" #include "lang.h" +#include "application.h" #include "boxes/sessionsbox.h" +#include "boxes/passcodebox.h" +#include "boxes/autolockbox.h" +#include "pspecific.h" namespace Settings { -PrivacyWidget::PrivacyWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_privacy)) { - refreshControls(); +LocalPasscodeState::LocalPasscodeState(QWidget *parent) : TWidget(parent) +, _edit(this, lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on), st::defaultBoxLinkButton) +, _turnOff(this, lang(lng_passcode_turn_off), st::defaultBoxLinkButton) { + updateControls(); + connect(_edit, SIGNAL(clicked()), this, SLOT(onEdit())); + connect(_turnOff, SIGNAL(clicked()), this, SLOT(onTurnOff())); + subscribe(Global::RefLocalPasscodeChanged(), [this]() { updateControls(); }); } -void PrivacyWidget::refreshControls() { +int LocalPasscodeState::resizeGetHeight(int newWidth) { + _edit->moveToLeft(0, 0, newWidth); + _turnOff->moveToRight(0, 0, newWidth); + return _edit->height(); +} + +void LocalPasscodeState::onEdit() { + Ui::showLayer(new PasscodeBox()); +} + +void LocalPasscodeState::onTurnOff() { + Ui::showLayer(new PasscodeBox(true)); +} + +void LocalPasscodeState::updateControls() { + _edit->setText(lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on)); + _edit->moveToLeft(0, 0); + _turnOff->setVisible(Global::LocalPasscode()); +} + +CloudPasswordState::CloudPasswordState(QWidget *parent) : TWidget(parent) +, _edit(this, lang(lng_cloud_password_set), st::defaultBoxLinkButton) +, _turnOff(this, lang(lng_passcode_turn_off), st::defaultBoxLinkButton) { + _turnOff->hide(); + connect(_edit, SIGNAL(clicked()), this, SLOT(onEdit())); + connect(_turnOff, SIGNAL(clicked()), this, SLOT(onTurnOff())); + Sandbox::connect(SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onReloadPassword(Qt::ApplicationState))); + onReloadPassword(); +} + +int CloudPasswordState::resizeGetHeight(int newWidth) { + _edit->moveToLeft(0, 0, newWidth); + _turnOff->moveToRight(0, 0, newWidth); + return _edit->height(); +} + +void CloudPasswordState::onEdit() { + PasscodeBox *box = new PasscodeBox(_newPasswordSalt, _curPasswordSalt, _hasPasswordRecovery, _curPasswordHint); + connect(box, SIGNAL(reloadPassword()), this, SLOT(onReloadPassword())); + Ui::showLayer(box); +} + +void CloudPasswordState::onTurnOff() { + if (_curPasswordSalt.isEmpty()) { + _turnOff->hide(); + + MTPDaccount_passwordInputSettings::Flags flags = MTPDaccount_passwordInputSettings::Flag::f_email; + MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_bytes(QByteArray()), MTP_bytes(QByteArray()), MTP_string(QString()), MTP_string(QString()))); + MTP::send(MTPaccount_UpdatePasswordSettings(MTP_bytes(QByteArray()), settings), rpcDone(&CloudPasswordState::offPasswordDone), rpcFail(&CloudPasswordState::offPasswordFail)); + } else { + PasscodeBox *box = new PasscodeBox(_newPasswordSalt, _curPasswordSalt, _hasPasswordRecovery, _curPasswordHint, true); + connect(box, SIGNAL(reloadPassword()), this, SLOT(onReloadPassword())); + Ui::showLayer(box); + } +} + +void CloudPasswordState::onReloadPassword(Qt::ApplicationState state) { + if (state == Qt::ApplicationActive) { + MTP::send(MTPaccount_GetPassword(), rpcDone(&CloudPasswordState::getPasswordDone)); + } +} + +void CloudPasswordState::getPasswordDone(const MTPaccount_Password &result) { + _waitingConfirm = QString(); + + switch (result.type()) { + case mtpc_account_noPassword: { + auto &d = result.c_account_noPassword(); + _curPasswordSalt = QByteArray(); + _hasPasswordRecovery = false; + _curPasswordHint = QString(); + _newPasswordSalt = qba(d.vnew_salt); + auto pattern = qs(d.vemail_unconfirmed_pattern); + if (!pattern.isEmpty()) { + _waitingConfirm = lng_cloud_password_waiting(lt_email, pattern); + } + } break; + + case mtpc_account_password: { + auto &d = result.c_account_password(); + _curPasswordSalt = qba(d.vcurrent_salt); + _hasPasswordRecovery = mtpIsTrue(d.vhas_recovery); + _curPasswordHint = qs(d.vhint); + _newPasswordSalt = qba(d.vnew_salt); + auto pattern = qs(d.vemail_unconfirmed_pattern); + if (!pattern.isEmpty()) { + _waitingConfirm = lng_cloud_password_waiting(lt_email, pattern); + } + } break; + } + _edit->setText(lang(_curPasswordSalt.isEmpty() ? lng_cloud_password_set : lng_cloud_password_edit)); + _edit->setVisible(_waitingConfirm.isEmpty()); + _turnOff->setVisible(!_waitingConfirm.isEmpty() || !_curPasswordSalt.isEmpty()); + update(); + + _newPasswordSalt.resize(_newPasswordSalt.size() + 8); + memset_rand(_newPasswordSalt.data() + _newPasswordSalt.size() - 8, 8); +} + +void CloudPasswordState::paintEvent(QPaintEvent *e) { + Painter p(this); + + auto text = st::linkFont->elided(_waitingConfirm, width() - _turnOff->width()); + if (!text.isEmpty()) { + p.setPen(st::windowTextFg); + p.setFont(st::boxTextFont); + p.drawTextLeft(0, 0, width(), text); + } +} + +void CloudPasswordState::offPasswordDone(const MTPBool &result) { + onReloadPassword(); +} + +bool CloudPasswordState::offPasswordFail(const RPCError &error) { + if (MTP::isDefaultHandledError(error)) return false; + + onReloadPassword(); + return true; +} + +PrivacyWidget::PrivacyWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_privacy)) { + createControls(); + subscribe(Global::RefLocalPasscodeChanged(), [this]() { autoLockUpdated(); }); +} + +void PrivacyWidget::createControls() { style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); style::margins marginSkip(0, 0, 0, st::settingsSkip); style::margins slidedPadding(0, marginSmall.bottom() / 2, 0, marginSmall.bottom() - (marginSmall.bottom() / 2)); - addChildRow(_editPasscode, marginSmall, lang(lng_passcode_turn_on), SLOT(onEditPasscode())); - addChildRow(_editPassword, marginSmall, lang(lng_cloud_password_set), SLOT(onEditPassword())); + 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); + addChildRow(_autoLock, marginSmall, slidedPadding, label, value, LabeledLink::Type::Primary, SLOT(onAutoLock())); + if (!Global::LocalPasscode()) { + _autoLock->hideFast(); + } + addChildRow(_cloudPasswordState, marginSmall); addChildRow(_showAllSessions, marginSmall, lang(lng_settings_show_sessions), SLOT(onShowSessions())); } -void PrivacyWidget::onEditPasscode() { - +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); + _autoLock->entity()->link()->setText(value); + resizeToWidth(width()); + _autoLock->slideDown(); + } else { + _autoLock->slideUp(); + } } -void PrivacyWidget::onEditPassword() { - +void PrivacyWidget::onAutoLock() { + Ui::showLayer(new AutoLockBox()); } void PrivacyWidget::onShowSessions() { diff --git a/Telegram/SourceFiles/settings/settings_privacy_widget.h b/Telegram/SourceFiles/settings/settings_privacy_widget.h index cce92d5de..eec2ff87d 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_widget.h +++ b/Telegram/SourceFiles/settings/settings_privacy_widget.h @@ -21,13 +21,61 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "settings/settings_block_widget.h" +#include "settings/settings_chat_settings_widget.h" namespace Settings { -class LocalPasscodeState : public TWidget { +class LocalPasscodeState : public TWidget, public base::Subscriber { + Q_OBJECT + +public: + LocalPasscodeState(QWidget *parent); + +protected: + int resizeGetHeight(int newWidth) override; + +private slots: + void onEdit(); + void onTurnOff(); + +private: + void updateControls(); + + ChildWidget _edit; + ChildWidget _turnOff; + }; -class CloudPasswordState : public TWidget { +class CloudPasswordState : public TWidget, private base::Subscriber, public RPCSender { + Q_OBJECT + +public: + CloudPasswordState(QWidget *parent); + +protected: + int resizeGetHeight(int newWidth) override; + + void paintEvent(QPaintEvent *e) override; + +private slots: + void onEdit(); + void onTurnOff(); + void onReloadPassword(Qt::ApplicationState state = Qt::ApplicationActive); + +private: + void getPasswordDone(const MTPaccount_Password &result); + void offPasswordDone(const MTPBool &result); + bool offPasswordFail(const RPCError &error); + + ChildWidget _edit; + ChildWidget _turnOff; + + QString _waitingConfirm; + QByteArray _curPasswordSalt; + bool _hasPasswordRecovery = false; + QString _curPasswordHint; + QByteArray _newPasswordSalt; + }; class PrivacyWidget : public BlockWidget { @@ -37,18 +85,16 @@ public: PrivacyWidget(QWidget *parent, UserData *self); private slots: - void onEditPasscode(); - void onEditPassword(); + void onAutoLock(); void onShowSessions(); private: - void refreshControls(); + void createControls(); + void autoLockUpdated(); - //ChildWidget _localPasscodeState = { nullptr }; - //ChildWidget> _autoLock = { nullptr }; - //ChildWidget _cloudPasswordState = { nullptr }; - ChildWidget _editPasscode = { nullptr }; - ChildWidget _editPassword = { nullptr }; + ChildWidget _localPasscodeState = { nullptr }; + ChildWidget> _autoLock = { nullptr }; + ChildWidget _cloudPasswordState = { nullptr }; ChildWidget _showAllSessions = { nullptr }; }; diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index ff8220b81..e6e02552f 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -191,9 +191,9 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent) , _radial(animation(this, &SettingsInner::step_radial)) // advanced -, _passcodeEdit(this, lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on)) +, _passcodeEdit(this, lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on)) , _passcodeTurnOff(this, lang(lng_passcode_turn_off)) -, _autoLock(this, (cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600)) +, _autoLock(this, /*(cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600)*/"") , _autoLockText(lang(psIdleSupported() ? lng_passcode_autolock_away : lng_passcode_autolock_inactive) + ' ') , _autoLockWidth(st::linkFont->width(_autoLockText)) , _passwordEdit(this, lang(lng_cloud_password_set)) @@ -665,7 +665,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { p.setPen(st::black->p); if (self()) { top += _passcodeEdit.height() + st::setLittleSkip; - if (cHasPasscode()) { + if (Global::LocalPasscode()) { p.drawText(_left, top + st::linkFont->ascent, _autoLockText); top += _autoLock.height() + st::setLittleSkip; } @@ -782,7 +782,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { if (self()) { _passcodeEdit.move(_left, top); _passcodeTurnOff.move(_left + st::setWidth - _passcodeTurnOff.width(), top); top += _passcodeTurnOff.height() + st::setLittleSkip; - if (cHasPasscode()) { + if (Global::LocalPasscode()) { _autoLock.move(_left + _autoLockWidth, top); top += _autoLock.height() + st::setLittleSkip; } _passwordEdit.move(_left, top); @@ -953,8 +953,8 @@ void SettingsInner::updateConnectionType() { void SettingsInner::passcodeChanged() { resizeEvent(0); - _passcodeEdit.setText(lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on)); - _autoLock.setText((cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600)); + //_passcodeEdit.setText(lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on)); + //_autoLock.setText((cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600)); // _passwordEdit.setText() showAll(); } @@ -1165,7 +1165,7 @@ void SettingsInner::showAll() { // advanced if (self()) { _passcodeEdit.show(); - if (cHasPasscode()) { + if (Global::LocalPasscode()) { _autoLock.show(); _passcodeTurnOff.show(); } else { diff --git a/Telegram/SourceFiles/shortcuts.cpp b/Telegram/SourceFiles/shortcuts.cpp index 9f782ea35..89b8facc3 100644 --- a/Telegram/SourceFiles/shortcuts.cpp +++ b/Telegram/SourceFiles/shortcuts.cpp @@ -35,7 +35,7 @@ bool lock_telegram() { if (App::passcoded()) { w->passcodeWidget()->onSubmit(); return true; - } else if (cHasPasscode()) { + } else if (Global::LocalPasscode()) { w->setupPasscode(true); return true; } diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index 170afbd89..f75eb8d58 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -73,7 +73,7 @@ TitleWidget::TitleWidget(MainWindow *window) : TWidget(window) #ifndef TDESKTOP_DISABLE_AUTOUPDATE Sandbox::updatingState() == Application::UpdatingReady || #endif - cHasPasscode() + Global::LocalPasscode() ) { showUpdateBtn(); } @@ -309,7 +309,7 @@ void TitleWidget::showUpdateBtn() { _close.hide(); return; } - if (cHasPasscode()) { + if (Global::LocalPasscode()) { _lock.show(); } else { _lock.hide(); diff --git a/Telegram/SourceFiles/ui/flatbutton.cpp b/Telegram/SourceFiles/ui/flatbutton.cpp index 2fff65d45..3ed82ca7b 100644 --- a/Telegram/SourceFiles/ui/flatbutton.cpp +++ b/Telegram/SourceFiles/ui/flatbutton.cpp @@ -121,26 +121,36 @@ void FlatButton::paintEvent(QPaintEvent *e) { p.drawText(r, _text, style::al_top); } -LinkButton::LinkButton(QWidget *parent, const QString &text, const style::linkButton &st) : Button(parent), _text(text), _st(st) { +LinkButton::LinkButton(QWidget *parent, const QString &text, const style::linkButton &st) : Button(parent) +, _text(text) +, _textWidth(st.font->width(_text)) +, _st(st) { connect(this, SIGNAL(stateChanged(int, ButtonStateChangeSource)), this, SLOT(onStateChange(int, ButtonStateChangeSource))); - resize(_st.font->width(_text), _st.font->height); + resize(_textWidth, _st.font->height); setCursor(style::cur_pointer); } int LinkButton::naturalWidth() const { - return _st.font->width(_text); + return _textWidth; } void LinkButton::paintEvent(QPaintEvent *e) { - QPainter p(this); - p.setFont(((_state & StateOver) ? _st.overFont : _st.font)->f); - p.setPen(((_state & StateDown) ? _st.downColor : ((_state & StateOver) ? _st.overColor : _st.color))->p); - p.drawText(0, ((_state & StateOver) ? _st.overFont : _st.font)->ascent, _text); + Painter p(this); + auto &font = ((_state & StateOver) ? _st.overFont : _st.font); + auto &pen = ((_state & StateDown) ? _st.downColor : ((_state & StateOver) ? _st.overColor : _st.color)); + p.setFont(font); + p.setPen(pen); + if (_textWidth > width()) { + p.drawText(0, font->ascent, font->elided(_text, width())); + } else { + p.drawText(0, font->ascent, _text); + } } void LinkButton::setText(const QString &text) { _text = text; - resize(_st.font->width(_text), _st.font->height); + _textWidth = _st.font->width(_text); + resize(_textWidth, _st.font->height); update(); } diff --git a/Telegram/SourceFiles/ui/flatbutton.h b/Telegram/SourceFiles/ui/flatbutton.h index aada3d54c..83d725615 100644 --- a/Telegram/SourceFiles/ui/flatbutton.h +++ b/Telegram/SourceFiles/ui/flatbutton.h @@ -82,6 +82,7 @@ public slots: private: QString _text; + int _textWidth = 0; style::linkButton _st; }; diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 3798112ea..a69901236 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -163,6 +163,8 @@ '<(src_loc)/boxes/emojibox.h', '<(src_loc)/boxes/languagebox.cpp', '<(src_loc)/boxes/languagebox.h', + '<(src_loc)/boxes/localstoragebox.cpp', + '<(src_loc)/boxes/localstoragebox.h', '<(src_loc)/boxes/passcodebox.cpp', '<(src_loc)/boxes/passcodebox.h', '<(src_loc)/boxes/photocropbox.cpp',