mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-01 23:00:58 +00:00
First version of the new Settings page is finished.
Added LocalStorageBox for watching info and clearing local storage. Local passcode and cloud password state display and editing done. Temporary download location clearing link added. Crash fixed in local storage clear + app close, now waiting for the clearing thread to quit. Some design improvements and testing.
This commit is contained in:
parent
afab21372b
commit
b520cf0f78
Telegram
Resources/langs
SourceFiles
app.cppapplication.cppautoupdater.h
boxes
facades.cppfacades.hlocalstorage.cpplocalstorage.hmainwindow.cppsettings.cppsettings.hsettings
settings.stylesettings_advanced_widget.cppsettings_background_widget.cppsettings_block_widget.cppsettings_block_widget.hsettings_chat_settings_widget.cppsettings_chat_settings_widget.hsettings_cover.cppsettings_general_widget.cppsettings_info_widget.cppsettings_inner_widget.cppsettings_inner_widget.hsettings_notifications_widget.cppsettings_privacy_widget.cppsettings_privacy_widget.h
settingswidget.cppshortcuts.cpptitle.cppui
gyp
@ -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}";
|
||||
|
@ -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();
|
||||
|
@ -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..."));
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -85,3 +85,5 @@ aboutRevokePublicLabel: flatLabel(labelDefFlat) {
|
||||
width: 320px;
|
||||
textFg: windowTextFg;
|
||||
}
|
||||
|
||||
localStorageBoxSkip: 10px;
|
||||
|
131
Telegram/SourceFiles/boxes/localstoragebox.cpp
Normal file
131
Telegram/SourceFiles/boxes/localstoragebox.cpp
Normal file
@ -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();
|
||||
}
|
62
Telegram/SourceFiles/boxes/localstoragebox.h
Normal file
62
Telegram/SourceFiles/boxes/localstoragebox.h
Normal file
@ -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<LinkButton> _clear;
|
||||
ChildWidget<BoxButton> _close;
|
||||
|
||||
int _imagesCount = -1;
|
||||
int _audiosCount = -1;
|
||||
|
||||
};
|
@ -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);
|
||||
|
@ -653,6 +653,10 @@ struct Data {
|
||||
|
||||
base::Observable<void> ChooseCustomLang;
|
||||
|
||||
int AutoLock = 3600;
|
||||
bool LocalPasscode = false;
|
||||
base::Observable<void> LocalPasscodeChanged;
|
||||
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
@ -757,4 +761,8 @@ DefineRefVar(Global, base::Observable<void>, ConnectionTypeChanged);
|
||||
|
||||
DefineRefVar(Global, base::Observable<void>, ChooseCustomLang);
|
||||
|
||||
DefineVar(Global, int, AutoLock);
|
||||
DefineVar(Global, bool, LocalPasscode);
|
||||
DefineRefVar(Global, base::Observable<void>, LocalPasscodeChanged);
|
||||
|
||||
} // namespace Global
|
||||
|
@ -318,6 +318,10 @@ DeclareRefVar(base::Observable<void>, ConnectionTypeChanged);
|
||||
|
||||
DeclareRefVar(base::Observable<void>, ChooseCustomLang);
|
||||
|
||||
DeclareVar(int, AutoLock);
|
||||
DeclareVar(bool, LocalPasscode);
|
||||
DeclareRefVar(base::Observable<void>, LocalPasscodeChanged);
|
||||
|
||||
} // namespace Global
|
||||
|
||||
namespace Adaptive {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -75,9 +75,6 @@ bool gCompressPastedImage = true;
|
||||
|
||||
QString gTimeFormat = qsl("hh:mm");
|
||||
|
||||
int32 gAutoLock = 3600;
|
||||
bool gHasPasscode = false;
|
||||
|
||||
bool gHasAudioPlayer = true;
|
||||
bool gHasAudioCapture = true;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<Checkbox> &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<Radiobutton> &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<LinkButton> &child, style::margins &margin, const QString &text, const char *slot) {
|
||||
child = new LinkButton(this, text);
|
||||
void BlockWidget::createChildRow(ChildWidget<LinkButton> &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);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ private:
|
||||
}
|
||||
void createChildRow(ChildWidget<Checkbox> &child, style::margins &margin, const QString &text, const char *slot, bool checked);
|
||||
void createChildRow(ChildWidget<Radiobutton> &child, style::margins &margin, const QString &group, int value, const QString &text, const char *slot, bool checked);
|
||||
void createChildRow(ChildWidget<LinkButton> &child, style::margins &margin, const QString &text, const char *slot);
|
||||
void createChildRow(ChildWidget<LinkButton> &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();
|
||||
|
@ -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);
|
||||
|
@ -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<LabeledLink> _path;
|
||||
ChildWidget<LinkButton> _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<Checkbox> _replaceEmoji = { nullptr };
|
||||
ChildWidget<Ui::WidgetSlideWrap<LinkButton>> _viewList = { nullptr };
|
||||
ChildWidget<Checkbox> _dontAskDownloadPath = { nullptr };
|
||||
ChildWidget<Ui::WidgetSlideWrap<LabeledLink>> _downloadPath = { nullptr };
|
||||
ChildWidget<Ui::WidgetSlideWrap<DownloadPathState>> _downloadPath = { nullptr };
|
||||
ChildWidget<Radiobutton> _sendByEnter = { nullptr };
|
||||
ChildWidget<Radiobutton> _sendByCtrlEnter = { nullptr };
|
||||
ChildWidget<LinkButton> _automaticMediaDownloadSettings = { nullptr };
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<LabeledWrap> &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<LabeledWrap> &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<FlatLabel> &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();
|
||||
|
@ -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();
|
||||
|
@ -57,7 +57,7 @@ private:
|
||||
void refreshBlocks();
|
||||
|
||||
// Returns the new height value.
|
||||
int refreshBlocksPositions();
|
||||
int refreshBlocksPositions(int newWidth);
|
||||
|
||||
ChildWidget<CoverWidget> _cover = { nullptr };
|
||||
QList<BlockWidget*> _blocks;
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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<LinkButton> _edit;
|
||||
ChildWidget<LinkButton> _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<LinkButton> _edit;
|
||||
ChildWidget<LinkButton> _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> _localPasscodeState = { nullptr };
|
||||
//ChildWidget<Ui::WidgetSlideWrap<LabeledLink>> _autoLock = { nullptr };
|
||||
//ChildWidget<CloudPasswordState> _cloudPasswordState = { nullptr };
|
||||
ChildWidget<LinkButton> _editPasscode = { nullptr };
|
||||
ChildWidget<LinkButton> _editPassword = { nullptr };
|
||||
ChildWidget<LocalPasscodeState> _localPasscodeState = { nullptr };
|
||||
ChildWidget<Ui::WidgetSlideWrap<LabeledLink>> _autoLock = { nullptr };
|
||||
ChildWidget<CloudPasswordState> _cloudPasswordState = { nullptr };
|
||||
ChildWidget<LinkButton> _showAllSessions = { nullptr };
|
||||
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,7 @@ public slots:
|
||||
|
||||
private:
|
||||
QString _text;
|
||||
int _textWidth = 0;
|
||||
style::linkButton _st;
|
||||
|
||||
};
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user