mirror of https://github.com/procxx/kepka.git
Remove old settings code.
This commit is contained in:
parent
19a9a990b6
commit
0d4ad1b635
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
using "basic.style";
|
|
||||||
using "dialogs/dialogs.style";
|
|
||||||
using "ui/widgets/widgets.style";
|
|
||||||
using "boxes/boxes.style";
|
|
||||||
|
|
||||||
settingsScroll: ScrollArea(defaultScrollArea) {
|
|
||||||
bottomsh: 0px;
|
|
||||||
topsh: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
settingsMaxWidth: 520px;
|
|
||||||
settingsMaxPadding: 48px;
|
|
||||||
settingsMinPadding: 32px;
|
|
||||||
settingsMargin: 48px;
|
|
||||||
|
|
||||||
settingsFixedBarHeight: boxLayerTitleHeight;
|
|
||||||
settingsFixedBarFont: boxTitleFont;
|
|
||||||
settingsFixedBarTextPosition: boxLayerTitlePosition;
|
|
||||||
settingsFixedBarClose: IconButton(boxTitleClose) {
|
|
||||||
width: settingsFixedBarHeight;
|
|
||||||
height: settingsFixedBarHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
settingsMarginTop: 34px;
|
|
||||||
settingsPhoto: UserpicButton(defaultUserpicButton) {
|
|
||||||
size: size(112px, 112px);
|
|
||||||
photoSize: 112px;
|
|
||||||
}
|
|
||||||
settingsPhotoLeft: -8px;
|
|
||||||
settingsPhotoDuration: 500;
|
|
||||||
settingsNameLeft: 26px;
|
|
||||||
settingsNameTop: 9px;
|
|
||||||
settingsNameLabel: FlatLabel(defaultFlatLabel) {
|
|
||||||
margin: margins(10px, 5px, 10px, 5px);
|
|
||||||
minWidth: 160px;
|
|
||||||
maxHeight: 24px;
|
|
||||||
textFg: windowBoldFg;
|
|
||||||
style: TextStyle(defaultTextStyle) {
|
|
||||||
font: font(16px semibold);
|
|
||||||
linkFont: font(16px semibold);
|
|
||||||
linkFontOver: font(16px semibold underline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
settingsStatusLeft: 27px;
|
|
||||||
settingsStatusTop: 35px;
|
|
||||||
settingsStatusFont: normalFont;
|
|
||||||
settingsStatusFg: windowSubTextFg;
|
|
||||||
settingsStatusFgActive: windowActiveTextFg;
|
|
||||||
settingsMarginBottom: 35px;
|
|
||||||
|
|
||||||
settingsButtonLeft: 27px;
|
|
||||||
settingsButtonTop: 75px;
|
|
||||||
settingsButtonSkip: 10px;
|
|
||||||
settingsPrimaryButton: defaultActiveButton;
|
|
||||||
settingsSecondaryButton: defaultLightButton;
|
|
||||||
settingsEditButton: IconButton {
|
|
||||||
width: 24px;
|
|
||||||
height: 34px;
|
|
||||||
|
|
||||||
icon: icon {{ "settings_edit_name", menuIconFg }};
|
|
||||||
iconPosition: point(3px, 9px);
|
|
||||||
}
|
|
||||||
|
|
||||||
settingsBlocksTop: 7px;
|
|
||||||
settingsBlocksBottom: 20px;
|
|
||||||
settingsBlockMarginTop: 14px;
|
|
||||||
settingsBlockMarginRight: 10px;
|
|
||||||
settingsBlockMarginBottom: 10px;
|
|
||||||
settingsBlockTitleHeight: 31px;
|
|
||||||
settingsBlockTitleFont: font(15px semibold);
|
|
||||||
settingsBlockTitleFg: windowBoldFg;
|
|
||||||
settingsBlockTitleTop: 0px;
|
|
||||||
settingsPrimaryLabel: FlatLabel(defaultFlatLabel) {
|
|
||||||
style: TextStyle(defaultTextStyle) {
|
|
||||||
font: boxTextFont;
|
|
||||||
linkFont: boxTextFont;
|
|
||||||
linkFontOver: font(boxFontSize underline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
settingsBlockLabel: FlatLabel(settingsPrimaryLabel) {
|
|
||||||
textFg: windowSubTextFg;
|
|
||||||
}
|
|
||||||
settingsBlockOneLineTextPart: FlatLabel(settingsPrimaryLabel) {
|
|
||||||
minWidth: 0px; // No need to set minWidth in one-line text.
|
|
||||||
margin: margins(5px, 5px, 5px, 5px);
|
|
||||||
maxHeight: 20px;
|
|
||||||
}
|
|
||||||
settingsBioValue: FlatLabel(settingsBlockOneLineTextPart) {
|
|
||||||
minWidth: 120px;
|
|
||||||
maxHeight: 0px;
|
|
||||||
}
|
|
||||||
settingsSubSkip: 4px;
|
|
||||||
settingsSmallSkip: 10px;
|
|
||||||
settingsSkip: 14px;
|
|
||||||
settingsLargeSkip: 23px;
|
|
||||||
|
|
||||||
settingsActionPadding: margins(0px, 4px, 0px, 5px);
|
|
||||||
|
|
||||||
settingsBackgroundSize: 120px;
|
|
||||||
|
|
||||||
settingsUpdateFg: windowSubTextFg;
|
|
|
@ -1,162 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_advanced_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "boxes/connection_box.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
#include "boxes/about_box.h"
|
|
||||||
#include "boxes/local_storage_box.h"
|
|
||||||
#include "data/data_session.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "window/themes/window_theme.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
AdvancedWidget::AdvancedWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_advanced_settings)) {
|
|
||||||
createControls();
|
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
subscribe(Global::RefConnectionTypeChanged(), [this]() {
|
|
||||||
connectionTypeUpdated();
|
|
||||||
});
|
|
||||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
if (!self) {
|
|
||||||
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
|
|
||||||
if (update.type == Window::Theme::BackgroundUpdate::Type::ApplyingTheme) {
|
|
||||||
checkNonDefaultTheme();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::createControls() {
|
|
||||||
style::margins marginSmall(0, 0, 0, st::settingsSmallSkip);
|
|
||||||
style::margins marginLarge(0, 0, 0, st::settingsLargeSkip);
|
|
||||||
|
|
||||||
style::margins marginLocalStorage = [&] {
|
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
return marginSmall;
|
|
||||||
#else // !TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
return marginLarge;
|
|
||||||
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
}();
|
|
||||||
if (self()) {
|
|
||||||
createChildRow(_manageLocalStorage, marginLocalStorage, lang(lng_settings_manage_local_storage), SLOT(onManageLocalStorage()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
createChildRow(_connectionType, marginLarge, lang(lng_connection_type), lang(lng_connection_auto_connecting), LabeledLink::Type::Primary, SLOT(onConnectionType()));
|
|
||||||
connectionTypeUpdated();
|
|
||||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
|
|
||||||
if (self()) {
|
|
||||||
createChildRow(_askQuestion, marginSmall, lang(lng_settings_ask_question), SLOT(onAskQuestion()));
|
|
||||||
} else {
|
|
||||||
style::margins slidedPadding(0, marginLarge.bottom() / 2, 0, marginLarge.bottom() - (marginLarge.bottom() / 2));
|
|
||||||
createChildRow(_useDefaultTheme, marginLarge, slidedPadding, lang(lng_settings_bg_use_default), SLOT(onUseDefaultTheme()));
|
|
||||||
if (!Window::Theme::SuggestThemeReset()) {
|
|
||||||
_useDefaultTheme->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
createChildRow(_toggleNightTheme, marginLarge, getNightThemeToggleText(), SLOT(onToggleNightTheme()));
|
|
||||||
}
|
|
||||||
createChildRow(_telegramFAQ, marginLarge, lang(lng_settings_faq), SLOT(onTelegramFAQ()));
|
|
||||||
if (self()) {
|
|
||||||
style::margins marginLogout(0, 0, 0, 2 * st::settingsLargeSkip);
|
|
||||||
createChildRow(_logOut, marginLogout, lang(lng_settings_logout), SLOT(onLogOut()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::checkNonDefaultTheme() {
|
|
||||||
if (self()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_useDefaultTheme->toggle(
|
|
||||||
Window::Theme::SuggestThemeReset(),
|
|
||||||
anim::type::normal);
|
|
||||||
_toggleNightTheme->setText(getNightThemeToggleText());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::onManageLocalStorage() {
|
|
||||||
LocalStorageBox::Show(&Auth().data().cache());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
void AdvancedWidget::connectionTypeUpdated() {
|
|
||||||
const auto connection = [] {
|
|
||||||
const auto transport = MTP::dctransport();
|
|
||||||
if (!Global::UseProxy()) {
|
|
||||||
return transport.isEmpty()
|
|
||||||
? lang(lng_connection_auto_connecting)
|
|
||||||
: lng_connection_auto(lt_transport, transport);
|
|
||||||
} else {
|
|
||||||
return transport.isEmpty()
|
|
||||||
? lang(lng_connection_proxy_connecting)
|
|
||||||
: lng_connection_proxy(lt_transport, transport);
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
_connectionType->link()->setText(connection);
|
|
||||||
resizeToWidth(width());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::onConnectionType() {
|
|
||||||
Ui::show(ProxiesBoxController::CreateOwningBox());
|
|
||||||
}
|
|
||||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
|
|
||||||
void AdvancedWidget::onUseDefaultTheme() {
|
|
||||||
Window::Theme::ApplyDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::onToggleNightTheme() {
|
|
||||||
Window::Theme::ToggleNightMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::onAskQuestion() {
|
|
||||||
auto box = Box<ConfirmBox>(lang(lng_settings_ask_sure), lang(lng_settings_ask_ok), lang(lng_settings_faq_button), crl::guard(this, [this] {
|
|
||||||
onAskQuestionSure();
|
|
||||||
}), crl::guard(this, [this] {
|
|
||||||
onTelegramFAQ();
|
|
||||||
}));
|
|
||||||
box->setStrictCancel(true);
|
|
||||||
Ui::show(std::move(box));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::onAskQuestionSure() {
|
|
||||||
if (_supportGetRequest) return;
|
|
||||||
_supportGetRequest = MTP::send(MTPhelp_GetSupport(), rpcDone(&AdvancedWidget::supportGot));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::supportGot(const MTPhelp_Support &support) {
|
|
||||||
if (!App::main()) return;
|
|
||||||
|
|
||||||
if (support.type() == mtpc_help_support) {
|
|
||||||
if (auto user = App::feedUsers(MTP_vector<MTPUser>(1, support.c_help_support().vuser))) {
|
|
||||||
Ui::showPeerHistory(user, ShowAtUnreadMsgId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AdvancedWidget::getNightThemeToggleText() const {
|
|
||||||
return lang(Window::Theme::IsNightMode()
|
|
||||||
? lng_settings_disable_night_theme
|
|
||||||
: lng_settings_enable_night_theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::onTelegramFAQ() {
|
|
||||||
QDesktopServices::openUrl(telegramFaqLink());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedWidget::onLogOut() {
|
|
||||||
App::wnd()->onLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
#include "old_settings/settings_chat_settings_widget.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class AdvancedWidget : public BlockWidget, public RPCSender {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
AdvancedWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onManageLocalStorage();
|
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
void onConnectionType();
|
|
||||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
void onAskQuestion();
|
|
||||||
void onAskQuestionSure();
|
|
||||||
void onUseDefaultTheme();
|
|
||||||
void onToggleNightTheme();
|
|
||||||
void onTelegramFAQ();
|
|
||||||
void onLogOut();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void createControls();
|
|
||||||
void checkNonDefaultTheme();
|
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
void connectionTypeUpdated();
|
|
||||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
void supportGot(const MTPhelp_Support &support);
|
|
||||||
QString getNightThemeToggleText() const;
|
|
||||||
|
|
||||||
Ui::LinkButton *_manageLocalStorage = nullptr;
|
|
||||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
LabeledLink *_connectionType = nullptr;
|
|
||||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
|
||||||
Ui::SlideWrap<Ui::LinkButton> *_useDefaultTheme = nullptr;
|
|
||||||
Ui::LinkButton *_toggleNightTheme = nullptr;
|
|
||||||
Ui::LinkButton *_askQuestion = nullptr;
|
|
||||||
Ui::LinkButton *_telegramFAQ = nullptr;
|
|
||||||
Ui::LinkButton *_logOut = nullptr;
|
|
||||||
|
|
||||||
mtpRequestId _supportGetRequest = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,297 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_background_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "mainwidget.h"
|
|
||||||
#include "boxes/background_box.h"
|
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "window/themes/window_theme.h"
|
|
||||||
#include "window/themes/window_theme_editor.h"
|
|
||||||
#include "core/file_utilities.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
BackgroundRow::BackgroundRow(QWidget *parent) : RpWidget(parent)
|
|
||||||
, _chooseFromGallery(this, lang(lng_settings_bg_from_gallery), st::boxLinkButton)
|
|
||||||
, _chooseFromFile(this, lang(lng_settings_bg_from_file), st::boxLinkButton)
|
|
||||||
, _editTheme(this, lang(lng_settings_bg_edit_theme), st::boxLinkButton)
|
|
||||||
, _radial(animation(this, &BackgroundRow::step_radial)) {
|
|
||||||
updateImage();
|
|
||||||
|
|
||||||
connect(_chooseFromGallery, SIGNAL(clicked()), this, SIGNAL(chooseFromGallery()));
|
|
||||||
connect(_chooseFromFile, SIGNAL(clicked()), this, SIGNAL(chooseFromFile()));
|
|
||||||
connect(_editTheme, SIGNAL(clicked()), this, SIGNAL(editTheme()));
|
|
||||||
checkNonDefaultTheme();
|
|
||||||
using Update = const Window::Theme::BackgroundUpdate;
|
|
||||||
subscribe(Window::Theme::Background(), [this](Update &update) {
|
|
||||||
if (update.type == Update::Type::ApplyingTheme
|
|
||||||
|| update.type == Update::Type::New) {
|
|
||||||
checkNonDefaultTheme();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundRow::checkNonDefaultTheme() {
|
|
||||||
if (Window::Theme::SuggestThemeReset()) {
|
|
||||||
if (!_useDefaultTheme) {
|
|
||||||
_useDefaultTheme.create(this, lang(lng_settings_bg_use_default), st::boxLinkButton);
|
|
||||||
_useDefaultTheme->show();
|
|
||||||
connect(_useDefaultTheme, SIGNAL(clicked()), this, SIGNAL(useDefault()));
|
|
||||||
resizeToWidth(width());
|
|
||||||
}
|
|
||||||
} else if (_useDefaultTheme) {
|
|
||||||
_useDefaultTheme.destroy();
|
|
||||||
resizeToWidth(width());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundRow::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
|
|
||||||
bool radial = false;
|
|
||||||
float64 radialOpacity = 0;
|
|
||||||
if (_radial.animating()) {
|
|
||||||
_radial.step(getms());
|
|
||||||
radial = _radial.animating();
|
|
||||||
radialOpacity = _radial.opacity();
|
|
||||||
}
|
|
||||||
if (radial) {
|
|
||||||
auto backThumb = App::main() ? App::main()->newBackgroundThumb() : ImagePtr();
|
|
||||||
if (backThumb->isNull()) {
|
|
||||||
p.drawPixmap(0, 0, _background);
|
|
||||||
} else {
|
|
||||||
const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(Data::FileOrigin(), st::settingsBackgroundSize);
|
|
||||||
p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, 0, (pix.height() - st::settingsBackgroundSize * cIntRetinaFactor()) / 2, st::settingsBackgroundSize * cIntRetinaFactor(), st::settingsBackgroundSize * cIntRetinaFactor());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto outer = radialRect();
|
|
||||||
QRect inner(QPoint(outer.x() + (outer.width() - st::radialSize.width()) / 2, outer.y() + (outer.height() - st::radialSize.height()) / 2), st::radialSize);
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setOpacity(radialOpacity);
|
|
||||||
p.setBrush(st::radialBg);
|
|
||||||
|
|
||||||
{
|
|
||||||
PainterHighQualityEnabler hq(p);
|
|
||||||
p.drawEllipse(inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
p.setOpacity(1);
|
|
||||||
QRect arc(inner.marginsRemoved(QMargins(st::radialLine, st::radialLine, st::radialLine, st::radialLine)));
|
|
||||||
_radial.draw(p, arc, st::radialLine, st::radialFg);
|
|
||||||
} else {
|
|
||||||
p.drawPixmap(0, 0, _background);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int BackgroundRow::resizeGetHeight(int newWidth) {
|
|
||||||
auto linkTop = 0;
|
|
||||||
auto linkLeft = st::settingsBackgroundSize + st::settingsSmallSkip;
|
|
||||||
auto linkWidth = newWidth - linkLeft;
|
|
||||||
_chooseFromGallery->resizeToWidth(qMin(linkWidth, _chooseFromGallery->naturalWidth()));
|
|
||||||
_chooseFromFile->resizeToWidth(qMin(linkWidth, _chooseFromFile->naturalWidth()));
|
|
||||||
_editTheme->resizeToWidth(qMin(linkWidth, _editTheme->naturalWidth()));
|
|
||||||
if (_useDefaultTheme) {
|
|
||||||
_useDefaultTheme->resizeToWidth(qMin(linkWidth, _useDefaultTheme->naturalWidth()));
|
|
||||||
_useDefaultTheme->moveToLeft(linkLeft, linkTop, newWidth);
|
|
||||||
linkTop += _useDefaultTheme->height() + st::settingsSmallSkip;
|
|
||||||
}
|
|
||||||
_chooseFromGallery->moveToLeft(linkLeft, linkTop, newWidth);
|
|
||||||
linkTop += _chooseFromGallery->height() + st::settingsSmallSkip;
|
|
||||||
_chooseFromFile->moveToLeft(linkLeft, linkTop, newWidth);
|
|
||||||
linkTop += _chooseFromFile->height() + st::settingsSmallSkip;
|
|
||||||
_editTheme->moveToLeft(linkLeft, linkTop, newWidth);
|
|
||||||
|
|
||||||
return st::settingsBackgroundSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
float64 BackgroundRow::radialProgress() const {
|
|
||||||
if (auto m = App::main()) {
|
|
||||||
return m->chatBackgroundProgress();
|
|
||||||
}
|
|
||||||
return 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BackgroundRow::radialLoading() const {
|
|
||||||
if (auto m = App::main()) {
|
|
||||||
if (m->chatBackgroundLoading()) {
|
|
||||||
m->checkChatBackground();
|
|
||||||
if (m->chatBackgroundLoading()) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
const_cast<BackgroundRow*>(this)->updateImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect BackgroundRow::radialRect() const {
|
|
||||||
return QRect(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundRow::radialStart() {
|
|
||||||
if (radialLoading() && !_radial.animating()) {
|
|
||||||
_radial.start(radialProgress());
|
|
||||||
if (auto shift = radialTimeShift()) {
|
|
||||||
_radial.update(radialProgress(), !radialLoading(), getms() + shift);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeMs BackgroundRow::radialTimeShift() const {
|
|
||||||
return st::radialDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundRow::step_radial(TimeMs ms, bool timer) {
|
|
||||||
_radial.update(radialProgress(), !radialLoading(), ms + radialTimeShift());
|
|
||||||
if (timer && _radial.animating()) {
|
|
||||||
rtlupdate(radialRect());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundRow::updateImage() {
|
|
||||||
int32 size = st::settingsBackgroundSize * cIntRetinaFactor();
|
|
||||||
QImage back(size, size, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
back.setDevicePixelRatio(cRetinaFactor());
|
|
||||||
{
|
|
||||||
Painter p(&back);
|
|
||||||
PainterHighQualityEnabler hq(p);
|
|
||||||
|
|
||||||
auto &pix = Window::Theme::Background()->pixmap();
|
|
||||||
int sx = (pix.width() > pix.height()) ? ((pix.width() - pix.height()) / 2) : 0;
|
|
||||||
int sy = (pix.height() > pix.width()) ? ((pix.height() - pix.width()) / 2) : 0;
|
|
||||||
int s = (pix.width() > pix.height()) ? pix.height() : pix.width();
|
|
||||||
p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, sx, sy, s, s);
|
|
||||||
}
|
|
||||||
Images::prepareRound(back, ImageRoundRadius::Small);
|
|
||||||
_background = App::pixmapFromImageInPlace(std::move(back));
|
|
||||||
_background.setDevicePixelRatio(cRetinaFactor());
|
|
||||||
|
|
||||||
rtlupdate(radialRect());
|
|
||||||
|
|
||||||
if (radialLoading()) {
|
|
||||||
radialStart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BackgroundWidget::BackgroundWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_background)) {
|
|
||||||
createControls();
|
|
||||||
|
|
||||||
using Update = Window::Theme::BackgroundUpdate;
|
|
||||||
subscribe(Window::Theme::Background(), [this](const Update &update) {
|
|
||||||
if (update.type == Update::Type::New) {
|
|
||||||
_background->updateImage();
|
|
||||||
} else if (update.type == Update::Type::Start
|
|
||||||
|| update.type == Update::Type::Changed) {
|
|
||||||
needBackgroundUpdate(update.tiled);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
subscribe(Adaptive::Changed(), [this]() {
|
|
||||||
_adaptive->toggle(
|
|
||||||
(Global::AdaptiveChatLayout() == Adaptive::ChatLayout::Wide),
|
|
||||||
anim::type::normal);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::createControls() {
|
|
||||||
style::margins margin(0, 0, 0, st::settingsSmallSkip);
|
|
||||||
style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2));
|
|
||||||
|
|
||||||
createChildRow(_background, margin);
|
|
||||||
connect(_background, SIGNAL(chooseFromGallery()), this, SLOT(onChooseFromGallery()));
|
|
||||||
connect(_background, SIGNAL(chooseFromFile()), this, SLOT(onChooseFromFile()));
|
|
||||||
connect(_background, SIGNAL(editTheme()), this, SLOT(onEditTheme()));
|
|
||||||
connect(_background, SIGNAL(useDefault()), this, SLOT(onUseDefaultTheme()));
|
|
||||||
|
|
||||||
createChildRow(_tile, margin, lang(lng_settings_bg_tile), [this](bool) { onTile(); }, Window::Theme::Background()->tile());
|
|
||||||
createChildRow(_adaptive, margin, slidedPadding, lang(lng_settings_adaptive_wide), [this](bool) { onAdaptive(); }, Global::AdaptiveForWide());
|
|
||||||
if (Global::AdaptiveChatLayout() != Adaptive::ChatLayout::Wide) {
|
|
||||||
_adaptive->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::onChooseFromGallery() {
|
|
||||||
Ui::show(Box<BackgroundBox>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::needBackgroundUpdate(bool tile) {
|
|
||||||
_tile->setChecked(tile);
|
|
||||||
_background->updateImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::onChooseFromFile() {
|
|
||||||
auto imgExtensions = cImgExtensions();
|
|
||||||
auto filters = QStringList(qsl("Theme files (*.tdesktop-theme *.tdesktop-palette *") + imgExtensions.join(qsl(" *")) + qsl(")"));
|
|
||||||
filters.push_back(FileDialog::AllFilesFilter());
|
|
||||||
const auto callback = [=](const FileDialog::OpenResult &result) {
|
|
||||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result.paths.isEmpty()) {
|
|
||||||
auto filePath = result.paths.front();
|
|
||||||
if (filePath.endsWith(qstr(".tdesktop-theme"), Qt::CaseInsensitive)
|
|
||||||
|| filePath.endsWith(qstr(".tdesktop-palette"), Qt::CaseInsensitive)) {
|
|
||||||
Window::Theme::Apply(filePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage img;
|
|
||||||
if (!result.remoteContent.isEmpty()) {
|
|
||||||
img = App::readImage(result.remoteContent);
|
|
||||||
} else {
|
|
||||||
img = App::readImage(result.paths.front());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (img.isNull() || img.width() <= 0 || img.height() <= 0) return;
|
|
||||||
|
|
||||||
if (img.width() > 4096 * img.height()) {
|
|
||||||
img = img.copy((img.width() - 4096 * img.height()) / 2, 0, 4096 * img.height(), img.height());
|
|
||||||
} else if (img.height() > 4096 * img.width()) {
|
|
||||||
img = img.copy(0, (img.height() - 4096 * img.width()) / 2, img.width(), 4096 * img.width());
|
|
||||||
}
|
|
||||||
|
|
||||||
Window::Theme::Background()->setImage(Window::Theme::kCustomBackground, std::move(img));
|
|
||||||
_tile->setChecked(false);
|
|
||||||
_background->updateImage();
|
|
||||||
};
|
|
||||||
FileDialog::GetOpenPath(
|
|
||||||
this,
|
|
||||||
lang(lng_choose_image),
|
|
||||||
filters.join(qsl(";;")),
|
|
||||||
crl::guard(this, callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::onEditTheme() {
|
|
||||||
Window::Theme::Editor::Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::onUseDefaultTheme() {
|
|
||||||
Window::Theme::ApplyDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::onTile() {
|
|
||||||
Window::Theme::Background()->setTile(_tile->checked());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackgroundWidget::onAdaptive() {
|
|
||||||
if (Global::AdaptiveForWide() != _adaptive->entity()->checked()) {
|
|
||||||
Global::SetAdaptiveForWide(_adaptive->entity()->checked());
|
|
||||||
Adaptive::Changed().notify();
|
|
||||||
Local::writeUserSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
#include "ui/effects/radial_animation.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class BackgroundRow : public Ui::RpWidget, private base::Subscriber {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
BackgroundRow(QWidget *parent);
|
|
||||||
|
|
||||||
void updateImage();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void chooseFromGallery();
|
|
||||||
void chooseFromFile();
|
|
||||||
void editTheme();
|
|
||||||
void useDefault();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void checkNonDefaultTheme();
|
|
||||||
|
|
||||||
float64 radialProgress() const;
|
|
||||||
bool radialLoading() const;
|
|
||||||
QRect radialRect() const;
|
|
||||||
void radialStart();
|
|
||||||
TimeMs radialTimeShift() const;
|
|
||||||
void step_radial(TimeMs ms, bool timer);
|
|
||||||
|
|
||||||
QPixmap _background;
|
|
||||||
object_ptr<Ui::LinkButton> _useDefaultTheme = { nullptr };
|
|
||||||
object_ptr<Ui::LinkButton> _chooseFromGallery;
|
|
||||||
object_ptr<Ui::LinkButton> _chooseFromFile;
|
|
||||||
object_ptr<Ui::LinkButton> _editTheme;
|
|
||||||
|
|
||||||
Ui::RadialAnimation _radial;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class BackgroundWidget : public BlockWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
BackgroundWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onChooseFromGallery();
|
|
||||||
void onChooseFromFile();
|
|
||||||
void onEditTheme();
|
|
||||||
void onUseDefaultTheme();
|
|
||||||
void onTile();
|
|
||||||
void onAdaptive();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void createControls();
|
|
||||||
void needBackgroundUpdate(bool tile);
|
|
||||||
|
|
||||||
BackgroundRow *_background = nullptr;
|
|
||||||
Ui::Checkbox *_tile = nullptr;
|
|
||||||
Ui::SlideWrap<Ui::Checkbox> *_adaptive = nullptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/wrap/vertical_layout.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
BlockWidget::BlockWidget(QWidget *parent, UserData *self, const QString &title) : RpWidget(parent)
|
|
||||||
, _content(this)
|
|
||||||
, _self(self)
|
|
||||||
, _title(title) {
|
|
||||||
_content->heightValue(
|
|
||||||
) | rpl::start_with_next([this](int contentHeight) {
|
|
||||||
resize(
|
|
||||||
width(),
|
|
||||||
contentTop()
|
|
||||||
+ contentHeight
|
|
||||||
+ st::settingsBlockMarginBottom);
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockWidget::setContentLeft(int contentLeft) {
|
|
||||||
_contentLeft = contentLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BlockWidget::contentTop() const {
|
|
||||||
return emptyTitle() ? 0 : (st::settingsBlockMarginTop + st::settingsBlockTitleHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
int BlockWidget::resizeGetHeight(int newWidth) {
|
|
||||||
int x = contentLeft(), result = contentTop();
|
|
||||||
int availw = newWidth - x;
|
|
||||||
|
|
||||||
auto margins = getMargins();
|
|
||||||
|
|
||||||
_content->resizeToWidth(availw);
|
|
||||||
_content->moveToLeft(margins.left() + x, margins.top() + result, newWidth);
|
|
||||||
result += _content->heightNoMargins() + st::settingsBlockMarginBottom;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMargins BlockWidget::getMargins() const {
|
|
||||||
auto result = _content->getMargins();
|
|
||||||
return QMargins(
|
|
||||||
result.left(),
|
|
||||||
qMax(result.top() - contentTop(), 0),
|
|
||||||
result.right(),
|
|
||||||
qMax(result.bottom() - st::settingsBlockMarginBottom, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockWidget::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
|
|
||||||
paintTitle(p);
|
|
||||||
paintContents(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockWidget::paintTitle(Painter &p) {
|
|
||||||
if (emptyTitle()) return;
|
|
||||||
|
|
||||||
p.setFont(st::settingsBlockTitleFont);
|
|
||||||
p.setPen(st::settingsBlockTitleFg);
|
|
||||||
auto margins = getMargins();
|
|
||||||
auto titleTop = st::settingsBlockMarginTop + st::settingsBlockTitleTop;
|
|
||||||
p.drawTextLeft(
|
|
||||||
margins.left() + contentLeft(),
|
|
||||||
margins.top() + titleTop,
|
|
||||||
width(),
|
|
||||||
_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ui::RpWidget *BlockWidget::addCreatedRow(
|
|
||||||
object_ptr<RpWidget> row,
|
|
||||||
const style::margins &margin) {
|
|
||||||
return _content->add(std::move(row), margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockWidget::createChildWidget(
|
|
||||||
object_ptr<Ui::Checkbox> &child,
|
|
||||||
style::margins &margin,
|
|
||||||
const QString &text,
|
|
||||||
Fn<void(bool checked)> callback,
|
|
||||||
bool checked) {
|
|
||||||
child.create(this, text, checked, st::defaultBoxCheckbox);
|
|
||||||
subscribe(child->checkedChanged, std::move(callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockWidget::createChildWidget(
|
|
||||||
object_ptr<Ui::LinkButton> &child,
|
|
||||||
style::margins &margin,
|
|
||||||
const QString &text,
|
|
||||||
const char *slot,
|
|
||||||
const style::LinkButton &st) {
|
|
||||||
child.create(this, text, st);
|
|
||||||
connect(child, SIGNAL(clicked()), this, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "base/observer.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class Checkbox;
|
|
||||||
class RadiobuttonGroup;
|
|
||||||
class Radiobutton;
|
|
||||||
class LinkButton;
|
|
||||||
template <typename Enum>
|
|
||||||
class RadioenumGroup;
|
|
||||||
template <typename Enum>
|
|
||||||
class Radioenum;
|
|
||||||
template <typename Widget>
|
|
||||||
class SlideWrap;
|
|
||||||
class VerticalLayout;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class BlockWidget : public Ui::RpWidget, protected base::Subscriber {
|
|
||||||
public:
|
|
||||||
BlockWidget(QWidget *parent, UserData *self, const QString &title);
|
|
||||||
|
|
||||||
void setContentLeft(int contentLeft);
|
|
||||||
|
|
||||||
QMargins getMargins() const override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
virtual void paintContents(Painter &p) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Where does the block content start (after the title).
|
|
||||||
int contentLeft() const {
|
|
||||||
return _contentLeft;
|
|
||||||
}
|
|
||||||
int contentTop() const;
|
|
||||||
|
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
UserData *self() const {
|
|
||||||
return _self;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool emptyTitle() const {
|
|
||||||
return _title.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Widget, typename ...Args>
|
|
||||||
void createChildRow(
|
|
||||||
Widget *&child,
|
|
||||||
style::margins margin,
|
|
||||||
Args&&... args) {
|
|
||||||
auto row = object_ptr<Widget>{ nullptr };
|
|
||||||
createChildWidget(row, margin, std::forward<Args>(args)...);
|
|
||||||
child = static_cast<Widget*>(addCreatedRow(
|
|
||||||
std::move(row),
|
|
||||||
margin));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename Widget, typename ...Args>
|
|
||||||
void createChildWidget(
|
|
||||||
object_ptr<Ui::SlideWrap<Widget>> &child,
|
|
||||||
style::margins &margin,
|
|
||||||
const style::margins &padding,
|
|
||||||
Args&&... args) {
|
|
||||||
object_ptr<Widget> entity = { nullptr };
|
|
||||||
createChildWidget(entity, margin, std::forward<Args>(args)...);
|
|
||||||
child.create(this, std::move(entity), padding);
|
|
||||||
margin.setLeft(margin.left() - padding.left());
|
|
||||||
margin.setTop(margin.top() - padding.top());
|
|
||||||
margin.setRight(margin.right() - padding.right());
|
|
||||||
margin.setBottom(margin.bottom() - padding.bottom());
|
|
||||||
}
|
|
||||||
void createChildWidget(
|
|
||||||
object_ptr<Ui::Checkbox> &child,
|
|
||||||
style::margins &margin,
|
|
||||||
const QString &text, Fn<void(bool checked)> callback, bool checked);
|
|
||||||
void createChildWidget(
|
|
||||||
object_ptr<Ui::LinkButton> &child,
|
|
||||||
style::margins &margin,
|
|
||||||
const QString &text,
|
|
||||||
const char *slot,
|
|
||||||
const style::LinkButton &st = st::boxLinkButton);
|
|
||||||
|
|
||||||
template <typename Enum>
|
|
||||||
void createChildWidget(
|
|
||||||
object_ptr<Ui::Radioenum<Enum>> &child,
|
|
||||||
style::margins &margin,
|
|
||||||
const std::shared_ptr<Ui::RadioenumGroup<Enum>> &group,
|
|
||||||
Enum value,
|
|
||||||
const QString &text) {
|
|
||||||
child.create(
|
|
||||||
this,
|
|
||||||
group,
|
|
||||||
value,
|
|
||||||
text,
|
|
||||||
st::defaultBoxCheckbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
RpWidget *addCreatedRow(
|
|
||||||
object_ptr<RpWidget> row,
|
|
||||||
const style::margins &margin);
|
|
||||||
|
|
||||||
template <typename Widget>
|
|
||||||
struct IsSlideWrap : std::false_type {
|
|
||||||
};
|
|
||||||
template <typename Widget>
|
|
||||||
struct IsSlideWrap<Ui::SlideWrap<Widget>> : std::true_type {
|
|
||||||
};
|
|
||||||
template <typename Widget>
|
|
||||||
struct IsRadioenum : std::false_type {
|
|
||||||
};
|
|
||||||
template <typename Enum>
|
|
||||||
struct IsRadioenum<Ui::Radioenum<Enum>> : std::true_type {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Widget>
|
|
||||||
using NotImplementedYet = std::enable_if_t<
|
|
||||||
!IsSlideWrap<Widget>::value &&
|
|
||||||
!IsRadioenum<Widget>::value &&
|
|
||||||
!std::is_same<Ui::Checkbox, Widget>::value &&
|
|
||||||
!std::is_same<Ui::LinkButton, Widget>::value>;
|
|
||||||
|
|
||||||
template <typename Widget, typename... Args, typename = NotImplementedYet<Widget>>
|
|
||||||
void createChildWidget(object_ptr<Widget> &child, style::margins &margin, Args&&... args) {
|
|
||||||
child.create(this, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintTitle(Painter &p);
|
|
||||||
|
|
||||||
object_ptr<Ui::VerticalLayout> _content;
|
|
||||||
|
|
||||||
int _contentLeft = 0;
|
|
||||||
UserData *_self;
|
|
||||||
QString _title;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,213 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_chat_settings_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/widgets/labels.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "mainwidget.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "boxes/stickers_box.h"
|
|
||||||
#include "boxes/download_path_box.h"
|
|
||||||
#include "boxes/connection_box.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &text, Type type, const char *slot) : RpWidget(parent)
|
|
||||||
, _label(this, label, Ui::FlatLabel::InitType::Simple, (type == Type::Primary) ? st::settingsPrimaryLabel : st::defaultFlatLabel)
|
|
||||||
, _link(this, text, (type == Type::Primary) ? st::boxLinkButton : st::defaultLinkButton) {
|
|
||||||
connect(_link, SIGNAL(clicked()), parent, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ui::LinkButton *LabeledLink::link() const {
|
|
||||||
return _link;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LabeledLink::naturalWidth() const {
|
|
||||||
return _label->naturalWidth() + st::normalFont->spacew + _link->naturalWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
int LabeledLink::resizeGetHeight(int newWidth) {
|
|
||||||
_label->moveToLeft(0, 0, newWidth);
|
|
||||||
_link->resizeToWidth(newWidth - st::normalFont->spacew - _label->width());
|
|
||||||
_link->moveToLeft(_label->width() + st::normalFont->spacew, 0, newWidth);
|
|
||||||
return _label->height();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
DownloadPathState::DownloadPathState(QWidget *parent) : RpWidget(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::Hard::ClearPathFailed();
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
})();
|
|
||||||
if (!text.isEmpty()) {
|
|
||||||
p.setFont(st::linkFont);
|
|
||||||
p.setPen(st::windowFg);
|
|
||||||
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::show(Box<DownloadPathBox>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DownloadPathState::onClear() {
|
|
||||||
Ui::show(Box<ConfirmBox>(lang(lng_sure_clear_downloads), crl::guard(this, [this] {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
#endif // OS_WIN_STORE
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
createChildRow(_replaceEmoji, marginSmall, lang(lng_settings_replace_emojis), [this](bool) { toggleReplaceEmoji(); }, Global::ReplaceEmoji());
|
|
||||||
createChildRow(_suggestEmoji, marginSmall, lang(lng_settings_suggest_emoji), [this](bool) { toggleSuggestEmoji(); }, Global::SuggestEmoji());
|
|
||||||
createChildRow(_suggestByEmoji, marginSkip, lang(lng_settings_suggest_by_emoji), [this](bool) { toggleSuggestStickersByEmoji(); }, Global::SuggestStickersByEmoji());
|
|
||||||
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
auto pathMargin = marginSub;
|
|
||||||
#else // OS_WIN_STORE
|
|
||||||
auto pathMargin = marginSkip;
|
|
||||||
#endif // OS_WIN_STORE
|
|
||||||
createChildRow(_dontAskDownloadPath, pathMargin, lang(lng_download_path_dont_ask), [this](bool) { onDontAskDownloadPath(); }, !Global::AskDownloadPath());
|
|
||||||
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
style::margins marginPath(st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip);
|
|
||||||
createChildRow(_downloadPath, marginPath, slidedPadding);
|
|
||||||
if (Global::AskDownloadPath()) {
|
|
||||||
_downloadPath->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
#endif // OS_WIN_STORE
|
|
||||||
|
|
||||||
auto group = std::make_shared<Ui::RadioenumGroup<SendByType>>(cCtrlEnter() ? SendByType::CtrlEnter : SendByType::Enter);
|
|
||||||
createChildRow(_sendByEnter, marginSmall, group, SendByType::Enter, lang(lng_settings_send_enter));
|
|
||||||
createChildRow(_sendByCtrlEnter, marginSkip, group, SendByType::CtrlEnter, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter));
|
|
||||||
group->setChangedCallback([this](SendByType value) {
|
|
||||||
sendByChanged(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
createChildRow(_automaticMediaDownloadSettings, marginSmall, lang(lng_media_auto_settings), SLOT(onAutomaticMediaDownloadSettings()));
|
|
||||||
createChildRow(_manageStickerSets, marginSmall, lang(lng_stickers_you_have), SLOT(onManageStickerSets()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatSettingsWidget::toggleReplaceEmoji() {
|
|
||||||
Global::SetReplaceEmoji(_replaceEmoji->checked());
|
|
||||||
Global::RefReplaceEmojiChanged().notify();
|
|
||||||
Local::writeUserSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatSettingsWidget::toggleSuggestEmoji() {
|
|
||||||
Global::SetSuggestEmoji(_suggestEmoji->checked());
|
|
||||||
Local::writeUserSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatSettingsWidget::toggleSuggestStickersByEmoji() {
|
|
||||||
Global::SetSuggestStickersByEmoji(_suggestByEmoji->checked());
|
|
||||||
Local::writeUserSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatSettingsWidget::onDontAskDownloadPath() {
|
|
||||||
Global::SetAskDownloadPath(!_dontAskDownloadPath->checked());
|
|
||||||
Local::writeUserSettings();
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
_downloadPath->toggle(
|
|
||||||
_dontAskDownloadPath->checked(),
|
|
||||||
anim::type::normal);
|
|
||||||
#endif // OS_WIN_STORE
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatSettingsWidget::sendByChanged(SendByType value) {
|
|
||||||
cSetCtrlEnter(value == SendByType::CtrlEnter);
|
|
||||||
if (App::main()) App::main()->ctrlEnterSubmitUpdated();
|
|
||||||
Local::writeUserSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatSettingsWidget::onAutomaticMediaDownloadSettings() {
|
|
||||||
Ui::show(Box<AutoDownloadBox>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatSettingsWidget::onManageStickerSets() {
|
|
||||||
Ui::show(Box<StickersBox>(StickersBox::Section::Installed));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class FlatLabel;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class LabeledLink : public Ui::RpWidget {
|
|
||||||
public:
|
|
||||||
enum class Type {
|
|
||||||
Primary,
|
|
||||||
Secondary,
|
|
||||||
};
|
|
||||||
LabeledLink(QWidget *parent, const QString &label, const QString &text, Type type, const char *slot);
|
|
||||||
|
|
||||||
Ui::LinkButton *link() const;
|
|
||||||
|
|
||||||
int naturalWidth() const override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
object_ptr<Ui::FlatLabel> _label;
|
|
||||||
object_ptr<Ui::LinkButton> _link;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
class DownloadPathState : public Ui::RpWidget, private 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 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;
|
|
||||||
|
|
||||||
object_ptr<LabeledLink> _path;
|
|
||||||
object_ptr<Ui::LinkButton> _clear;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // OS_WIN_STORE
|
|
||||||
|
|
||||||
class ChatSettingsWidget : public BlockWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
ChatSettingsWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onDontAskDownloadPath();
|
|
||||||
void onAutomaticMediaDownloadSettings();
|
|
||||||
void onManageStickerSets();
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class SendByType {
|
|
||||||
Enter,
|
|
||||||
CtrlEnter,
|
|
||||||
};
|
|
||||||
void sendByChanged(SendByType value);
|
|
||||||
void createControls();
|
|
||||||
|
|
||||||
void toggleReplaceEmoji();
|
|
||||||
void toggleSuggestEmoji();
|
|
||||||
void toggleSuggestStickersByEmoji();
|
|
||||||
|
|
||||||
Ui::Checkbox *_replaceEmoji = nullptr;
|
|
||||||
Ui::Checkbox *_suggestEmoji = nullptr;
|
|
||||||
Ui::Checkbox *_suggestByEmoji = nullptr;
|
|
||||||
Ui::Checkbox *_dontAskDownloadPath = nullptr;
|
|
||||||
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
Ui::SlideWrap<DownloadPathState> *_downloadPath = nullptr;
|
|
||||||
#endif // OS_WIN_STORE
|
|
||||||
|
|
||||||
Ui::Radioenum<SendByType> *_sendByEnter = nullptr;
|
|
||||||
Ui::Radioenum<SendByType> *_sendByCtrlEnter = nullptr;
|
|
||||||
Ui::LinkButton *_automaticMediaDownloadSettings = nullptr;
|
|
||||||
Ui::LinkButton *_manageStickerSets = nullptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,382 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_cover.h"
|
|
||||||
|
|
||||||
#include "data/data_photo.h"
|
|
||||||
#include "data/data_session.h"
|
|
||||||
#include "ui/widgets/labels.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/special_buttons.h"
|
|
||||||
#include "observer_peer.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "messenger.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "apiwrap.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
#include "profile/profile_cover_drop_area.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
#include "boxes/photo_crop_box.h"
|
|
||||||
#include "boxes/add_contact_box.h"
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "styles/style_profile.h" // for divider
|
|
||||||
#include "platform/platform_file_utilities.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
CoverWidget::CoverWidget(QWidget *parent, UserData *self)
|
|
||||||
: BlockWidget(parent, self, QString())
|
|
||||||
, _self(self)
|
|
||||||
, _userpicButton(
|
|
||||||
this,
|
|
||||||
App::wnd()->controller(),
|
|
||||||
_self,
|
|
||||||
Ui::UserpicButton::Role::OpenPhoto,
|
|
||||||
st::settingsPhoto)
|
|
||||||
, _name(this, st::settingsNameLabel)
|
|
||||||
, _editNameInline(this, st::settingsEditButton)
|
|
||||||
, _setPhoto(this, langFactory(lng_settings_upload), st::settingsPrimaryButton)
|
|
||||||
, _editName(this, langFactory(lng_settings_edit), st::settingsSecondaryButton) {
|
|
||||||
if (_self) {
|
|
||||||
_self->updateFull();
|
|
||||||
}
|
|
||||||
setAcceptDrops(true);
|
|
||||||
|
|
||||||
_name->setSelectable(true);
|
|
||||||
_name->setContextCopyText(lang(lng_profile_copy_fullname));
|
|
||||||
|
|
||||||
_setPhoto->setClickedCallback(App::LambdaDelayed(
|
|
||||||
st::settingsPrimaryButton.ripple.hideDuration,
|
|
||||||
this,
|
|
||||||
[this] { chooseNewPhoto(); }));
|
|
||||||
_editName->addClickHandler([this] { editName(); });
|
|
||||||
_editNameInline->addClickHandler([this] { editName(); });
|
|
||||||
|
|
||||||
auto observeEvents = Notify::PeerUpdate::Flag::NameChanged | Notify::PeerUpdate::Flag::PhotoChanged;
|
|
||||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
|
||||||
notifyPeerUpdated(update);
|
|
||||||
}));
|
|
||||||
|
|
||||||
_userpicButton->addClickHandler([this] { showPhoto(); });
|
|
||||||
validatePhoto();
|
|
||||||
|
|
||||||
refreshNameText();
|
|
||||||
|
|
||||||
subscribe(Global::RefConnectionTypeChanged(), [this] { refreshStatusText(); });
|
|
||||||
refreshStatusText();
|
|
||||||
}
|
|
||||||
|
|
||||||
PhotoData *CoverWidget::validatePhoto() const {
|
|
||||||
Expects(_self != nullptr);
|
|
||||||
|
|
||||||
const auto photo = _self->userpicPhotoId()
|
|
||||||
? Auth().data().photo(_self->userpicPhotoId()).get()
|
|
||||||
: nullptr;
|
|
||||||
_userpicButton->setPointerCursor(photo != nullptr && photo->date != 0);
|
|
||||||
if (_self->userpicPhotoUnknown() || (photo && !photo->date)) {
|
|
||||||
Auth().api().requestFullPeer(_self);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return photo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::showPhoto() {
|
|
||||||
if (const auto photo = validatePhoto()) {
|
|
||||||
Messenger::Instance().showPhoto(photo, _self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::cancelPhotoUpload() {
|
|
||||||
refreshStatusText();
|
|
||||||
}
|
|
||||||
|
|
||||||
int CoverWidget::resizeGetHeight(int newWidth) {
|
|
||||||
int newHeight = 0;
|
|
||||||
|
|
||||||
newHeight += st::settingsMarginTop;
|
|
||||||
|
|
||||||
auto margins = getMargins();
|
|
||||||
_userpicButton->moveToLeft(
|
|
||||||
margins.left() + contentLeft() + st::settingsPhotoLeft,
|
|
||||||
margins.top() + newHeight,
|
|
||||||
newWidth);
|
|
||||||
|
|
||||||
int infoLeft = _userpicButton->x() + _userpicButton->width();
|
|
||||||
_statusPosition = QPoint(infoLeft + st::settingsStatusLeft, _userpicButton->y() + st::settingsStatusTop);
|
|
||||||
if (_cancelPhotoUpload) {
|
|
||||||
_cancelPhotoUpload->moveToLeft(
|
|
||||||
margins.left()
|
|
||||||
+ _statusPosition.x()
|
|
||||||
+ st::settingsStatusFont->width(_statusText)
|
|
||||||
+ st::settingsStatusFont->spacew,
|
|
||||||
margins.top() + _statusPosition.y(),
|
|
||||||
newWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshButtonsGeometry(newWidth);
|
|
||||||
refreshNameGeometry(newWidth);
|
|
||||||
|
|
||||||
newHeight += st::settingsPhoto.size.height();
|
|
||||||
newHeight += st::settingsMarginBottom;
|
|
||||||
|
|
||||||
_dividerTop = newHeight;
|
|
||||||
newHeight += st::profileDividerLeft.height();
|
|
||||||
|
|
||||||
newHeight += st::settingsBlocksTop;
|
|
||||||
|
|
||||||
resizeDropArea();
|
|
||||||
return newHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::refreshButtonsGeometry(int newWidth) {
|
|
||||||
auto margins = getMargins();
|
|
||||||
auto buttonLeft = margins.left() + _userpicButton->x() + _userpicButton->width() + st::settingsButtonLeft;
|
|
||||||
_setPhoto->moveToLeft(
|
|
||||||
buttonLeft,
|
|
||||||
margins.top() + _userpicButton->y() + st::settingsButtonTop,
|
|
||||||
newWidth);
|
|
||||||
buttonLeft += _setPhoto->width() + st::settingsButtonSkip;
|
|
||||||
_editName->moveToLeft(
|
|
||||||
buttonLeft,
|
|
||||||
margins.top() + _setPhoto->y(),
|
|
||||||
newWidth);
|
|
||||||
_editNameVisible = (buttonLeft + _editName->width() + st::settingsButtonSkip <= newWidth);
|
|
||||||
_editName->setVisible(_editNameVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::refreshNameGeometry(int newWidth) {
|
|
||||||
auto margins = getMargins();
|
|
||||||
auto infoLeft = _userpicButton->x() + _userpicButton->width();
|
|
||||||
auto nameLeft = infoLeft + st::settingsNameLeft;
|
|
||||||
auto nameTop = _userpicButton->y() + st::settingsNameTop;
|
|
||||||
auto nameWidth = newWidth - infoLeft - st::settingsNameLeft;
|
|
||||||
auto editNameInlineVisible = !_editNameVisible;
|
|
||||||
if (editNameInlineVisible) {
|
|
||||||
nameWidth -= _editNameInline->width();
|
|
||||||
}
|
|
||||||
|
|
||||||
_name->resizeToNaturalWidth(nameWidth);
|
|
||||||
_name->moveToLeft(
|
|
||||||
margins.left() + nameLeft,
|
|
||||||
margins.top() + nameTop,
|
|
||||||
newWidth);
|
|
||||||
|
|
||||||
_editNameInline->moveToLeft(
|
|
||||||
margins.left() + nameLeft + _name->widthNoMargins() + st::settingsNameLabel.margin.right(),
|
|
||||||
margins.top() + nameTop - st::settingsNameLabel.margin.top(),
|
|
||||||
newWidth);
|
|
||||||
_editNameInline->setVisible(editNameInlineVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::paintContents(Painter &p) {
|
|
||||||
p.setFont(st::settingsStatusFont);
|
|
||||||
p.setPen(_statusTextIsOnline ? st::settingsStatusFgActive : st::settingsStatusFg);
|
|
||||||
p.drawTextLeft(_statusPosition.x(), _statusPosition.y(), width(), _statusText);
|
|
||||||
|
|
||||||
paintDivider(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::resizeDropArea() {
|
|
||||||
if (_dropArea) {
|
|
||||||
_dropArea->setGeometry(0, 0, width(), _dividerTop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::dropAreaHidden(Profile::CoverDropArea *dropArea) {
|
|
||||||
if (_dropArea == dropArea) {
|
|
||||||
_dropArea.destroyDelayed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CoverWidget::mimeDataHasImage(const QMimeData *mimeData) const {
|
|
||||||
if (!mimeData) return false;
|
|
||||||
|
|
||||||
if (mimeData->hasImage()) return true;
|
|
||||||
|
|
||||||
auto uriListFormat = qsl("text/uri-list");
|
|
||||||
if (!mimeData->hasFormat(uriListFormat)) return false;
|
|
||||||
|
|
||||||
const auto &urls = mimeData->urls();
|
|
||||||
if (urls.size() != 1) return false;
|
|
||||||
|
|
||||||
auto &url = urls.at(0);
|
|
||||||
if (!url.isLocalFile()) return false;
|
|
||||||
|
|
||||||
auto file = Platform::File::UrlToLocal(url);
|
|
||||||
|
|
||||||
QFileInfo info(file);
|
|
||||||
if (info.isDir()) return false;
|
|
||||||
|
|
||||||
if (info.size() > App::kImageSizeLimit) return false;
|
|
||||||
|
|
||||||
for (auto &ext : cImgExtensions()) {
|
|
||||||
if (file.endsWith(ext, Qt::CaseInsensitive)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::dragEnterEvent(QDragEnterEvent *e) {
|
|
||||||
if (!mimeDataHasImage(e->mimeData())) {
|
|
||||||
e->ignore();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!_dropArea) {
|
|
||||||
auto title = lang(lng_profile_drop_area_title);
|
|
||||||
auto subtitle = lang(lng_settings_drop_area_subtitle);
|
|
||||||
_dropArea.create(this, title, subtitle);
|
|
||||||
resizeDropArea();
|
|
||||||
}
|
|
||||||
_dropArea->showAnimated();
|
|
||||||
e->setDropAction(Qt::CopyAction);
|
|
||||||
e->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::dragLeaveEvent(QDragLeaveEvent *e) {
|
|
||||||
if (_dropArea && !_dropArea->hiding()) {
|
|
||||||
_dropArea->hideAnimated([this](Profile::CoverDropArea *area) { dropAreaHidden(area); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::dropEvent(QDropEvent *e) {
|
|
||||||
auto mimeData = e->mimeData();
|
|
||||||
|
|
||||||
QImage img;
|
|
||||||
if (mimeData->hasImage()) {
|
|
||||||
img = qvariant_cast<QImage>(mimeData->imageData());
|
|
||||||
} else {
|
|
||||||
auto urls = mimeData->urls();
|
|
||||||
if (urls.size() == 1) {
|
|
||||||
auto &url = urls.at(0);
|
|
||||||
if (url.isLocalFile()) {
|
|
||||||
img = App::readImage(Platform::File::UrlToLocal(url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_dropArea->hiding()) {
|
|
||||||
_dropArea->hideAnimated([this](Profile::CoverDropArea *area) { dropAreaHidden(area); });
|
|
||||||
}
|
|
||||||
e->acceptProposedAction();
|
|
||||||
|
|
||||||
showSetPhotoBox(img);
|
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::paintDivider(Painter &p) {
|
|
||||||
auto dividerHeight = st::profileDividerLeft.height();
|
|
||||||
auto divider = rtlrect(0, _dividerTop, width(), dividerHeight, width());
|
|
||||||
p.fillRect(divider, st::profileDividerBg);
|
|
||||||
auto dividerFillTop = rtlrect(0, _dividerTop, width(), st::profileDividerTop.height(), width());
|
|
||||||
st::profileDividerTop.fill(p, dividerFillTop);
|
|
||||||
auto dividerFillBottom = rtlrect(0, _dividerTop + dividerHeight - st::profileDividerBottom.height(), width(), st::profileDividerBottom.height(), width());
|
|
||||||
st::profileDividerBottom.fill(p, dividerFillBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
|
||||||
if (update.peer != _self) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (update.flags & Notify::PeerUpdate::Flag::NameChanged) {
|
|
||||||
refreshNameText();
|
|
||||||
}
|
|
||||||
if (update.flags & Notify::PeerUpdate::Flag::PhotoChanged) {
|
|
||||||
validatePhoto();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::refreshNameText() {
|
|
||||||
_name->setText(App::peerName(_self));
|
|
||||||
refreshNameGeometry(width());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::refreshStatusText() {
|
|
||||||
if (false) {
|
|
||||||
_statusText = lang(lng_settings_uploading_photo);
|
|
||||||
_statusTextIsOnline = false;
|
|
||||||
if (!_cancelPhotoUpload) {
|
|
||||||
auto margins = getMargins();
|
|
||||||
_cancelPhotoUpload.create(this, lang(lng_cancel), st::defaultLinkButton);
|
|
||||||
_cancelPhotoUpload->addClickHandler([this] { cancelPhotoUpload(); });
|
|
||||||
_cancelPhotoUpload->show();
|
|
||||||
_cancelPhotoUpload->moveToLeft(
|
|
||||||
margins.left()
|
|
||||||
+ _statusPosition.x()
|
|
||||||
+ st::settingsStatusFont->width(_statusText)
|
|
||||||
+ st::settingsStatusFont->spacew,
|
|
||||||
margins.top() + _statusPosition.y());
|
|
||||||
}
|
|
||||||
update();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cancelPhotoUpload.destroy();
|
|
||||||
auto state = MTP::dcstate();
|
|
||||||
if (state == MTP::ConnectingState || state == MTP::DisconnectedState || state < 0) {
|
|
||||||
_statusText = lang(lng_status_connecting);
|
|
||||||
_statusTextIsOnline = false;
|
|
||||||
} else {
|
|
||||||
_statusText = lang(lng_status_online);
|
|
||||||
_statusTextIsOnline = true;
|
|
||||||
}
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::chooseNewPhoto() {
|
|
||||||
auto imageExtensions = cImgExtensions();
|
|
||||||
auto filter = qsl("Image files (*") + imageExtensions.join(qsl(" *")) + qsl(");;") + FileDialog::AllFilesFilter();
|
|
||||||
const auto callback = [=](const FileDialog::OpenResult &result) {
|
|
||||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage img;
|
|
||||||
if (!result.remoteContent.isEmpty()) {
|
|
||||||
img = App::readImage(result.remoteContent);
|
|
||||||
} else {
|
|
||||||
img = App::readImage(result.paths.front());
|
|
||||||
}
|
|
||||||
|
|
||||||
showSetPhotoBox(img);
|
|
||||||
};
|
|
||||||
FileDialog::GetOpenPath(
|
|
||||||
this,
|
|
||||||
lang(lng_choose_image),
|
|
||||||
filter,
|
|
||||||
crl::guard(this, callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::editName() {
|
|
||||||
Ui::show(Box<EditNameBox>(self()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::showSetPhotoBox(const QImage &img) {
|
|
||||||
if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) {
|
|
||||||
Ui::show(Box<InformBox>(lang(lng_bad_photo)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto peer = _self;
|
|
||||||
auto box = Ui::show(Box<PhotoCropBox>(img, peer));
|
|
||||||
box->ready(
|
|
||||||
) | rpl::start_with_next([=](QImage &&image) {
|
|
||||||
Auth().api().uploadPeerPhoto(peer, std::move(image));
|
|
||||||
}, box->lifetime());
|
|
||||||
box->boxClosing() | rpl::start_with_next([=] {
|
|
||||||
onPhotoUploadStatusChanged();
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoverWidget::onPhotoUploadStatusChanged(PeerId peerId) {
|
|
||||||
if (!peerId || peerId == _self->id) {
|
|
||||||
refreshStatusText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "base/observer.h"
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class FlatLabel;
|
|
||||||
class RoundButton;
|
|
||||||
class IconButton;
|
|
||||||
class UserpicButton;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace Notify {
|
|
||||||
struct PeerUpdate;
|
|
||||||
} // namespace Notify
|
|
||||||
|
|
||||||
namespace Profile {
|
|
||||||
class CoverDropArea;
|
|
||||||
} // namespace Profile
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class CoverWidget : public BlockWidget {
|
|
||||||
public:
|
|
||||||
CoverWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void dragEnterEvent(QDragEnterEvent *e) override;
|
|
||||||
void dragLeaveEvent(QDragLeaveEvent *e) override;
|
|
||||||
void dropEvent(QDropEvent *e) override;
|
|
||||||
|
|
||||||
void paintContents(Painter &p) override;
|
|
||||||
|
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Observed notifications.
|
|
||||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
|
||||||
|
|
||||||
void showPhoto();
|
|
||||||
void cancelPhotoUpload();
|
|
||||||
void chooseNewPhoto();
|
|
||||||
void editName();
|
|
||||||
|
|
||||||
void onPhotoUploadStatusChanged(PeerId peerId = 0);
|
|
||||||
|
|
||||||
PhotoData *validatePhoto() const;
|
|
||||||
|
|
||||||
void refreshButtonsGeometry(int newWidth);
|
|
||||||
void refreshNameGeometry(int newWidth);
|
|
||||||
void refreshNameText();
|
|
||||||
void refreshStatusText();
|
|
||||||
|
|
||||||
void paintDivider(Painter &p);
|
|
||||||
|
|
||||||
void showSetPhotoBox(const QImage &img);
|
|
||||||
void resizeDropArea();
|
|
||||||
void dropAreaHidden(Profile::CoverDropArea *dropArea);
|
|
||||||
bool mimeDataHasImage(const QMimeData *mimeData) const;
|
|
||||||
|
|
||||||
UserData *_self;
|
|
||||||
|
|
||||||
object_ptr<Ui::UserpicButton> _userpicButton;
|
|
||||||
object_ptr<Profile::CoverDropArea> _dropArea = { nullptr };
|
|
||||||
|
|
||||||
object_ptr<Ui::FlatLabel> _name;
|
|
||||||
object_ptr<Ui::IconButton> _editNameInline;
|
|
||||||
object_ptr<Ui::LinkButton> _cancelPhotoUpload = { nullptr };
|
|
||||||
|
|
||||||
QPoint _statusPosition;
|
|
||||||
QString _statusText;
|
|
||||||
bool _statusTextIsOnline = false;
|
|
||||||
|
|
||||||
object_ptr<Ui::RoundButton> _setPhoto;
|
|
||||||
object_ptr<Ui::RoundButton> _editName;
|
|
||||||
bool _editNameVisible = true;
|
|
||||||
|
|
||||||
int _dividerTop = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_fixed_bar.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
FixedBar::FixedBar(QWidget *parent) : TWidget(parent) {
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FixedBar::setText(const QString &text) {
|
|
||||||
_text = text;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
int FixedBar::resizeGetHeight(int newWidth) {
|
|
||||||
return st::settingsFixedBarHeight - st::boxRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FixedBar::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
|
|
||||||
p.fillRect(e->rect(), st::boxBg);
|
|
||||||
|
|
||||||
p.setFont(st::settingsFixedBarFont);
|
|
||||||
p.setPen(st::windowFg);
|
|
||||||
p.drawTextLeft(st::settingsFixedBarTextPosition.x(), st::settingsFixedBarTextPosition.y() - st::boxRadius, width(), _text);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class IconButton;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class FixedBar : public TWidget {
|
|
||||||
public:
|
|
||||||
FixedBar(QWidget *parent);
|
|
||||||
|
|
||||||
void setText(const QString &text);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString _text;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,314 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_general_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "platform/platform_specific.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "application.h"
|
|
||||||
#include "boxes/language_box.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
#include "boxes/about_box.h"
|
|
||||||
#include "core/file_utilities.h"
|
|
||||||
#include "lang/lang_file_parser.h"
|
|
||||||
#include "lang/lang_cloud_manager.h"
|
|
||||||
#include "messenger.h"
|
|
||||||
#include "core/update_checker.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
UpdateStateRow::UpdateStateRow(QWidget *parent) : RpWidget(parent)
|
|
||||||
, _check(this, lang(lng_settings_check_now))
|
|
||||||
, _restart(this, lang(lng_settings_update_now)) {
|
|
||||||
Expects(!Core::UpdaterDisabled());
|
|
||||||
|
|
||||||
connect(_check, SIGNAL(clicked()), this, SLOT(onCheck()));
|
|
||||||
connect(_restart, SIGNAL(clicked()), this, SIGNAL(restart()));
|
|
||||||
|
|
||||||
_versionText = lng_settings_current_version_label(lt_version, currentVersionText());
|
|
||||||
|
|
||||||
Core::UpdateChecker checker;
|
|
||||||
checker.checking() | rpl::start_with_next([=] {
|
|
||||||
onChecking();
|
|
||||||
}, lifetime());
|
|
||||||
checker.isLatest() | rpl::start_with_next([=] {
|
|
||||||
onLatest();
|
|
||||||
}, lifetime());
|
|
||||||
checker.progress(
|
|
||||||
) | rpl::start_with_next([=](Core::UpdateChecker::Progress progress) {
|
|
||||||
onDownloading(progress.already, progress.size);
|
|
||||||
}, lifetime());
|
|
||||||
checker.failed() | rpl::start_with_next([=] {
|
|
||||||
onFailed();
|
|
||||||
}, lifetime());
|
|
||||||
checker.ready() | rpl::start_with_next([=] {
|
|
||||||
onReady();
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
switch (checker.state()) {
|
|
||||||
case Core::UpdateChecker::State::Download:
|
|
||||||
setState(State::Download, true);
|
|
||||||
setDownloadProgress(checker.already(), checker.size());
|
|
||||||
break;
|
|
||||||
case Core::UpdateChecker::State::Ready:
|
|
||||||
setState(State::Ready, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setState(State::None, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int UpdateStateRow::resizeGetHeight(int newWidth) {
|
|
||||||
auto labelWidth = [](const QString &label) {
|
|
||||||
return st::linkFont->width(label) + st::linkFont->spacew;
|
|
||||||
};
|
|
||||||
auto checkLeft = (_state == State::Latest) ? labelWidth(lang(lng_settings_latest_installed)) : labelWidth(_versionText);
|
|
||||||
auto restartLeft = labelWidth(lang(lng_settings_update_ready));
|
|
||||||
|
|
||||||
_check->resizeToWidth(qMin(newWidth, _check->naturalWidth()));
|
|
||||||
_check->moveToLeft(checkLeft, 0, newWidth);
|
|
||||||
|
|
||||||
_restart->resizeToWidth(qMin(newWidth, _restart->naturalWidth()));
|
|
||||||
_restart->moveToLeft(restartLeft, 0, newWidth);
|
|
||||||
|
|
||||||
return _check->height();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
|
|
||||||
auto text = ([this]() -> QString {
|
|
||||||
switch (_state) {
|
|
||||||
case State::Check: return lang(lng_settings_update_checking);
|
|
||||||
case State::Latest: return lang(lng_settings_latest_installed);
|
|
||||||
case State::Download: return _downloadText;
|
|
||||||
case State::Ready: return lang(lng_settings_update_ready);
|
|
||||||
case State::Fail: return lang(lng_settings_update_fail);
|
|
||||||
default: return _versionText;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
p.setFont(st::linkFont);
|
|
||||||
p.setPen((_state == State::None) ? st::windowFg : st::settingsUpdateFg);
|
|
||||||
p.drawTextLeft(0, 0, width(), text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::onCheck() {
|
|
||||||
if (!cAutoUpdate()) return;
|
|
||||||
|
|
||||||
Core::UpdateChecker checker;
|
|
||||||
|
|
||||||
setState(State::Check);
|
|
||||||
cSetLastUpdateCheck(0);
|
|
||||||
checker.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::setState(State state, bool force) {
|
|
||||||
if (_state != state || force) {
|
|
||||||
_state = state;
|
|
||||||
switch (state) {
|
|
||||||
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());
|
|
||||||
sendSynteticMouseEvent(this, QEvent::MouseMove, Qt::NoButton);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::setDownloadProgress(qint64 ready, qint64 total) {
|
|
||||||
auto readyTenthMb = (ready * 10 / (1024 * 1024)), totalTenthMb = (total * 10 / (1024 * 1024));
|
|
||||||
auto readyStr = QString::number(readyTenthMb / 10) + '.' + QString::number(readyTenthMb % 10);
|
|
||||||
auto totalStr = QString::number(totalTenthMb / 10) + '.' + QString::number(totalTenthMb % 10);
|
|
||||||
auto result = lng_settings_downloading(lt_ready, readyStr, lt_total, totalStr);
|
|
||||||
if (_downloadText != result) {
|
|
||||||
_downloadText = result;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::onChecking() {
|
|
||||||
setState(State::Check);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::onLatest() {
|
|
||||||
setState(State::Latest);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::onDownloading(qint64 ready, qint64 total) {
|
|
||||||
setState(State::Download);
|
|
||||||
setDownloadProgress(ready, total);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::onReady() {
|
|
||||||
setState(State::Ready);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateStateRow::onFailed() {
|
|
||||||
setState(State::Fail);
|
|
||||||
}
|
|
||||||
|
|
||||||
GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_general))
|
|
||||||
, _changeLanguage(this, lang(lng_settings_change_lang), st::boxLinkButton) {
|
|
||||||
connect(_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage()));
|
|
||||||
refreshControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
int GeneralWidget::getUpdateTop() const {
|
|
||||||
// Just scroll to the top of the whole General widget
|
|
||||||
return Core::UpdaterDisabled() ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GeneralWidget::resizeGetHeight(int newWidth) {
|
|
||||||
_changeLanguage->moveToRight(0, st::settingsBlockMarginTop + st::settingsBlockTitleTop + st::settingsBlockTitleFont->ascent - st::defaultLinkButton.font->ascent, newWidth);
|
|
||||||
return BlockWidget::resizeGetHeight(newWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::refreshControls() {
|
|
||||||
style::margins marginSub(0, 0, 0, st::settingsSubSkip);
|
|
||||||
style::margins marginLarge(0, 0, 0, st::settingsLargeSkip);
|
|
||||||
style::margins marginSmall(0, 0, 0, st::settingsSmallSkip);
|
|
||||||
style::margins slidedPadding(0, marginSmall.bottom() / 2, 0, marginSmall.bottom() - (marginSmall.bottom() / 2));
|
|
||||||
|
|
||||||
if (!Core::UpdaterDisabled()) {
|
|
||||||
createChildRow(_updateAutomatically, marginSub, lang(lng_settings_update_automatically), [this](bool) { onUpdateAutomatically(); }, cAutoUpdate());
|
|
||||||
style::margins marginLink(st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip);
|
|
||||||
createChildRow(_updateRow, marginLink, slidedPadding);
|
|
||||||
connect(_updateRow->entity(), SIGNAL(restart()), this, SLOT(onRestart()));
|
|
||||||
if (!cAutoUpdate()) {
|
|
||||||
_updateRow->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cPlatform() == dbipWindows || cSupportTray()) {
|
|
||||||
auto workMode = Global::WorkMode().value();
|
|
||||||
createChildRow(_enableTrayIcon, marginSmall, lang(lng_settings_workmode_tray), [this](bool) { onEnableTrayIcon(); }, (workMode == dbiwmTrayOnly || workMode == dbiwmWindowAndTray));
|
|
||||||
if (cPlatform() == dbipWindows) {
|
|
||||||
createChildRow(_enableTaskbarIcon, marginLarge, lang(lng_settings_workmode_window), [this](bool) { onEnableTaskbarIcon(); }, (workMode == dbiwmWindowOnly || workMode == dbiwmWindowAndTray));
|
|
||||||
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
createChildRow(_autoStart, marginSmall, lang(lng_settings_auto_start), [this](bool) { onAutoStart(); }, cAutoStart());
|
|
||||||
createChildRow(_startMinimized, marginLarge, slidedPadding, lang(lng_settings_start_min), [this](bool) { onStartMinimized(); }, (cStartMinimized() && !Global::LocalPasscode()));
|
|
||||||
subscribe(Global::RefLocalPasscodeChanged(), [this] {
|
|
||||||
_startMinimized->entity()->setChecked(cStartMinimized() && !Global::LocalPasscode());
|
|
||||||
});
|
|
||||||
if (!cAutoStart()) {
|
|
||||||
_startMinimized->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
createChildRow(_addInSendTo, marginSmall, lang(lng_settings_add_sendto), [this](bool) { onAddInSendTo(); }, cSendToMenu());
|
|
||||||
#endif // OS_WIN_STORE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::onChangeLanguage() {
|
|
||||||
if ((_changeLanguage->clickModifiers() & Qt::ShiftModifier) && (_changeLanguage->clickModifiers() & Qt::AltModifier)) {
|
|
||||||
Lang::CurrentCloudManager().switchToLanguage(qsl("custom"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_languagesLoadWaiter = LanguageBox::Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::onRestart() {
|
|
||||||
if (!Core::UpdaterDisabled()) {
|
|
||||||
Core::checkReadyUpdate();
|
|
||||||
}
|
|
||||||
App::restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::onUpdateAutomatically() {
|
|
||||||
Expects(!Core::UpdaterDisabled());
|
|
||||||
|
|
||||||
cSetAutoUpdate(_updateAutomatically->checked());
|
|
||||||
Local::writeSettings();
|
|
||||||
_updateRow->toggle(
|
|
||||||
cAutoUpdate(),
|
|
||||||
anim::type::normal);
|
|
||||||
Core::UpdateChecker checker;
|
|
||||||
if (cAutoUpdate()) {
|
|
||||||
checker.start();
|
|
||||||
} else {
|
|
||||||
checker.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::onEnableTrayIcon() {
|
|
||||||
if ((!_enableTrayIcon->checked() || cPlatform() != dbipWindows) && _enableTaskbarIcon && !_enableTaskbarIcon->checked()) {
|
|
||||||
_enableTaskbarIcon->setChecked(true);
|
|
||||||
} else {
|
|
||||||
updateWorkmode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::onEnableTaskbarIcon() {
|
|
||||||
if (!_enableTrayIcon->checked() && !_enableTaskbarIcon->checked()) {
|
|
||||||
_enableTrayIcon->setChecked(true);
|
|
||||||
} else {
|
|
||||||
updateWorkmode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::updateWorkmode() {
|
|
||||||
auto newMode = (_enableTrayIcon->checked() && (!_enableTaskbarIcon || _enableTaskbarIcon->checked())) ? dbiwmWindowAndTray : (_enableTrayIcon->checked() ? dbiwmTrayOnly : dbiwmWindowOnly);
|
|
||||||
if (Global::WorkMode().value() != newMode && (newMode == dbiwmWindowAndTray || newMode == dbiwmTrayOnly)) {
|
|
||||||
cSetSeenTrayTooltip(false);
|
|
||||||
}
|
|
||||||
Global::RefWorkMode().set(newMode);
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined OS_WIN_STORE
|
|
||||||
void GeneralWidget::onAutoStart() {
|
|
||||||
cSetAutoStart(_autoStart->checked());
|
|
||||||
if (cAutoStart()) {
|
|
||||||
psAutoStart(true);
|
|
||||||
Local::writeSettings();
|
|
||||||
} else {
|
|
||||||
psAutoStart(false);
|
|
||||||
if (_startMinimized->entity()->checked()) {
|
|
||||||
_startMinimized->entity()->setChecked(false);
|
|
||||||
} else {
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_startMinimized->toggle(cAutoStart(), anim::type::normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::onStartMinimized() {
|
|
||||||
auto checked = _startMinimized->entity()->checked();
|
|
||||||
if (Global::LocalPasscode()) {
|
|
||||||
if (checked) {
|
|
||||||
_startMinimized->entity()->setChecked(false);
|
|
||||||
Ui::show(Box<InformBox>(lang(lng_error_start_minimized_passcoded)));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (cStartMinimized() != checked) {
|
|
||||||
cSetStartMinimized(checked);
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralWidget::onAddInSendTo() {
|
|
||||||
cSetSendToMenu(_addInSendTo->checked());
|
|
||||||
psSendToMenu(_addInSendTo->checked());
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
#endif // !OS_WIN_STORE
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
#include "base/binary_guard.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class UpdateStateRow : public Ui::RpWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
UpdateStateRow(QWidget *parent);
|
|
||||||
|
|
||||||
bool isUpdateReady() const {
|
|
||||||
return (_state == State::Ready);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void restart();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onCheck();
|
|
||||||
|
|
||||||
void onChecking();
|
|
||||||
void onLatest();
|
|
||||||
void onDownloading(qint64 ready, qint64 total);
|
|
||||||
void onReady();
|
|
||||||
void onFailed();
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class State {
|
|
||||||
None,
|
|
||||||
Check,
|
|
||||||
Latest,
|
|
||||||
Download,
|
|
||||||
Fail,
|
|
||||||
Ready
|
|
||||||
};
|
|
||||||
void setState(State state, bool force = false);
|
|
||||||
void setDownloadProgress(qint64 ready, qint64 total);
|
|
||||||
|
|
||||||
object_ptr<Ui::LinkButton> _check;
|
|
||||||
object_ptr<Ui::LinkButton> _restart;
|
|
||||||
|
|
||||||
State _state = State::None;
|
|
||||||
QString _downloadText;
|
|
||||||
QString _versionText;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class GeneralWidget : public BlockWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
GeneralWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
int getUpdateTop() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onChangeLanguage();
|
|
||||||
void onUpdateAutomatically();
|
|
||||||
void onEnableTrayIcon();
|
|
||||||
void onEnableTaskbarIcon();
|
|
||||||
|
|
||||||
#ifndef OS_WIN_STORE
|
|
||||||
void onAutoStart();
|
|
||||||
void onStartMinimized();
|
|
||||||
void onAddInSendTo();
|
|
||||||
#endif // !OS_WIN_STORE
|
|
||||||
|
|
||||||
void onRestart();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void refreshControls();
|
|
||||||
void updateWorkmode();
|
|
||||||
|
|
||||||
object_ptr<Ui::LinkButton> _changeLanguage;
|
|
||||||
Ui::Checkbox *_updateAutomatically = nullptr;
|
|
||||||
Ui::SlideWrap<UpdateStateRow> *_updateRow = nullptr;
|
|
||||||
Ui::Checkbox *_enableTrayIcon = nullptr;
|
|
||||||
Ui::Checkbox *_enableTaskbarIcon = nullptr;
|
|
||||||
Ui::Checkbox *_autoStart = nullptr;
|
|
||||||
Ui::SlideWrap<Ui::Checkbox> *_startMinimized = nullptr;
|
|
||||||
Ui::Checkbox *_addInSendTo = nullptr;
|
|
||||||
|
|
||||||
base::binary_guard _languagesLoadWaiter;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,248 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_info_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "ui/widgets/labels.h"
|
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "boxes/username_box.h"
|
|
||||||
#include "boxes/add_contact_box.h"
|
|
||||||
#include "boxes/change_phone_box.h"
|
|
||||||
#include "data/data_session.h"
|
|
||||||
#include "observer_peer.h"
|
|
||||||
#include "messenger.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
|
||||||
|
|
||||||
InfoWidget::InfoWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_info)) {
|
|
||||||
auto observeEvents = UpdateFlag::UsernameChanged | UpdateFlag::UserPhoneChanged | UpdateFlag::AboutChanged;
|
|
||||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
|
||||||
notifyPeerUpdated(update);
|
|
||||||
}));
|
|
||||||
|
|
||||||
createControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::createControls() {
|
|
||||||
style::margins margin(0, 0, 0, 0);
|
|
||||||
style::margins slidedPadding(0, 0, 0, 0);
|
|
||||||
createChildRow(_mobileNumber, margin, slidedPadding, st::settingsBlockOneLineTextPart);
|
|
||||||
createChildRow(_username, margin, slidedPadding, st::settingsBlockOneLineTextPart);
|
|
||||||
createChildRow(_bio, margin, slidedPadding, st::settingsBioValue);
|
|
||||||
refreshControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::refreshControls() {
|
|
||||||
refreshMobileNumber();
|
|
||||||
refreshUsername();
|
|
||||||
refreshBio();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::refreshMobileNumber() {
|
|
||||||
TextWithEntities phoneText;
|
|
||||||
if (const auto user = self()->asUser()) {
|
|
||||||
phoneText.text = Auth().data().findContactPhone(user);
|
|
||||||
}
|
|
||||||
setLabeledText(
|
|
||||||
_mobileNumber,
|
|
||||||
lang(lng_profile_mobile_number),
|
|
||||||
phoneText,
|
|
||||||
TextWithEntities(),
|
|
||||||
lang(lng_profile_copy_phone));
|
|
||||||
if (auto text = _mobileNumber->entity()->textLabel()) {
|
|
||||||
text->setRichText(textcmdLink(1, phoneText.text));
|
|
||||||
text->setLink(1, std::make_shared<LambdaClickHandler>([] {
|
|
||||||
Ui::show(Box<ChangePhoneBox>());
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::refreshUsername() {
|
|
||||||
TextWithEntities usernameText;
|
|
||||||
QString copyText;
|
|
||||||
if (self()->username.isEmpty()) {
|
|
||||||
usernameText.text = lang(lng_settings_choose_username);
|
|
||||||
} else {
|
|
||||||
usernameText.text = '@' + self()->username;
|
|
||||||
copyText = lang(lng_context_copy_mention);
|
|
||||||
}
|
|
||||||
usernameText.entities.push_back(EntityInText(
|
|
||||||
EntityInTextCustomUrl,
|
|
||||||
0,
|
|
||||||
usernameText.text.size(),
|
|
||||||
Messenger::Instance().createInternalLinkFull(
|
|
||||||
self()->username)));
|
|
||||||
setLabeledText(
|
|
||||||
_username,
|
|
||||||
lang(lng_profile_username),
|
|
||||||
usernameText,
|
|
||||||
TextWithEntities(),
|
|
||||||
copyText);
|
|
||||||
if (auto text = _username->entity()->textLabel()) {
|
|
||||||
text->setClickHandlerFilter([](auto&&...) {
|
|
||||||
Ui::show(Box<UsernameBox>());
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::refreshBio() {
|
|
||||||
TextWithEntities bioText;
|
|
||||||
auto aboutText = self()->about();
|
|
||||||
if (self()->about().isEmpty()) {
|
|
||||||
bioText.text = lang(lng_settings_empty_bio);
|
|
||||||
} else {
|
|
||||||
bioText.text = aboutText;
|
|
||||||
}
|
|
||||||
bioText.entities.push_back(EntityInText(
|
|
||||||
EntityInTextCustomUrl,
|
|
||||||
0,
|
|
||||||
bioText.text.size(),
|
|
||||||
QString("internal:edit_bio")));
|
|
||||||
setLabeledText(
|
|
||||||
_bio,
|
|
||||||
lang(lng_profile_bio),
|
|
||||||
bioText,
|
|
||||||
TextWithEntities(),
|
|
||||||
QString());
|
|
||||||
if (auto text = _bio->entity()->textLabel()) {
|
|
||||||
text->setClickHandlerFilter([=](auto&&...) {
|
|
||||||
Ui::show(Box<EditBioBox>(self()));
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::setLabeledText(
|
|
||||||
LabeledWrap *row,
|
|
||||||
const QString &label,
|
|
||||||
const TextWithEntities &textWithEntities,
|
|
||||||
const TextWithEntities &shortTextWithEntities,
|
|
||||||
const QString ©Text) {
|
|
||||||
auto nonEmptyText = !textWithEntities.text.isEmpty();
|
|
||||||
if (nonEmptyText) {
|
|
||||||
row->entity()->setLabeledText(
|
|
||||||
label,
|
|
||||||
textWithEntities,
|
|
||||||
shortTextWithEntities,
|
|
||||||
copyText,
|
|
||||||
width());
|
|
||||||
}
|
|
||||||
row->toggle(nonEmptyText, anim::type::normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoWidget::LabeledWidget::LabeledWidget(QWidget *parent, const style::FlatLabel &valueSt) : RpWidget(parent)
|
|
||||||
, _valueSt(valueSt) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::LabeledWidget::setLabeledText(
|
|
||||||
const QString &label,
|
|
||||||
const TextWithEntities &textWithEntities,
|
|
||||||
const TextWithEntities &shortTextWithEntities,
|
|
||||||
const QString ©Text,
|
|
||||||
int availableWidth) {
|
|
||||||
_label.destroy();
|
|
||||||
_text.destroy();
|
|
||||||
_shortText.destroy();
|
|
||||||
if (textWithEntities.text.isEmpty()) return;
|
|
||||||
|
|
||||||
_label.create(this, label, Ui::FlatLabel::InitType::Simple, st::settingsBlockLabel);
|
|
||||||
_label->show();
|
|
||||||
setLabelText(_text, textWithEntities, copyText);
|
|
||||||
setLabelText(_shortText, shortTextWithEntities, copyText);
|
|
||||||
resizeToNaturalWidth(availableWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ui::FlatLabel *InfoWidget::LabeledWidget::textLabel() const {
|
|
||||||
return _text;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ui::FlatLabel *InfoWidget::LabeledWidget::shortTextLabel() const {
|
|
||||||
return _shortText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::LabeledWidget::setLabelText(object_ptr<Ui::FlatLabel> &text, const TextWithEntities &textWithEntities, const QString ©Text) {
|
|
||||||
text.destroy();
|
|
||||||
if (textWithEntities.text.isEmpty()) return;
|
|
||||||
|
|
||||||
text.create(this, QString(), Ui::FlatLabel::InitType::Simple, _valueSt);
|
|
||||||
text->show();
|
|
||||||
text->setMarkedText(textWithEntities);
|
|
||||||
text->setContextCopyText(copyText);
|
|
||||||
text->setSelectable(true);
|
|
||||||
text->setDoubleClickSelectsParagraph(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
|
||||||
if (update.peer != self()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update.flags & UpdateFlag::UsernameChanged) {
|
|
||||||
refreshUsername();
|
|
||||||
}
|
|
||||||
if (update.flags & (UpdateFlag::UserPhoneChanged)) {
|
|
||||||
refreshMobileNumber();
|
|
||||||
}
|
|
||||||
if (update.flags & UpdateFlag::AboutChanged) {
|
|
||||||
refreshBio();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int InfoWidget::LabeledWidget::naturalWidth() const {
|
|
||||||
if (!_text) return -1;
|
|
||||||
return _label->naturalWidth() + st::normalFont->spacew + _text->naturalWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
int InfoWidget::LabeledWidget::resizeGetHeight(int newWidth) {
|
|
||||||
if (!_label) return 0;
|
|
||||||
|
|
||||||
_label->moveToLeft(
|
|
||||||
0,
|
|
||||||
st::settingsBlockOneLineTextPart.margin.top(),
|
|
||||||
newWidth);
|
|
||||||
_label->resizeToNaturalWidth(newWidth);
|
|
||||||
|
|
||||||
int textLeft = _label->width() + st::normalFont->spacew;
|
|
||||||
int textWidth = _text->naturalWidth();
|
|
||||||
int availableWidth = newWidth - textLeft;
|
|
||||||
bool doesNotFit = (textWidth > availableWidth);
|
|
||||||
accumulate_min(textWidth, availableWidth);
|
|
||||||
accumulate_min(textWidth, st::msgMaxWidth);
|
|
||||||
if (textWidth < 0) {
|
|
||||||
textWidth = 0;
|
|
||||||
}
|
|
||||||
_text->resizeToWidth(textWidth);
|
|
||||||
_text->moveToLeft(
|
|
||||||
textLeft,
|
|
||||||
st::settingsBlockOneLineTextPart.margin.top(),
|
|
||||||
newWidth);
|
|
||||||
if (_shortText) {
|
|
||||||
_shortText->resizeToWidth(textWidth);
|
|
||||||
_shortText->moveToLeft(
|
|
||||||
textLeft,
|
|
||||||
st::settingsBlockOneLineTextPart.margin.top(),
|
|
||||||
newWidth);
|
|
||||||
if (doesNotFit) {
|
|
||||||
_shortText->show();
|
|
||||||
_text->hide();
|
|
||||||
} else {
|
|
||||||
_shortText->hide();
|
|
||||||
_text->show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return st::settingsBlockOneLineTextPart.margin.top()
|
|
||||||
+ qMax(_label->heightNoMargins(), _text->heightNoMargins())
|
|
||||||
+ st::settingsBlockOneLineTextPart.margin.bottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class FlatLabel;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace Notify {
|
|
||||||
struct PeerUpdate;
|
|
||||||
} // namespace Notify
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class InfoWidget : public BlockWidget {
|
|
||||||
public:
|
|
||||||
InfoWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Observed notifications.
|
|
||||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
|
||||||
|
|
||||||
void createControls();
|
|
||||||
void refreshControls();
|
|
||||||
void refreshMobileNumber();
|
|
||||||
void refreshUsername();
|
|
||||||
void refreshBio();
|
|
||||||
|
|
||||||
class LabeledWidget : public Ui::RpWidget {
|
|
||||||
public:
|
|
||||||
LabeledWidget(QWidget *parent, const style::FlatLabel &valueSt);
|
|
||||||
|
|
||||||
void setLabeledText(
|
|
||||||
const QString &label,
|
|
||||||
const TextWithEntities &textWithEntities,
|
|
||||||
const TextWithEntities &shortTextWithEntities,
|
|
||||||
const QString ©Text,
|
|
||||||
int availableWidth);
|
|
||||||
|
|
||||||
Ui::FlatLabel *textLabel() const;
|
|
||||||
Ui::FlatLabel *shortTextLabel() const;
|
|
||||||
|
|
||||||
int naturalWidth() const override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setLabelText(
|
|
||||||
object_ptr<Ui::FlatLabel> &text,
|
|
||||||
const TextWithEntities &textWithEntities,
|
|
||||||
const QString ©Text);
|
|
||||||
|
|
||||||
const style::FlatLabel &_valueSt;
|
|
||||||
object_ptr<Ui::FlatLabel> _label = { nullptr };
|
|
||||||
object_ptr<Ui::FlatLabel> _text = { nullptr };
|
|
||||||
object_ptr<Ui::FlatLabel> _shortText = { nullptr };
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
using LabeledWrap = Ui::SlideWrap<LabeledWidget>;
|
|
||||||
void setLabeledText(
|
|
||||||
LabeledWrap *row,
|
|
||||||
const QString &label,
|
|
||||||
const TextWithEntities &textWithEntities,
|
|
||||||
const TextWithEntities &shortTextWithEntities,
|
|
||||||
const QString ©Text);
|
|
||||||
|
|
||||||
LabeledWrap *_mobileNumber = nullptr;
|
|
||||||
LabeledWrap *_username = nullptr;
|
|
||||||
LabeledWrap *_bio = nullptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,115 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_inner_widget.h"
|
|
||||||
|
|
||||||
#include "lang/lang_instance.h"
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "old_settings/settings_cover.h"
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
#include "old_settings/settings_info_widget.h"
|
|
||||||
#include "old_settings/settings_notifications_widget.h"
|
|
||||||
#include "old_settings/settings_general_widget.h"
|
|
||||||
#include "old_settings/settings_chat_settings_widget.h"
|
|
||||||
#include "old_settings/settings_scale_widget.h"
|
|
||||||
#include "old_settings/settings_background_widget.h"
|
|
||||||
#include "old_settings/settings_privacy_widget.h"
|
|
||||||
#include "old_settings/settings_advanced_widget.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
InnerWidget::InnerWidget(QWidget *parent) : LayerInner(parent)
|
|
||||||
, _blocks(this)
|
|
||||||
, _self(AuthSession::Exists() ? Auth().user().get() : nullptr) {
|
|
||||||
refreshBlocks();
|
|
||||||
subscribe(Lang::Current().updated(), [this] { fullRebuild(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void InnerWidget::fullRebuild() {
|
|
||||||
_self = AuthSession::Exists() ? Auth().user().get() : nullptr;
|
|
||||||
refreshBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
int InnerWidget::getUpdateTop() const {
|
|
||||||
return _getUpdateTop ? _getUpdateTop() : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InnerWidget::refreshBlocks() {
|
|
||||||
if (App::quitting()) {
|
|
||||||
_cover.destroy();
|
|
||||||
_blocks.destroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cover = _self
|
|
||||||
? object_ptr<CoverWidget>(this, _self)
|
|
||||||
: nullptr;
|
|
||||||
_blocks = object_ptr<Ui::VerticalLayout>(this);
|
|
||||||
resizeToWidth(width(), _contentLeft);
|
|
||||||
|
|
||||||
if (_self) {
|
|
||||||
_blocks->add(object_ptr<InfoWidget>(this, _self));
|
|
||||||
_blocks->add(object_ptr<NotificationsWidget>(this, _self));
|
|
||||||
}
|
|
||||||
const auto general = make_weak(_blocks->add(object_ptr<GeneralWidget>(
|
|
||||||
this,
|
|
||||||
_self)));
|
|
||||||
_getUpdateTop = [=] {
|
|
||||||
if (!general) {
|
|
||||||
return -1;
|
|
||||||
} else if (const auto top = general->getUpdateTop(); top >= 0) {
|
|
||||||
return _blocks->y() + general->y() + top;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
if (!cRetina()) {
|
|
||||||
_blocks->add(object_ptr<ScaleWidget>(this, _self));
|
|
||||||
}
|
|
||||||
if (_self) {
|
|
||||||
_blocks->add(object_ptr<ChatSettingsWidget>(this, _self));
|
|
||||||
_blocks->add(object_ptr<BackgroundWidget>(this, _self));
|
|
||||||
_blocks->add(object_ptr<PrivacyWidget>(this, _self));
|
|
||||||
}
|
|
||||||
_blocks->add(object_ptr<AdvancedWidget>(this, _self));
|
|
||||||
|
|
||||||
if (_cover) {
|
|
||||||
_cover->show();
|
|
||||||
}
|
|
||||||
_blocks->show();
|
|
||||||
_blocks->heightValue(
|
|
||||||
) | rpl::start_with_next([this](int blocksHeight) {
|
|
||||||
resize(width(), _blocks->y() + blocksHeight);
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
int InnerWidget::resizeGetHeight(int newWidth) {
|
|
||||||
if (_cover) {
|
|
||||||
_cover->setContentLeft(_contentLeft);
|
|
||||||
_cover->resizeToWidth(newWidth);
|
|
||||||
}
|
|
||||||
_blocks->resizeToWidth(newWidth - 2 * _contentLeft);
|
|
||||||
_blocks->moveToLeft(
|
|
||||||
_contentLeft,
|
|
||||||
(_cover ? (_cover->y() + _cover->height()) : 0)
|
|
||||||
+ st::settingsBlocksTop);
|
|
||||||
return height();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InnerWidget::visibleTopBottomUpdated(
|
|
||||||
int visibleTop,
|
|
||||||
int visibleBottom) {
|
|
||||||
setChildVisibleTopBottom(
|
|
||||||
_cover,
|
|
||||||
visibleTop,
|
|
||||||
visibleBottom);
|
|
||||||
setChildVisibleTopBottom(
|
|
||||||
_blocks,
|
|
||||||
visibleTop,
|
|
||||||
visibleBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_layer.h"
|
|
||||||
#include "ui/wrap/vertical_layout.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class CoverWidget;
|
|
||||||
class BlockWidget;
|
|
||||||
|
|
||||||
class InnerWidget : public LayerInner, private base::Subscriber {
|
|
||||||
public:
|
|
||||||
InnerWidget(QWidget *parent);
|
|
||||||
|
|
||||||
// Count new height for width=newWidth and resize to it.
|
|
||||||
void resizeToWidth(int newWidth, int contentLeft) override {
|
|
||||||
_contentLeft = contentLeft;
|
|
||||||
return TWidget::resizeToWidth(newWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getUpdateTop() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
void visibleTopBottomUpdated(
|
|
||||||
int visibleTop,
|
|
||||||
int visibleBottom) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void fullRebuild();
|
|
||||||
void refreshBlocks();
|
|
||||||
|
|
||||||
object_ptr<CoverWidget> _cover = { nullptr };
|
|
||||||
object_ptr<Ui::VerticalLayout> _blocks;
|
|
||||||
|
|
||||||
UserData *_self = nullptr;
|
|
||||||
|
|
||||||
int _contentLeft = 0;
|
|
||||||
Fn<int()> _getUpdateTop;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,120 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_layer.h"
|
|
||||||
|
|
||||||
#include <rpl/mappers.h>
|
|
||||||
#include "old_settings/settings_inner_widget.h"
|
|
||||||
#include "old_settings/settings_fixed_bar.h"
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "styles/style_window.h"
|
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
#include "ui/widgets/scroll_area.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/widgets/shadow.h"
|
|
||||||
#include "ui/wrap/fade_wrap.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "mainwidget.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
#include "application.h"
|
|
||||||
#include "core/file_utilities.h"
|
|
||||||
#include "window/themes/window_theme.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
Layer::Layer()
|
|
||||||
: _scroll(this, st::settingsScroll)
|
|
||||||
, _fixedBar(this)
|
|
||||||
, _fixedBarClose(this, st::settingsFixedBarClose)
|
|
||||||
, _fixedBarShadow(this) {
|
|
||||||
_fixedBar->moveToLeft(0, st::boxRadius);
|
|
||||||
_fixedBarClose->moveToRight(0, 0);
|
|
||||||
_fixedBarShadow->entity()->resize(width(), st::lineWidth);
|
|
||||||
_fixedBarShadow->moveToLeft(0, _fixedBar->y() + _fixedBar->height());
|
|
||||||
_fixedBarShadow->hide(anim::type::instant);
|
|
||||||
_scroll->moveToLeft(0, st::settingsFixedBarHeight);
|
|
||||||
|
|
||||||
using namespace rpl::mappers;
|
|
||||||
_fixedBarShadow->toggleOn(_scroll->scrollTopValue()
|
|
||||||
| rpl::map(_1 > 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::setCloseClickHandler(Fn<void()> callback) {
|
|
||||||
_fixedBarClose->setClickedCallback(std::move(callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::resizeToWidth(int newWidth, int newContentLeft) {
|
|
||||||
// Widget height depends on InnerWidget height, so we
|
|
||||||
// resize it here, not in the resizeEvent() handler.
|
|
||||||
_inner->resizeToWidth(newWidth, newContentLeft);
|
|
||||||
|
|
||||||
resizeUsingInnerHeight(newWidth, _inner->height());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::doSetInnerWidget(object_ptr<LayerInner> widget) {
|
|
||||||
_inner = _scroll->setOwnedWidget(std::move(widget));
|
|
||||||
_inner->heightValue(
|
|
||||||
) | rpl::start_with_next([this](int innerHeight) {
|
|
||||||
resizeUsingInnerHeight(width(), innerHeight);
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
auto clip = e->rect();
|
|
||||||
if (_roundedCorners) {
|
|
||||||
auto paintTopRounded = clip.intersects(QRect(0, 0, width(), st::boxRadius));
|
|
||||||
auto paintBottomRounded = clip.intersects(QRect(0, height() - st::boxRadius, width(), st::boxRadius));
|
|
||||||
if (paintTopRounded || paintBottomRounded) {
|
|
||||||
auto parts = RectPart::None | 0;
|
|
||||||
if (paintTopRounded) parts |= RectPart::FullTop;
|
|
||||||
if (paintBottomRounded) parts |= RectPart::FullBottom;
|
|
||||||
App::roundRect(p, rect(), st::boxBg, BoxCorners, nullptr, parts);
|
|
||||||
}
|
|
||||||
auto other = clip.intersected(QRect(0, st::boxRadius, width(), height() - 2 * st::boxRadius));
|
|
||||||
if (!other.isEmpty()) {
|
|
||||||
p.fillRect(other, st::boxBg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p.fillRect(e->rect(), st::boxBg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::resizeEvent(QResizeEvent *e) {
|
|
||||||
LayerWidget::resizeEvent(e);
|
|
||||||
if (!width() || !height()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fixedBar->resizeToWidth(width());
|
|
||||||
_fixedBar->moveToLeft(0, st::boxRadius);
|
|
||||||
_fixedBar->update();
|
|
||||||
_fixedBarClose->moveToRight(0, 0);
|
|
||||||
auto shadowTop = _fixedBar->y() + _fixedBar->height();
|
|
||||||
_fixedBarShadow->entity()->resize(width(), st::lineWidth);
|
|
||||||
_fixedBarShadow->moveToLeft(0, shadowTop);
|
|
||||||
|
|
||||||
auto scrollSize = QSize(width(), height() - shadowTop - (_roundedCorners ? st::boxRadius : 0));
|
|
||||||
if (_scroll->size() != scrollSize) {
|
|
||||||
_scroll->resize(scrollSize);
|
|
||||||
}
|
|
||||||
if (!_scroll->isHidden()) {
|
|
||||||
auto scrollTop = _scroll->scrollTop();
|
|
||||||
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::setTitle(const QString &title) {
|
|
||||||
_fixedBar->setText(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::scrollToY(int y) {
|
|
||||||
_scroll->scrollToY(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "window/layer_widget.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class ScrollArea;
|
|
||||||
class IconButton;
|
|
||||||
class FadeShadow;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class FixedBar;
|
|
||||||
class LayerInner : public Ui::RpWidget {
|
|
||||||
public:
|
|
||||||
LayerInner(QWidget *parent) : RpWidget(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void resizeToWidth(int newWidth, int contentLeft) {
|
|
||||||
TWidget::resizeToWidth(newWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class Layer : public Window::LayerWidget {
|
|
||||||
public:
|
|
||||||
Layer();
|
|
||||||
|
|
||||||
void setCloseClickHandler(Fn<void()> callback);
|
|
||||||
void resizeToWidth(int newWidth, int newContentLeft);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
|
||||||
|
|
||||||
template <typename Widget>
|
|
||||||
QPointer<Widget> setInnerWidget(object_ptr<Widget> widget) {
|
|
||||||
auto result = QPointer<Widget>(widget);
|
|
||||||
doSetInnerWidget(std::move(widget));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTitle(const QString &title);
|
|
||||||
void setRoundedCorners(bool roundedCorners) {
|
|
||||||
_roundedCorners = roundedCorners;
|
|
||||||
}
|
|
||||||
void scrollToY(int y);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void doSetInnerWidget(object_ptr<LayerInner> widget);
|
|
||||||
|
|
||||||
virtual void resizeUsingInnerHeight(int newWidth, int innerHeight) {
|
|
||||||
resize(newWidth, height());
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<Ui::ScrollArea> _scroll;
|
|
||||||
QPointer<LayerInner> _inner;
|
|
||||||
object_ptr<FixedBar> _fixedBar;
|
|
||||||
object_ptr<Ui::IconButton> _fixedBarClose;
|
|
||||||
object_ptr<Ui::FadeShadow> _fixedBarShadow;
|
|
||||||
|
|
||||||
bool _roundedCorners = false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,181 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_notifications_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "window/notifications_manager.h"
|
|
||||||
#include "boxes/notifications_box.h"
|
|
||||||
#include "platform/platform_notifications_manager.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using ChangeType = Window::Notifications::ChangeType;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
NotificationsWidget::NotificationsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_notify)) {
|
|
||||||
createControls();
|
|
||||||
|
|
||||||
subscribe(Auth().notifications().settingsChanged(), [this](ChangeType type) {
|
|
||||||
if (type == ChangeType::DesktopEnabled) {
|
|
||||||
desktopEnabledUpdated();
|
|
||||||
} else if (type == ChangeType::ViewParams) {
|
|
||||||
viewParamUpdated();
|
|
||||||
} else if (type == ChangeType::SoundEnabled) {
|
|
||||||
_playSound->setChecked(Global::SoundNotify());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::createControls() {
|
|
||||||
style::margins margin(0, 0, 0, st::settingsSkip);
|
|
||||||
style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2));
|
|
||||||
createChildRow(_desktopNotifications, margin, lang(lng_settings_desktop_notify), [this](bool) { onDesktopNotifications(); }, Global::DesktopNotify());
|
|
||||||
createChildRow(_showSenderName, margin, slidedPadding, lang(lng_settings_show_name), [this](bool) { onShowSenderName(); }, Global::NotifyView() <= dbinvShowName);
|
|
||||||
createChildRow(_showMessagePreview, margin, slidedPadding, lang(lng_settings_show_preview), [this](bool) { onShowMessagePreview(); }, Global::NotifyView() <= dbinvShowPreview);
|
|
||||||
if (!_showSenderName->entity()->checked()) {
|
|
||||||
_showMessagePreview->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
if (!_desktopNotifications->checked()) {
|
|
||||||
_showSenderName->hide(anim::type::instant);
|
|
||||||
_showMessagePreview->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
createChildRow(_playSound, margin, lang(lng_settings_sound_notify), [this](bool) { onPlaySound(); }, Global::SoundNotify());
|
|
||||||
createChildRow(_includeMuted, margin, lang(lng_settings_include_muted), [this](bool) { onIncludeMuted(); }, Global::IncludeMuted());
|
|
||||||
|
|
||||||
if (cPlatform() != dbipMac) {
|
|
||||||
createNotificationsControls();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::createNotificationsControls() {
|
|
||||||
style::margins margin(0, 0, 0, st::settingsSkip);
|
|
||||||
style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2));
|
|
||||||
|
|
||||||
auto nativeNotificationsLabel = QString();
|
|
||||||
if (Platform::Notifications::Supported()) {
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
nativeNotificationsLabel = lang(lng_settings_use_windows);
|
|
||||||
#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32 // Q_OS_WIN
|
|
||||||
nativeNotificationsLabel = lang(lng_settings_use_native_notifications);
|
|
||||||
#endif // Q_OS_WIN || Q_OS_LINUX64 || Q_OS_LINUX32
|
|
||||||
}
|
|
||||||
if (!nativeNotificationsLabel.isEmpty()) {
|
|
||||||
createChildRow(_nativeNotifications, margin, nativeNotificationsLabel, [this](bool) { onNativeNotifications(); }, Global::NativeNotifications());
|
|
||||||
}
|
|
||||||
createChildRow(_advanced, margin, slidedPadding, lang(lng_settings_advanced_notifications), SLOT(onAdvanced()));
|
|
||||||
if (!nativeNotificationsLabel.isEmpty() && Global::NativeNotifications()) {
|
|
||||||
_advanced->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::onDesktopNotifications() {
|
|
||||||
if (Global::DesktopNotify() == _desktopNotifications->checked()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Global::SetDesktopNotify(_desktopNotifications->checked());
|
|
||||||
Local::writeUserSettings();
|
|
||||||
Auth().notifications().settingsChanged().notify(ChangeType::DesktopEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::desktopEnabledUpdated() {
|
|
||||||
_desktopNotifications->setChecked(Global::DesktopNotify());
|
|
||||||
_showSenderName->toggle(
|
|
||||||
Global::DesktopNotify(),
|
|
||||||
anim::type::normal);
|
|
||||||
_showMessagePreview->toggle(
|
|
||||||
Global::DesktopNotify()
|
|
||||||
&& _showSenderName->entity()->checked(),
|
|
||||||
anim::type::normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::onShowSenderName() {
|
|
||||||
auto viewParam = ([this]() {
|
|
||||||
if (!_showSenderName->entity()->checked()) {
|
|
||||||
return dbinvShowNothing;
|
|
||||||
} else if (!_showMessagePreview->entity()->checked()) {
|
|
||||||
return dbinvShowName;
|
|
||||||
}
|
|
||||||
return dbinvShowPreview;
|
|
||||||
})();
|
|
||||||
if (viewParam == Global::NotifyView()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Global::SetNotifyView(viewParam);
|
|
||||||
Local::writeUserSettings();
|
|
||||||
Auth().notifications().settingsChanged().notify(ChangeType::ViewParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::onShowMessagePreview() {
|
|
||||||
auto viewParam = ([this]() {
|
|
||||||
if (_showMessagePreview->entity()->checked()) {
|
|
||||||
return dbinvShowPreview;
|
|
||||||
} else if (_showSenderName->entity()->checked()) {
|
|
||||||
return dbinvShowName;
|
|
||||||
}
|
|
||||||
return dbinvShowNothing;
|
|
||||||
})();
|
|
||||||
if (viewParam == Global::NotifyView()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Global::SetNotifyView(viewParam);
|
|
||||||
Local::writeUserSettings();
|
|
||||||
Auth().notifications().settingsChanged().notify(ChangeType::ViewParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::viewParamUpdated() {
|
|
||||||
_showMessagePreview->toggle(
|
|
||||||
_showSenderName->entity()->checked(),
|
|
||||||
anim::type::normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::onNativeNotifications() {
|
|
||||||
if (Global::NativeNotifications() == _nativeNotifications->checked()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Global::SetNativeNotifications(_nativeNotifications->checked());
|
|
||||||
Local::writeUserSettings();
|
|
||||||
|
|
||||||
Auth().notifications().createManager();
|
|
||||||
|
|
||||||
_advanced->toggle(
|
|
||||||
!Global::NativeNotifications(),
|
|
||||||
anim::type::normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::onAdvanced() {
|
|
||||||
Ui::show(Box<NotificationsBox>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::onPlaySound() {
|
|
||||||
if (_playSound->checked() == Global::SoundNotify()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Global::SetSoundNotify(_playSound->checked());
|
|
||||||
Local::writeUserSettings();
|
|
||||||
Auth().notifications().settingsChanged().notify(ChangeType::SoundEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationsWidget::onIncludeMuted() {
|
|
||||||
Global::SetIncludeMuted(_includeMuted->checked());
|
|
||||||
Local::writeUserSettings();
|
|
||||||
Auth().notifications().settingsChanged().notify(ChangeType::IncludeMuted);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class NotificationsWidget : public BlockWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
NotificationsWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onDesktopNotifications();
|
|
||||||
void onShowSenderName();
|
|
||||||
void onShowMessagePreview();
|
|
||||||
void onNativeNotifications();
|
|
||||||
void onPlaySound();
|
|
||||||
void onIncludeMuted();
|
|
||||||
void onAdvanced();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void createControls();
|
|
||||||
void createNotificationsControls();
|
|
||||||
void desktopEnabledUpdated();
|
|
||||||
void viewParamUpdated();
|
|
||||||
|
|
||||||
Ui::Checkbox *_desktopNotifications = nullptr;
|
|
||||||
Ui::SlideWrap<Ui::Checkbox> *_showSenderName = nullptr;
|
|
||||||
Ui::SlideWrap<Ui::Checkbox> *_showMessagePreview = nullptr;
|
|
||||||
Ui::Checkbox *_nativeNotifications = nullptr;
|
|
||||||
Ui::Checkbox *_playSound = nullptr;
|
|
||||||
Ui::Checkbox *_includeMuted = nullptr;
|
|
||||||
Ui::SlideWrap<Ui::LinkButton> *_advanced = nullptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,357 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_privacy_controllers.h"
|
|
||||||
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "apiwrap.h"
|
|
||||||
#include "observer_peer.h"
|
|
||||||
#include "mainwidget.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "history/history.h"
|
|
||||||
#include "boxes/peer_list_controllers.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr auto kBlockedPerPage = 40;
|
|
||||||
|
|
||||||
class BlockUserBoxController : public ChatsListBoxController {
|
|
||||||
public:
|
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
|
||||||
|
|
||||||
void setBlockUserCallback(Fn<void(not_null<UserData*> user)> callback) {
|
|
||||||
_blockUserCallback = std::move(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void prepareViewHook() override;
|
|
||||||
std::unique_ptr<Row> createRow(not_null<History*> history) override;
|
|
||||||
void updateRowHook(not_null<Row*> row) override {
|
|
||||||
updateIsBlocked(row, row->peer()->asUser());
|
|
||||||
delegate()->peerListUpdateRow(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updateIsBlocked(not_null<PeerListRow*> row, UserData *user) const;
|
|
||||||
|
|
||||||
Fn<void(not_null<UserData*> user)> _blockUserCallback;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void BlockUserBoxController::prepareViewHook() {
|
|
||||||
delegate()->peerListSetTitle(langFactory(lng_blocked_list_add_title));
|
|
||||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserIsBlocked, [this](const Notify::PeerUpdate &update) {
|
|
||||||
if (auto user = update.peer->asUser()) {
|
|
||||||
if (auto row = delegate()->peerListFindRow(user->id)) {
|
|
||||||
updateIsBlocked(row, user);
|
|
||||||
delegate()->peerListUpdateRow(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockUserBoxController::updateIsBlocked(not_null<PeerListRow*> row, UserData *user) const {
|
|
||||||
auto blocked = user->isBlocked();
|
|
||||||
row->setDisabledState(blocked ? PeerListRow::State::DisabledChecked : PeerListRow::State::Active);
|
|
||||||
if (blocked) {
|
|
||||||
row->setCustomStatus(lang(lng_blocked_list_already_blocked));
|
|
||||||
} else {
|
|
||||||
row->clearCustomStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockUserBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|
||||||
_blockUserCallback(row->peer()->asUser());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<BlockUserBoxController::Row> BlockUserBoxController::createRow(not_null<History*> history) {
|
|
||||||
if (history->peer->isSelf()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (auto user = history->peer->asUser()) {
|
|
||||||
auto row = std::make_unique<Row>(history);
|
|
||||||
updateIsBlocked(row.get(), user);
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void BlockedBoxController::prepare() {
|
|
||||||
delegate()->peerListSetTitle(langFactory(lng_blocked_list_title));
|
|
||||||
setDescriptionText(lang(lng_contacts_loading));
|
|
||||||
delegate()->peerListRefreshRows();
|
|
||||||
|
|
||||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserIsBlocked, [this](const Notify::PeerUpdate &update) {
|
|
||||||
if (auto user = update.peer->asUser()) {
|
|
||||||
handleBlockedEvent(user);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
loadMoreRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockedBoxController::loadMoreRows() {
|
|
||||||
if (_loadRequestId || _allLoaded) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_loadRequestId = request(MTPcontacts_GetBlocked(MTP_int(_offset), MTP_int(kBlockedPerPage))).done([this](const MTPcontacts_Blocked &result) {
|
|
||||||
_loadRequestId = 0;
|
|
||||||
|
|
||||||
if (!_offset) {
|
|
||||||
setDescriptionText(lang(lng_blocked_list_about));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto handleContactsBlocked = [](auto &list) {
|
|
||||||
App::feedUsers(list.vusers);
|
|
||||||
return list.vblocked.v;
|
|
||||||
};
|
|
||||||
switch (result.type()) {
|
|
||||||
case mtpc_contacts_blockedSlice: {
|
|
||||||
receivedUsers(handleContactsBlocked(result.c_contacts_blockedSlice()));
|
|
||||||
} break;
|
|
||||||
case mtpc_contacts_blocked: {
|
|
||||||
_allLoaded = true;
|
|
||||||
receivedUsers(handleContactsBlocked(result.c_contacts_blocked()));
|
|
||||||
} break;
|
|
||||||
default: Unexpected("Bad type() in MTPcontacts_GetBlocked() result.");
|
|
||||||
}
|
|
||||||
}).fail([this](const RPCError &error) {
|
|
||||||
_loadRequestId = 0;
|
|
||||||
}).send();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockedBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|
||||||
InvokeQueued(App::main(), [peerId = row->peer()->id] {
|
|
||||||
Ui::showPeerHistory(peerId, ShowAtUnreadMsgId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockedBoxController::rowActionClicked(not_null<PeerListRow*> row) {
|
|
||||||
auto user = row->peer()->asUser();
|
|
||||||
Expects(user != nullptr);
|
|
||||||
|
|
||||||
Auth().api().unblockUser(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockedBoxController::receivedUsers(const QVector<MTPContactBlocked> &result) {
|
|
||||||
if (result.empty()) {
|
|
||||||
_allLoaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for_const (auto &item, result) {
|
|
||||||
++_offset;
|
|
||||||
if (item.type() != mtpc_contactBlocked) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto &contactBlocked = item.c_contactBlocked();
|
|
||||||
auto userId = contactBlocked.vuser_id.v;
|
|
||||||
if (auto user = App::userLoaded(userId)) {
|
|
||||||
appendRow(user);
|
|
||||||
user->setBlockStatus(UserData::BlockStatus::Blocked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delegate()->peerListRefreshRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockedBoxController::handleBlockedEvent(UserData *user) {
|
|
||||||
if (user->isBlocked()) {
|
|
||||||
if (prependRow(user)) {
|
|
||||||
delegate()->peerListRefreshRows();
|
|
||||||
delegate()->peerListScrollToTop();
|
|
||||||
}
|
|
||||||
} else if (auto row = delegate()->peerListFindRow(user->id)) {
|
|
||||||
delegate()->peerListRemoveRow(row);
|
|
||||||
delegate()->peerListRefreshRows();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockedBoxController::BlockNewUser() {
|
|
||||||
auto controller = std::make_unique<BlockUserBoxController>();
|
|
||||||
auto initBox = [controller = controller.get()](not_null<PeerListBox*> box) {
|
|
||||||
controller->setBlockUserCallback([box](not_null<UserData*> user) {
|
|
||||||
Auth().api().blockUser(user);
|
|
||||||
box->closeBox();
|
|
||||||
});
|
|
||||||
box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); });
|
|
||||||
};
|
|
||||||
Ui::show(
|
|
||||||
Box<PeerListBox>(std::move(controller), std::move(initBox)),
|
|
||||||
LayerOption::KeepOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BlockedBoxController::appendRow(UserData *user) {
|
|
||||||
if (delegate()->peerListFindRow(user->id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
delegate()->peerListAppendRow(createRow(user));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BlockedBoxController::prependRow(UserData *user) {
|
|
||||||
if (delegate()->peerListFindRow(user->id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
delegate()->peerListPrependRow(createRow(user));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<PeerListRow> BlockedBoxController::createRow(UserData *user) const {
|
|
||||||
auto row = std::make_unique<PeerListRowWithLink>(user);
|
|
||||||
row->setActionLink(lang(lng_blocked_list_unblock));
|
|
||||||
auto status = [user]() -> QString {
|
|
||||||
if (user->botInfo) {
|
|
||||||
return lang(lng_status_bot);
|
|
||||||
} else if (user->phone().isEmpty()) {
|
|
||||||
return lang(lng_blocked_list_unknown_phone);
|
|
||||||
}
|
|
||||||
return App::formatPhone(user->phone());
|
|
||||||
};
|
|
||||||
row->setCustomStatus(status());
|
|
||||||
return std::move(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiWrap::Privacy::Key LastSeenPrivacyController::key() {
|
|
||||||
return Key::LastSeen;
|
|
||||||
}
|
|
||||||
|
|
||||||
MTPInputPrivacyKey LastSeenPrivacyController::apiKey() {
|
|
||||||
return MTP_inputPrivacyKeyStatusTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LastSeenPrivacyController::title() {
|
|
||||||
return lang(lng_edit_privacy_lastseen_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LastSeenPrivacyController::description() {
|
|
||||||
return lang(lng_edit_privacy_lastseen_description);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LastSeenPrivacyController::warning() {
|
|
||||||
return lang(lng_edit_privacy_lastseen_warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LastSeenPrivacyController::exceptionLinkText(Exception exception, int count) {
|
|
||||||
switch (exception) {
|
|
||||||
case Exception::Always: return (count > 0) ? lng_edit_privacy_lastseen_always(lt_count, count) : lang(lng_edit_privacy_lastseen_always_empty);
|
|
||||||
case Exception::Never: return (count > 0) ? lng_edit_privacy_lastseen_never(lt_count, count) : lang(lng_edit_privacy_lastseen_never_empty);
|
|
||||||
}
|
|
||||||
Unexpected("Invalid exception value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LastSeenPrivacyController::exceptionBoxTitle(Exception exception) {
|
|
||||||
switch (exception) {
|
|
||||||
case Exception::Always: return lang(lng_edit_privacy_lastseen_always_title);
|
|
||||||
case Exception::Never: return lang(lng_edit_privacy_lastseen_never_title);
|
|
||||||
}
|
|
||||||
Unexpected("Invalid exception value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LastSeenPrivacyController::exceptionsDescription() {
|
|
||||||
return lang(lng_edit_privacy_lastseen_exceptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastSeenPrivacyController::confirmSave(bool someAreDisallowed, FnMut<void()> saveCallback) {
|
|
||||||
if (someAreDisallowed && !Auth().settings().lastSeenWarningSeen()) {
|
|
||||||
auto weakBox = std::make_shared<QPointer<ConfirmBox>>();
|
|
||||||
auto callback = [weakBox, saveCallback = std::move(saveCallback)]() mutable {
|
|
||||||
if (auto box = *weakBox) {
|
|
||||||
box->closeBox();
|
|
||||||
}
|
|
||||||
saveCallback();
|
|
||||||
Auth().settings().setLastSeenWarningSeen(true);
|
|
||||||
Local::writeUserSettings();
|
|
||||||
};
|
|
||||||
auto box = Box<ConfirmBox>(lang(lng_edit_privacy_lastseen_warning), lang(lng_continue), lang(lng_cancel), std::move(callback));
|
|
||||||
*weakBox = Ui::show(std::move(box), LayerOption::KeepOther);
|
|
||||||
} else {
|
|
||||||
saveCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiWrap::Privacy::Key GroupsInvitePrivacyController::key() {
|
|
||||||
return Key::Invites;
|
|
||||||
}
|
|
||||||
|
|
||||||
MTPInputPrivacyKey GroupsInvitePrivacyController::apiKey() {
|
|
||||||
return MTP_inputPrivacyKeyChatInvite();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GroupsInvitePrivacyController::title() {
|
|
||||||
return lang(lng_edit_privacy_groups_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GroupsInvitePrivacyController::hasOption(Option option) {
|
|
||||||
return (option != Option::Nobody);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GroupsInvitePrivacyController::description() {
|
|
||||||
return lang(lng_edit_privacy_groups_description);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GroupsInvitePrivacyController::exceptionLinkText(Exception exception, int count) {
|
|
||||||
switch (exception) {
|
|
||||||
case Exception::Always: return (count > 0) ? lng_edit_privacy_groups_always(lt_count, count) : lang(lng_edit_privacy_groups_always_empty);
|
|
||||||
case Exception::Never: return (count > 0) ? lng_edit_privacy_groups_never(lt_count, count) : lang(lng_edit_privacy_groups_never_empty);
|
|
||||||
}
|
|
||||||
Unexpected("Invalid exception value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GroupsInvitePrivacyController::exceptionBoxTitle(Exception exception) {
|
|
||||||
switch (exception) {
|
|
||||||
case Exception::Always: return lang(lng_edit_privacy_groups_always_title);
|
|
||||||
case Exception::Never: return lang(lng_edit_privacy_groups_never_title);
|
|
||||||
}
|
|
||||||
Unexpected("Invalid exception value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GroupsInvitePrivacyController::exceptionsDescription() {
|
|
||||||
return lang(lng_edit_privacy_groups_exceptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiWrap::Privacy::Key CallsPrivacyController::key() {
|
|
||||||
return Key::Calls;
|
|
||||||
}
|
|
||||||
|
|
||||||
MTPInputPrivacyKey CallsPrivacyController::apiKey() {
|
|
||||||
return MTP_inputPrivacyKeyPhoneCall();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CallsPrivacyController::title() {
|
|
||||||
return lang(lng_edit_privacy_calls_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CallsPrivacyController::description() {
|
|
||||||
return lang(lng_edit_privacy_calls_description);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CallsPrivacyController::exceptionLinkText(Exception exception, int count) {
|
|
||||||
switch (exception) {
|
|
||||||
case Exception::Always: return (count > 0) ? lng_edit_privacy_calls_always(lt_count, count) : lang(lng_edit_privacy_calls_always_empty);
|
|
||||||
case Exception::Never: return (count > 0) ? lng_edit_privacy_calls_never(lt_count, count) : lang(lng_edit_privacy_calls_never_empty);
|
|
||||||
}
|
|
||||||
Unexpected("Invalid exception value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CallsPrivacyController::exceptionBoxTitle(Exception exception) {
|
|
||||||
switch (exception) {
|
|
||||||
case Exception::Always: return lang(lng_edit_privacy_calls_always_title);
|
|
||||||
case Exception::Never: return lang(lng_edit_privacy_calls_never_title);
|
|
||||||
}
|
|
||||||
Unexpected("Invalid exception value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CallsPrivacyController::exceptionsDescription() {
|
|
||||||
return lang(lng_edit_privacy_calls_exceptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,91 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "boxes/peer_list_box.h"
|
|
||||||
#include "boxes/edit_privacy_box.h"
|
|
||||||
#include "mtproto/sender.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class BlockedBoxController : public PeerListController, private base::Subscriber, private MTP::Sender {
|
|
||||||
public:
|
|
||||||
void prepare() override;
|
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
|
||||||
void rowActionClicked(not_null<PeerListRow*> row) override;
|
|
||||||
void loadMoreRows() override;
|
|
||||||
|
|
||||||
static void BlockNewUser();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void receivedUsers(const QVector<MTPContactBlocked> &result);
|
|
||||||
void handleBlockedEvent(UserData *user);
|
|
||||||
|
|
||||||
bool appendRow(UserData *user);
|
|
||||||
bool prependRow(UserData *user);
|
|
||||||
std::unique_ptr<PeerListRow> createRow(UserData *user) const;
|
|
||||||
|
|
||||||
int _offset = 0;
|
|
||||||
mtpRequestId _loadRequestId = 0;
|
|
||||||
bool _allLoaded = false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class LastSeenPrivacyController : public EditPrivacyBox::Controller, private base::Subscriber {
|
|
||||||
public:
|
|
||||||
using Option = EditPrivacyBox::Option;
|
|
||||||
using Exception = EditPrivacyBox::Exception;
|
|
||||||
|
|
||||||
Key key() override;
|
|
||||||
MTPInputPrivacyKey apiKey() override;
|
|
||||||
|
|
||||||
QString title() override;
|
|
||||||
QString description() override;
|
|
||||||
QString warning() override;
|
|
||||||
QString exceptionLinkText(Exception exception, int count) override;
|
|
||||||
QString exceptionBoxTitle(Exception exception) override;
|
|
||||||
QString exceptionsDescription() override;
|
|
||||||
|
|
||||||
void confirmSave(bool someAreDisallowed, FnMut<void()> saveCallback) override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class GroupsInvitePrivacyController : public EditPrivacyBox::Controller, private base::Subscriber {
|
|
||||||
public:
|
|
||||||
using Option = EditPrivacyBox::Option;
|
|
||||||
using Exception = EditPrivacyBox::Exception;
|
|
||||||
|
|
||||||
Key key() override;
|
|
||||||
MTPInputPrivacyKey apiKey() override;
|
|
||||||
|
|
||||||
QString title() override;
|
|
||||||
bool hasOption(Option option) override;
|
|
||||||
QString description() override;
|
|
||||||
QString exceptionLinkText(Exception exception, int count) override;
|
|
||||||
QString exceptionBoxTitle(Exception exception) override;
|
|
||||||
QString exceptionsDescription() override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class CallsPrivacyController : public EditPrivacyBox::Controller, private base::Subscriber {
|
|
||||||
public:
|
|
||||||
using Option = EditPrivacyBox::Option;
|
|
||||||
using Exception = EditPrivacyBox::Exception;
|
|
||||||
|
|
||||||
Key key() override;
|
|
||||||
MTPInputPrivacyKey apiKey() override;
|
|
||||||
|
|
||||||
QString title() override;
|
|
||||||
QString description() override;
|
|
||||||
QString exceptionLinkText(Exception exception, int count) override;
|
|
||||||
QString exceptionBoxTitle(Exception exception) override;
|
|
||||||
QString exceptionsDescription() override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,317 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_privacy_widget.h"
|
|
||||||
|
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "application.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
#include "data/data_session.h"
|
|
||||||
#include "platform/platform_specific.h"
|
|
||||||
#include "core/update_checker.h"
|
|
||||||
#include "base/openssl_help.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
#include "boxes/sessions_box.h"
|
|
||||||
#include "boxes/passcode_box.h"
|
|
||||||
#include "boxes/autolock_box.h"
|
|
||||||
#include "boxes/peer_list_box.h"
|
|
||||||
#include "boxes/edit_privacy_box.h"
|
|
||||||
#include "boxes/self_destruction_box.h"
|
|
||||||
#include "old_settings/settings_privacy_controllers.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
LocalPasscodeState::LocalPasscodeState(QWidget *parent) : RpWidget(parent)
|
|
||||||
, _edit(this, GetEditPasscodeText(), st::boxLinkButton)
|
|
||||||
, _turnOff(this, lang(lng_passcode_turn_off), st::boxLinkButton) {
|
|
||||||
updateControls();
|
|
||||||
connect(_edit, SIGNAL(clicked()), this, SLOT(onEdit()));
|
|
||||||
connect(_turnOff, SIGNAL(clicked()), this, SLOT(onTurnOff()));
|
|
||||||
subscribe(Global::RefLocalPasscodeChanged(), [this]() { updateControls(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
int LocalPasscodeState::resizeGetHeight(int newWidth) {
|
|
||||||
_edit->moveToLeft(0, 0, newWidth);
|
|
||||||
_turnOff->moveToRight(0, 0, newWidth);
|
|
||||||
return _edit->height();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPasscodeState::onEdit() {
|
|
||||||
Ui::show(Box<PasscodeBox>(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPasscodeState::onTurnOff() {
|
|
||||||
Ui::show(Box<PasscodeBox>(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPasscodeState::updateControls() {
|
|
||||||
_edit->setText(GetEditPasscodeText());
|
|
||||||
_edit->moveToLeft(0, 0);
|
|
||||||
_turnOff->setVisible(Global::LocalPasscode());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LocalPasscodeState::GetEditPasscodeText() {
|
|
||||||
return lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on);
|
|
||||||
}
|
|
||||||
|
|
||||||
CloudPasswordState::CloudPasswordState(QWidget *parent) : RpWidget(parent)
|
|
||||||
, _edit(this, lang(lng_cloud_password_set), st::boxLinkButton)
|
|
||||||
, _turnOff(this, lang(lng_passcode_turn_off), st::boxLinkButton) {
|
|
||||||
_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() {
|
|
||||||
if (_unknownPasswordAlgo
|
|
||||||
|| !_newPasswordAlgo
|
|
||||||
|| !_newSecureSecretAlgo) {
|
|
||||||
const auto box = std::make_shared<QPointer<BoxContent>>();
|
|
||||||
const auto callback = [=] {
|
|
||||||
Core::UpdateApplication();
|
|
||||||
if (*box) (*box)->closeBox();
|
|
||||||
};
|
|
||||||
*box = Ui::show(Box<ConfirmBox>(
|
|
||||||
lang(lng_passport_app_out_of_date),
|
|
||||||
lang(lng_menu_update),
|
|
||||||
callback));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto box = Ui::show(Box<PasscodeBox>(
|
|
||||||
_curPasswordRequest,
|
|
||||||
_newPasswordAlgo,
|
|
||||||
_hasPasswordRecovery,
|
|
||||||
_notEmptyPassport,
|
|
||||||
_curPasswordHint,
|
|
||||||
_newSecureSecretAlgo));
|
|
||||||
rpl::merge(
|
|
||||||
box->newPasswordSet() | rpl::map([] { return rpl::empty_value(); }),
|
|
||||||
box->passwordReloadNeeded()
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
onReloadPassword();
|
|
||||||
}, box->lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloudPasswordState::onTurnOff() {
|
|
||||||
if (_unknownPasswordAlgo
|
|
||||||
|| !_newPasswordAlgo
|
|
||||||
|| !_newSecureSecretAlgo) {
|
|
||||||
const auto box = std::make_shared<QPointer<BoxContent>>();
|
|
||||||
const auto callback = [=] {
|
|
||||||
Core::UpdateApplication();
|
|
||||||
if (*box) (*box)->closeBox();
|
|
||||||
};
|
|
||||||
*box = Ui::show(Box<ConfirmBox>(
|
|
||||||
lang(lng_passport_app_out_of_date),
|
|
||||||
lang(lng_menu_update),
|
|
||||||
callback));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!_curPasswordRequest) {
|
|
||||||
_turnOff->hide();
|
|
||||||
|
|
||||||
MTP::send(
|
|
||||||
MTPaccount_UpdatePasswordSettings(
|
|
||||||
MTP_inputCheckPasswordEmpty(),
|
|
||||||
MTP_account_passwordInputSettings(
|
|
||||||
MTP_flags(
|
|
||||||
MTPDaccount_passwordInputSettings::Flag::f_email),
|
|
||||||
MTP_passwordKdfAlgoUnknown(), // new_algo
|
|
||||||
MTP_bytes(QByteArray()), // new_password_hash
|
|
||||||
MTP_string(QString()), // hint
|
|
||||||
MTP_string(QString()), // email
|
|
||||||
MTPSecureSecretSettings())),
|
|
||||||
rpcDone(&CloudPasswordState::offPasswordDone),
|
|
||||||
rpcFail(&CloudPasswordState::offPasswordFail));
|
|
||||||
} else {
|
|
||||||
auto box = Ui::show(Box<PasscodeBox>(
|
|
||||||
_curPasswordRequest,
|
|
||||||
_newPasswordAlgo,
|
|
||||||
_hasPasswordRecovery,
|
|
||||||
_notEmptyPassport,
|
|
||||||
_curPasswordHint,
|
|
||||||
_newSecureSecretAlgo,
|
|
||||||
true));
|
|
||||||
rpl::merge(
|
|
||||||
box->newPasswordSet(
|
|
||||||
) | rpl::map([] { return rpl::empty_value(); }),
|
|
||||||
box->passwordReloadNeeded()
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
onReloadPassword();
|
|
||||||
}, box->lifetime());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloudPasswordState::onReloadPassword() {
|
|
||||||
if (_reloadRequestId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_reloadRequestId = MTP::send(MTPaccount_GetPassword(), rpcDone(&CloudPasswordState::getPasswordDone), rpcFail(&CloudPasswordState::getPasswordFail));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloudPasswordState::onReloadPassword(Qt::ApplicationState state) {
|
|
||||||
if (!_waitingConfirm.isEmpty() && state == Qt::ApplicationActive) {
|
|
||||||
onReloadPassword();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloudPasswordState::getPasswordDone(const MTPaccount_Password &result) {
|
|
||||||
Expects(result.type() == mtpc_account_password);
|
|
||||||
|
|
||||||
_reloadRequestId = 0;
|
|
||||||
_waitingConfirm = QString();
|
|
||||||
|
|
||||||
const auto &d = result.c_account_password();
|
|
||||||
_curPasswordRequest = Core::ParseCloudPasswordCheckRequest(d);
|
|
||||||
_unknownPasswordAlgo = d.has_current_algo() && !_curPasswordRequest;
|
|
||||||
_hasPasswordRecovery = d.is_has_recovery();
|
|
||||||
_notEmptyPassport = d.is_has_secure_values();
|
|
||||||
_curPasswordHint = qs(d.vhint);
|
|
||||||
_newPasswordAlgo = Core::ValidateNewCloudPasswordAlgo(
|
|
||||||
Core::ParseCloudPasswordAlgo(d.vnew_algo));
|
|
||||||
_newSecureSecretAlgo = Core::ValidateNewSecureSecretAlgo(
|
|
||||||
Core::ParseSecureSecretAlgo(d.vnew_secure_algo));
|
|
||||||
const auto pattern = d.has_email_unconfirmed_pattern()
|
|
||||||
? qs(d.vemail_unconfirmed_pattern)
|
|
||||||
: QString();
|
|
||||||
if (!pattern.isEmpty()) {
|
|
||||||
_waitingConfirm = lng_cloud_password_waiting(lt_email, pattern);
|
|
||||||
}
|
|
||||||
openssl::AddRandomSeed(bytes::make_span(d.vsecure_random.v));
|
|
||||||
|
|
||||||
_edit->setText(lang(hasCloudPassword()
|
|
||||||
? lng_cloud_password_edit
|
|
||||||
: lng_cloud_password_set));
|
|
||||||
_edit->setVisible(_waitingConfirm.isEmpty());
|
|
||||||
_turnOff->setVisible(!_waitingConfirm.isEmpty() || hasCloudPassword());
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CloudPasswordState::hasCloudPassword() const {
|
|
||||||
return (_curPasswordRequest || _unknownPasswordAlgo);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CloudPasswordState::getPasswordFail(const RPCError &error) {
|
|
||||||
if (MTP::isDefaultHandledError(error)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_reloadRequestId = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloudPasswordState::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
|
|
||||||
auto text = st::boxTextFont->elided(_waitingConfirm, width() - _turnOff->width() - st::boxTextFont->spacew);
|
|
||||||
if (!text.isEmpty()) {
|
|
||||||
p.setPen(st::windowFg);
|
|
||||||
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(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
QString PrivacyWidget::GetAutoLockText() {
|
|
||||||
return (Global::AutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, Global::AutoLock() / 60) : lng_passcode_autolock_hours(lt_count, Global::AutoLock() / 3600);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::createControls() {
|
|
||||||
style::margins marginSmall(0, 0, 0, st::settingsSmallSkip);
|
|
||||||
style::margins marginSkip(0, 0, 0, st::settingsSkip);
|
|
||||||
style::margins slidedPadding(0, marginSmall.bottom() / 2, 0, marginSmall.bottom() - (marginSmall.bottom() / 2));
|
|
||||||
|
|
||||||
createChildRow(_blockedUsers, marginSmall, lang(lng_settings_blocked_users), SLOT(onBlockedUsers()));
|
|
||||||
createChildRow(_lastSeenPrivacy, marginSmall, lang(lng_settings_last_seen_privacy), SLOT(onLastSeenPrivacy()));
|
|
||||||
createChildRow(_callsPrivacy, marginSmall, lang(lng_settings_calls_privacy), SLOT(onCallsPrivacy()));
|
|
||||||
createChildRow(_groupsInvitePrivacy, marginSmall, lang(lng_settings_groups_invite_privacy), SLOT(onGroupsInvitePrivacy()));
|
|
||||||
createChildRow(_localPasscodeState, marginSmall);
|
|
||||||
auto label = lang(psIdleSupported() ? lng_passcode_autolock_away : lng_passcode_autolock_inactive);
|
|
||||||
auto value = GetAutoLockText();
|
|
||||||
createChildRow(_autoLock, marginSmall, slidedPadding, label, value, LabeledLink::Type::Primary, SLOT(onAutoLock()));
|
|
||||||
if (!Global::LocalPasscode()) {
|
|
||||||
_autoLock->hide(anim::type::instant);
|
|
||||||
}
|
|
||||||
createChildRow(_cloudPasswordState, marginSmall);
|
|
||||||
createChildRow(_selfDestruction, marginSmall, lang(lng_settings_self_destruct), SLOT(onSelfDestruction()));
|
|
||||||
createChildRow(_showAllSessions, marginSmall, lang(lng_settings_show_sessions), SLOT(onShowSessions()));
|
|
||||||
createChildRow(_exportData, marginSmall, lang(lng_settings_export_data), SLOT(onExportData()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::autoLockUpdated() {
|
|
||||||
if (Global::LocalPasscode()) {
|
|
||||||
auto value = GetAutoLockText();
|
|
||||||
_autoLock->entity()->link()->setText(value);
|
|
||||||
resizeToWidth(width());
|
|
||||||
}
|
|
||||||
_autoLock->toggle(
|
|
||||||
Global::LocalPasscode(),
|
|
||||||
anim::type::normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onBlockedUsers() {
|
|
||||||
Ui::show(Box<PeerListBox>(std::make_unique<BlockedBoxController>(), [](not_null<PeerListBox*> box) {
|
|
||||||
box->addButton(langFactory(lng_close), [box] { box->closeBox(); });
|
|
||||||
box->addLeftButton(langFactory(lng_blocked_list_add), [=] { BlockedBoxController::BlockNewUser(); });
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onLastSeenPrivacy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onCallsPrivacy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onGroupsInvitePrivacy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onAutoLock() {
|
|
||||||
Ui::show(Box<AutoLockBox>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onShowSessions() {
|
|
||||||
Ui::show(Box<SessionsBox>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onSelfDestruction() {
|
|
||||||
Ui::show(Box<SelfDestructionBox>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrivacyWidget::onExportData() {
|
|
||||||
Ui::hideSettingsAndLayer();
|
|
||||||
App::CallDelayed(
|
|
||||||
st::boxDuration,
|
|
||||||
&Auth(),
|
|
||||||
[] { Auth().data().startExport(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,115 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
#include "old_settings/settings_chat_settings_widget.h"
|
|
||||||
#include "core/core_cloud_password.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class LocalPasscodeState : public Ui::RpWidget, private base::Subscriber {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
LocalPasscodeState(QWidget *parent);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onEdit();
|
|
||||||
void onTurnOff();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static QString GetEditPasscodeText();
|
|
||||||
|
|
||||||
void updateControls();
|
|
||||||
|
|
||||||
object_ptr<Ui::LinkButton> _edit;
|
|
||||||
object_ptr<Ui::LinkButton> _turnOff;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class CloudPasswordState : public Ui::RpWidget, 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();
|
|
||||||
void onReloadPassword(Qt::ApplicationState state);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void getPasswordDone(const MTPaccount_Password &result);
|
|
||||||
bool getPasswordFail(const RPCError &error);
|
|
||||||
void offPasswordDone(const MTPBool &result);
|
|
||||||
bool offPasswordFail(const RPCError &error);
|
|
||||||
|
|
||||||
bool hasCloudPassword() const;
|
|
||||||
|
|
||||||
object_ptr<Ui::LinkButton> _edit;
|
|
||||||
object_ptr<Ui::LinkButton> _turnOff;
|
|
||||||
|
|
||||||
QString _waitingConfirm;
|
|
||||||
Core::CloudPasswordCheckRequest _curPasswordRequest;
|
|
||||||
bool _unknownPasswordAlgo = false;
|
|
||||||
bool _hasPasswordRecovery = false;
|
|
||||||
bool _notEmptyPassport = false;
|
|
||||||
QString _curPasswordHint;
|
|
||||||
Core::CloudPasswordAlgo _newPasswordAlgo;
|
|
||||||
Core::SecureSecretAlgo _newSecureSecretAlgo;
|
|
||||||
mtpRequestId _reloadRequestId = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class PrivacyWidget : public BlockWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
PrivacyWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onBlockedUsers();
|
|
||||||
void onLastSeenPrivacy();
|
|
||||||
void onCallsPrivacy();
|
|
||||||
void onGroupsInvitePrivacy();
|
|
||||||
void onAutoLock();
|
|
||||||
void onShowSessions();
|
|
||||||
void onSelfDestruction();
|
|
||||||
void onExportData();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static QString GetAutoLockText();
|
|
||||||
|
|
||||||
void createControls();
|
|
||||||
void autoLockUpdated();
|
|
||||||
|
|
||||||
Ui::LinkButton *_blockedUsers = nullptr;
|
|
||||||
Ui::LinkButton *_lastSeenPrivacy = nullptr;
|
|
||||||
Ui::LinkButton *_callsPrivacy = nullptr;
|
|
||||||
Ui::LinkButton *_groupsInvitePrivacy = nullptr;
|
|
||||||
LocalPasscodeState *_localPasscodeState = nullptr;
|
|
||||||
Ui::SlideWrap<LabeledLink> *_autoLock = nullptr;
|
|
||||||
CloudPasswordState *_cloudPasswordState = nullptr;
|
|
||||||
Ui::LinkButton *_showAllSessions = nullptr;
|
|
||||||
Ui::LinkButton *_selfDestruction = nullptr;
|
|
||||||
Ui::LinkButton *_exportData = nullptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_scale_widget.h"
|
|
||||||
|
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
#include "application.h"
|
|
||||||
#include "ui/widgets/discrete_sliders.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
QString scaleLabel(DBIScale scale) {
|
|
||||||
switch (scale) {
|
|
||||||
case dbisOne: return qsl("100%");
|
|
||||||
case dbisOneAndQuarter: return qsl("125%");
|
|
||||||
case dbisOneAndHalf: return qsl("150%");
|
|
||||||
case dbisTwo: return qsl("200%");
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
ScaleWidget::ScaleWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_scale)) {
|
|
||||||
createControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScaleWidget::createControls() {
|
|
||||||
style::margins margin(0, 0, 0, st::settingsSmallSkip);
|
|
||||||
|
|
||||||
createChildRow(_auto, margin, lng_settings_scale_auto(lt_cur, scaleLabel(cScreenScale())), [this](bool) { onAutoChanged(); }, (cConfigScale() == dbisAuto));
|
|
||||||
createChildRow(_scale, style::margins(0, 0, 0, 0));
|
|
||||||
|
|
||||||
_scale->addSection(scaleLabel(dbisOne));
|
|
||||||
_scale->addSection(scaleLabel(dbisOneAndQuarter));
|
|
||||||
_scale->addSection(scaleLabel(dbisOneAndHalf));
|
|
||||||
_scale->addSection(scaleLabel(dbisTwo));
|
|
||||||
_scale->setActiveSectionFast(cEvalScale(cConfigScale()) - 1);
|
|
||||||
_scale->sectionActivated(
|
|
||||||
) | rpl::start_with_next(
|
|
||||||
[this] { scaleChanged(); },
|
|
||||||
lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScaleWidget::onAutoChanged() {
|
|
||||||
auto newScale = _auto->checked() ? dbisAuto : cEvalScale(cConfigScale());
|
|
||||||
if (newScale == cScreenScale()) {
|
|
||||||
if (newScale != cScale()) {
|
|
||||||
newScale = cScale();
|
|
||||||
} else {
|
|
||||||
switch (newScale) {
|
|
||||||
case dbisOne: newScale = dbisOneAndQuarter; break;
|
|
||||||
case dbisOneAndQuarter: newScale = dbisOne; break;
|
|
||||||
case dbisOneAndHalf: newScale = dbisOneAndQuarter; break;
|
|
||||||
case dbisTwo: newScale = dbisOneAndHalf; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setScale(newScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScaleWidget::setScale(DBIScale newScale) {
|
|
||||||
if (_inSetScale) return;
|
|
||||||
_inSetScale = true;
|
|
||||||
auto guard = gsl::finally([this] { _inSetScale = false; });
|
|
||||||
|
|
||||||
if (newScale == cScreenScale()) newScale = dbisAuto;
|
|
||||||
if (newScale == dbisAuto && !_auto->checked()) {
|
|
||||||
_auto->setChecked(true);
|
|
||||||
} else if (newScale != dbisAuto && _auto->checked()) {
|
|
||||||
_auto->setChecked(false);
|
|
||||||
}
|
|
||||||
_newScale = newScale;
|
|
||||||
if (newScale == dbisAuto) newScale = cScreenScale();
|
|
||||||
if (_scale->activeSection() != newScale - 1) {
|
|
||||||
_scale->setActiveSection(newScale - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cEvalScale(newScale) != cEvalScale(cRealScale())) {
|
|
||||||
Ui::show(Box<ConfirmBox>(lang(lng_settings_need_restart), lang(lng_settings_restart_now), crl::guard(this, [this] {
|
|
||||||
cSetConfigScale(_newScale);
|
|
||||||
Local::writeSettings();
|
|
||||||
App::restart();
|
|
||||||
}), crl::guard(this, [this] {
|
|
||||||
App::CallDelayed(st::boxDuration, this, [this] {
|
|
||||||
setScale(cRealScale());
|
|
||||||
});
|
|
||||||
})));
|
|
||||||
} else {
|
|
||||||
cSetConfigScale(newScale);
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScaleWidget::scaleChanged() {
|
|
||||||
auto newScale = dbisAuto;
|
|
||||||
switch (_scale->activeSection()) {
|
|
||||||
case 0: newScale = dbisOne; break;
|
|
||||||
case 1: newScale = dbisOneAndQuarter; break;
|
|
||||||
case 2: newScale = dbisOneAndHalf; break;
|
|
||||||
case 3: newScale = dbisTwo; break;
|
|
||||||
}
|
|
||||||
setScale(newScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_block_widget.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class Checkbox;
|
|
||||||
class SettingsSlider;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class ScaleWidget : public BlockWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
ScaleWidget(QWidget *parent, UserData *self);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onAutoChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void scaleChanged();
|
|
||||||
void createControls();
|
|
||||||
void setScale(DBIScale newScale);
|
|
||||||
|
|
||||||
Ui::Checkbox *_auto = nullptr;
|
|
||||||
Ui::SettingsSlider *_scale = nullptr;
|
|
||||||
|
|
||||||
DBIScale _newScale = dbisAuto;
|
|
||||||
bool _inSetScale = false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,110 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "old_settings/settings_widget.h"
|
|
||||||
|
|
||||||
#include "old_settings/settings_inner_widget.h"
|
|
||||||
#include "old_settings/settings_fixed_bar.h"
|
|
||||||
#include "platform/platform_specific.h"
|
|
||||||
#include "ui/widgets/scroll_area.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/toast/toast.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "mainwidget.h"
|
|
||||||
#include "data/data_session.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "lang/lang_cloud_manager.h"
|
|
||||||
#include "messenger.h"
|
|
||||||
#include "mtproto/mtp_instance.h"
|
|
||||||
#include "mtproto/dc_options.h"
|
|
||||||
#include "core/file_utilities.h"
|
|
||||||
#include "core/update_checker.h"
|
|
||||||
#include "window/themes/window_theme.h"
|
|
||||||
#include "window/themes/window_theme_editor.h"
|
|
||||||
#include "media/media_audio_track.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "window/window_controller.h"
|
|
||||||
#include "styles/style_old_settings.h"
|
|
||||||
#include "styles/style_window.h"
|
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
Widget::Widget(QWidget *parent) {
|
|
||||||
refreshLang();
|
|
||||||
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
|
|
||||||
|
|
||||||
_inner = setInnerWidget(object_ptr<InnerWidget>(this));
|
|
||||||
setCloseClickHandler([]() {
|
|
||||||
Ui::hideSettingsAndLayer();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::refreshLang() {
|
|
||||||
setTitle(lang(lng_menu_settings));
|
|
||||||
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::scrollToUpdateRow() {
|
|
||||||
if (const auto top = _inner->getUpdateTop(); top >= 0) {
|
|
||||||
scrollToY(top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::keyPressEvent(QKeyEvent *e) {
|
|
||||||
return LayerWidget::keyPressEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::parentResized() {
|
|
||||||
auto parentSize = parentWidget()->size();
|
|
||||||
auto windowWidth = parentSize.width();
|
|
||||||
auto newWidth = st::settingsMaxWidth;
|
|
||||||
auto newContentLeft = st::settingsMaxPadding;
|
|
||||||
if (windowWidth <= st::settingsMaxWidth) {
|
|
||||||
newWidth = windowWidth;
|
|
||||||
newContentLeft = st::settingsMinPadding;
|
|
||||||
if (windowWidth > st::windowMinWidth) {
|
|
||||||
// Width changes from st::windowMinWidth to st::settingsMaxWidth.
|
|
||||||
// Padding changes from st::settingsMinPadding to st::settingsMaxPadding.
|
|
||||||
newContentLeft += ((newWidth - st::windowMinWidth) * (st::settingsMaxPadding - st::settingsMinPadding)) / (st::settingsMaxWidth - st::windowMinWidth);
|
|
||||||
}
|
|
||||||
} else if (windowWidth < st::settingsMaxWidth + 2 * st::settingsMargin) {
|
|
||||||
newWidth = windowWidth - 2 * st::settingsMargin;
|
|
||||||
newContentLeft = st::settingsMinPadding;
|
|
||||||
if (windowWidth > st::windowMinWidth) {
|
|
||||||
// Width changes from st::windowMinWidth to st::settingsMaxWidth.
|
|
||||||
// Padding changes from st::settingsMinPadding to st::settingsMaxPadding.
|
|
||||||
newContentLeft += ((newWidth - st::windowMinWidth) * (st::settingsMaxPadding - st::settingsMinPadding)) / (st::settingsMaxWidth - st::windowMinWidth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resizeToWidth(newWidth, newContentLeft);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::resizeUsingInnerHeight(int newWidth, int innerHeight) {
|
|
||||||
if (!parentWidget()) return;
|
|
||||||
|
|
||||||
auto parentSize = parentWidget()->size();
|
|
||||||
auto windowWidth = parentSize.width();
|
|
||||||
auto windowHeight = parentSize.height();
|
|
||||||
auto maxHeight = st::settingsFixedBarHeight + innerHeight;
|
|
||||||
auto newHeight = maxHeight + st::boxRadius;
|
|
||||||
if (newHeight > windowHeight || newWidth >= windowWidth) {
|
|
||||||
newHeight = windowHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto roundedCorners = newHeight < windowHeight;
|
|
||||||
setRoundedCorners(roundedCorners);
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, !roundedCorners);
|
|
||||||
|
|
||||||
setGeometry((windowWidth - newWidth) / 2, (windowHeight - newHeight) / 2, newWidth, newHeight);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "old_settings/settings_layer.h"
|
|
||||||
|
|
||||||
namespace OldSettings {
|
|
||||||
|
|
||||||
class InnerWidget;
|
|
||||||
|
|
||||||
class Widget : public Layer, private base::Subscriber {
|
|
||||||
public:
|
|
||||||
Widget(QWidget*);
|
|
||||||
|
|
||||||
void refreshLang();
|
|
||||||
void scrollToUpdateRow();
|
|
||||||
|
|
||||||
void parentResized() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void resizeUsingInnerHeight(int newWidth, int innerHeight) override;
|
|
||||||
|
|
||||||
QPointer<InnerWidget> _inner;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Settings
|
|
Loading…
Reference in New Issue