From 177078b0af23e450f3e846fcb32799c26280d027 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 20 Dec 2016 16:03:51 +0300 Subject: [PATCH] Closed beta 10020002: Use default color theme link in Settings. --- Telegram/Resources/langs/lang.strings | 3 +- Telegram/Resources/winrc/Telegram.rc | 8 +- Telegram/Resources/winrc/Updater.rc | 8 +- Telegram/SourceFiles/app.cpp | 110 ++++++----- Telegram/SourceFiles/application.cpp | 100 +++++----- Telegram/SourceFiles/boxes/abstractbox.cpp | 54 ++--- Telegram/SourceFiles/boxes/abstractbox.h | 10 +- Telegram/SourceFiles/boxes/addcontactbox.cpp | 51 ++--- Telegram/SourceFiles/boxes/addcontactbox.h | 11 +- Telegram/SourceFiles/boxes/backgroundbox.cpp | 7 + Telegram/SourceFiles/boxes/backgroundbox.h | 2 +- Telegram/SourceFiles/boxes/boxes.style | 29 ++- Telegram/SourceFiles/boxes/confirmbox.cpp | 23 ++- Telegram/SourceFiles/boxes/confirmbox.h | 7 +- .../SourceFiles/boxes/confirmphonebox.cpp | 3 +- Telegram/SourceFiles/boxes/connectionbox.cpp | 20 +- Telegram/SourceFiles/boxes/contactsbox.cpp | 60 ++++-- Telegram/SourceFiles/boxes/contactsbox.h | 4 +- Telegram/SourceFiles/boxes/members_box.cpp | 187 +++++++++++------- Telegram/SourceFiles/boxes/members_box.h | 40 ++-- Telegram/SourceFiles/boxes/passcodebox.cpp | 8 +- Telegram/SourceFiles/boxes/report_box.cpp | 4 +- Telegram/SourceFiles/boxes/report_box.h | 3 + Telegram/SourceFiles/boxes/send_files_box.cpp | 8 +- Telegram/SourceFiles/boxes/send_files_box.h | 6 + Telegram/SourceFiles/boxes/sessionsbox.cpp | 6 +- Telegram/SourceFiles/boxes/sharebox.cpp | 15 ++ Telegram/SourceFiles/boxes/sharebox.h | 1 + Telegram/SourceFiles/boxes/stickers_box.cpp | 2 + Telegram/SourceFiles/boxes/usernamebox.cpp | 32 ++- Telegram/SourceFiles/boxes/usernamebox.h | 2 +- .../SourceFiles/codegen/style/generator.cpp | 20 +- .../SourceFiles/core/click_handler_types.cpp | 14 +- .../SourceFiles/core/click_handler_types.h | 8 +- Telegram/SourceFiles/core/qthelp_regex.h | 8 + Telegram/SourceFiles/core/qthelp_url.cpp | 5 +- Telegram/SourceFiles/core/version.h | 2 +- Telegram/SourceFiles/dialogswidget.cpp | 2 +- Telegram/SourceFiles/facades.cpp | 18 +- Telegram/SourceFiles/facades.h | 1 + Telegram/SourceFiles/historywidget.cpp | 12 +- Telegram/SourceFiles/layerwidget.cpp | 15 +- Telegram/SourceFiles/layerwidget.h | 4 +- Telegram/SourceFiles/localstorage.cpp | 20 +- Telegram/SourceFiles/localstorage.h | 2 + Telegram/SourceFiles/mainwidget.cpp | 51 ++--- Telegram/SourceFiles/mainwidget.h | 2 +- .../SourceFiles/media/view/mediaview.style | 1 - .../SourceFiles/overview/overview_layout.cpp | 16 ++ .../SourceFiles/overview/overview_layout.h | 7 + Telegram/SourceFiles/overviewwidget.cpp | 17 ++ Telegram/SourceFiles/overviewwidget.h | 1 + Telegram/SourceFiles/pspecific_linux.cpp | 10 +- .../settings/settings_background_widget.cpp | 44 ++++- .../settings/settings_background_widget.h | 7 +- .../SourceFiles/ui/effects/round_checkbox.cpp | 9 + .../SourceFiles/ui/effects/round_checkbox.h | 6 + Telegram/SourceFiles/ui/twidget.cpp | 2 +- Telegram/SourceFiles/ui/widgets/buttons.cpp | 2 +- .../SourceFiles/ui/widgets/input_fields.cpp | 6 +- .../SourceFiles/ui/widgets/input_fields.h | 12 ++ .../SourceFiles/ui/widgets/multi_select.cpp | 2 +- Telegram/SourceFiles/ui/widgets/widgets.style | 2 - Telegram/SourceFiles/window/main_window.cpp | 7 +- .../window/notifications_manager.cpp | 4 + .../SourceFiles/window/top_bar_widget.cpp | 2 +- Telegram/SourceFiles/window/window_theme.cpp | 29 ++- Telegram/SourceFiles/window/window_theme.h | 2 + Telegram/build/build.bat | 9 +- Telegram/build/version | 2 +- 70 files changed, 788 insertions(+), 419 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 20d08b33c..c79ae8b07 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -289,6 +289,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_send_cmdenter" = "Send by Cmd+Enter"; "lng_settings_section_background" = "Chat background"; +"lng_settings_bg_use_default" = "Use default color theme"; "lng_settings_bg_from_gallery" = "Choose from gallery"; "lng_settings_bg_from_file" = "Choose from file"; "lng_settings_bg_tile" = "Tile background"; @@ -347,7 +348,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_passcode_enter_first" = "Enter a passcode"; "lng_passcode_enter_new" = "Enter new passcode"; "lng_passcode_confirm_new" = "Re-enter new passcode"; -"lng_passcode_about" = "When a local passcode is set, a lock icon appears in the top right corner of the window. Click it to lock the app.\n\nNote: if you forget your local passcode, you'll need to relogin in Telegram Desktop."; +"lng_passcode_about" = "When a local passcode is set, a lock icon appears at the top of your chats list. Click it to lock the app.\n\nNote: if you forget your local passcode, you'll need to relogin in Telegram Desktop."; "lng_passcode_differ" = "Passcodes are different"; "lng_passcode_wrong" = "Wrong passcode"; "lng_passcode_is_same" = "Passcode was not changed"; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 5f2d01a9b..140880783 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,20,1 - PRODUCTVERSION 0,10,20,1 + FILEVERSION 0,10,20,2 + PRODUCTVERSION 0,10,20,2 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.20.1" + VALUE "FileVersion", "0.10.20.2" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.20.1" + VALUE "ProductVersion", "0.10.20.2" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 839431d7f..99f3e1769 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,20,1 - PRODUCTVERSION 0,10,20,1 + FILEVERSION 0,10,20,2 + PRODUCTVERSION 0,10,20,2 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,10 +43,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram Messenger LLP" VALUE "FileDescription", "Telegram Updater" - VALUE "FileVersion", "0.10.20.1" + VALUE "FileVersion", "0.10.20.2" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.20.1" + VALUE "ProductVersion", "0.10.20.2" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index f793fd904..31e395ef0 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -2211,26 +2211,7 @@ namespace { return MsgRadius; } - void initMedia() { - if (!::monofont) { - QString family; - tryFontFamily(family, qsl("Consolas")); - tryFontFamily(family, qsl("Liberation Mono")); - tryFontFamily(family, qsl("Menlo")); - tryFontFamily(family, qsl("Courier")); - if (family.isEmpty()) family = QFontDatabase::systemFont(QFontDatabase::FixedFont).family(); - ::monofont = style::font(st::normalFont->f.pixelSize(), 0, family); - } - emojiInit(); - if (!::emoji) { - ::emoji = new QPixmap(QLatin1String(EName)); - if (cRetina()) ::emoji->setDevicePixelRatio(cRetinaFactor()); - } - if (!::emojiLarge) { - ::emojiLarge = new QPixmap(QLatin1String(EmojiNames[EIndex + 1])); - if (cRetina()) ::emojiLarge->setDevicePixelRatio(cRetinaFactor()); - } - + void createCorners() { style::color white = { 255, 255, 255, 255 }; QImage mask[4]; prepareCorners(LargeMaskCorners, msgRadius(), white, nullptr, mask); @@ -2272,22 +2253,69 @@ namespace { prepareCorners(MessageInSelectedCorners, msgRadius(), st::msgInBgSelected, &st::msgInShadowSelected); prepareCorners(MessageOutCorners, msgRadius(), st::msgOutBg, &st::msgOutShadow); prepareCorners(MessageOutSelectedCorners, msgRadius(), st::msgOutBgSelected, &st::msgOutShadowSelected); + } - static auto subscription = Window::Theme::Background()->add_subscription([](const Window::Theme::BackgroundUpdate &update) { - if (update.type != Window::Theme::BackgroundUpdate::Type::New) { - return; + void clearCorners() { + for (int j = 0; j < 4; ++j) { + for (int i = 0; i < RoundCornersCount; ++i) { + delete ::corners[i].p[j]; ::corners[i].p[j] = nullptr; } - for (int i = 0; i < 4; ++i) { - delete ::corners[StickerCorners].p[i]; ::corners[StickerCorners].p[i] = nullptr; - delete ::corners[StickerSelectedCorners].p[i]; ::corners[StickerSelectedCorners].p[i] = nullptr; + delete ::cornersMaskSmall[j]; ::cornersMaskSmall[j] = nullptr; + delete ::cornersMaskLarge[j]; ::cornersMaskLarge[j] = nullptr; + } + for (auto i = ::cornersMap.cbegin(), e = ::cornersMap.cend(); i != e; ++i) { + for (int j = 0; j < 4; ++j) { + delete i->p[j]; } - prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg); - prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceSelectBg); + } + ::cornersMap.clear(); + } - if (App::main()) { - App::main()->updateScrollColors(); + void initMedia() { + if (!::monofont) { + QString family; + tryFontFamily(family, qsl("Consolas")); + tryFontFamily(family, qsl("Liberation Mono")); + tryFontFamily(family, qsl("Menlo")); + tryFontFamily(family, qsl("Courier")); + if (family.isEmpty()) family = QFontDatabase::systemFont(QFontDatabase::FixedFont).family(); + ::monofont = style::font(st::normalFont->f.pixelSize(), 0, family); + } + emojiInit(); + if (!::emoji) { + ::emoji = new QPixmap(QLatin1String(EName)); + if (cRetina()) ::emoji->setDevicePixelRatio(cRetinaFactor()); + } + if (!::emojiLarge) { + ::emojiLarge = new QPixmap(QLatin1String(EmojiNames[EIndex + 1])); + if (cRetina()) ::emojiLarge->setDevicePixelRatio(cRetinaFactor()); + } + + createCorners(); + + using Update = Window::Theme::BackgroundUpdate; + static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) { + if (update.type == Update::Type::TestingTheme) { + clearCorners(); + createCorners(); + + if (App::main()) { + App::main()->updateScrollColors(); + } + HistoryLayout::serviceColorsUpdated(); + } else if (update.type == Update::Type::New) { + for (int i = 0; i < 4; ++i) { + delete ::corners[StickerCorners].p[i]; ::corners[StickerCorners].p[i] = nullptr; + delete ::corners[StickerSelectedCorners].p[i]; ::corners[StickerSelectedCorners].p[i] = nullptr; + } + prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg); + prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceSelectBg); + + if (App::main()) { + App::main()->updateScrollColors(); + } + HistoryLayout::serviceColorsUpdated(); } - HistoryLayout::serviceColorsUpdated(); }); } @@ -2305,22 +2333,12 @@ namespace { void deinitMedia() { delete ::emoji; - ::emoji = 0; + ::emoji = nullptr; delete ::emojiLarge; - ::emojiLarge = 0; - for (int j = 0; j < 4; ++j) { - for (int i = 0; i < RoundCornersCount; ++i) { - delete ::corners[i].p[j]; ::corners[i].p[j] = nullptr; - } - delete ::cornersMaskSmall[j]; ::cornersMaskSmall[j] = nullptr; - delete ::cornersMaskLarge[j]; ::cornersMaskLarge[j] = nullptr; - } - for (auto i = ::cornersMap.cbegin(), e = ::cornersMap.cend(); i != e; ++i) { - for (int j = 0; j < 4; ++j) { - delete i->p[j]; - } - } - ::cornersMap.clear(); + ::emojiLarge = nullptr; + + clearCorners(); + mainEmojiMap.clear(); otherEmojiMap.clear(); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index e197fc2b2..698842594 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -40,58 +40,60 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "history/history_location_manager.h" namespace { - void mtpStateChanged(int32 dc, int32 state) { - if (App::wnd()) { - App::wnd()->mtpStateChanged(dc, state); - } - } - void mtpSessionReset(int32 dc) { - if (App::main() && dc == MTP::maindc()) { - App::main()->getDifference(); - } - } - - QChar _toHex(ushort v) { - v = v & 0x000F; - return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v)); - } - ushort _fromHex(QChar c) { - return ((c.unicode() >= uchar('a')) ? (c.unicode() - uchar('a') + 10) : (c.unicode() - uchar('0'))) & 0x000F; - } - - QString _escapeTo7bit(const QString &str) { - QString result; - result.reserve(str.size() * 2); - for (int i = 0, l = str.size(); i != l; ++i) { - QChar ch(str.at(i)); - ushort uch(ch.unicode()); - if (uch < 32 || uch > 127 || uch == ushort(uchar('%'))) { - result.append('%').append(_toHex(uch >> 12)).append(_toHex(uch >> 8)).append(_toHex(uch >> 4)).append(_toHex(uch)); - } else { - result.append(ch); - } - } - return result; - } - - QString _escapeFrom7bit(const QString &str) { - QString result; - result.reserve(str.size()); - for (int i = 0, l = str.size(); i != l; ++i) { - QChar ch(str.at(i)); - if (ch == QChar::fromLatin1('%') && i + 4 < l) { - result.append(QChar(ushort((_fromHex(str.at(i + 1)) << 12) | (_fromHex(str.at(i + 2)) << 8) | (_fromHex(str.at(i + 3)) << 4) | _fromHex(str.at(i + 4))))); - i += 4; - } else { - result.append(ch); - } - } - return result; +void mtpStateChanged(int32 dc, int32 state) { + if (App::wnd()) { + App::wnd()->mtpStateChanged(dc, state); } } -AppClass *AppObject = 0; +void mtpSessionReset(int32 dc) { + if (App::main() && dc == MTP::maindc()) { + App::main()->getDifference(); + } +} + +QChar _toHex(ushort v) { + v = v & 0x000F; + return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v)); +} +ushort _fromHex(QChar c) { + return ((c.unicode() >= uchar('a')) ? (c.unicode() - uchar('a') + 10) : (c.unicode() - uchar('0'))) & 0x000F; +} + +QString _escapeTo7bit(const QString &str) { + QString result; + result.reserve(str.size() * 2); + for (int i = 0, l = str.size(); i != l; ++i) { + QChar ch(str.at(i)); + ushort uch(ch.unicode()); + if (uch < 32 || uch > 127 || uch == ushort(uchar('%'))) { + result.append('%').append(_toHex(uch >> 12)).append(_toHex(uch >> 8)).append(_toHex(uch >> 4)).append(_toHex(uch)); + } else { + result.append(ch); + } + } + return result; +} + +QString _escapeFrom7bit(const QString &str) { + QString result; + result.reserve(str.size()); + for (int i = 0, l = str.size(); i != l; ++i) { + QChar ch(str.at(i)); + if (ch == QChar::fromLatin1('%') && i + 4 < l) { + result.append(QChar(ushort((_fromHex(str.at(i + 1)) << 12) | (_fromHex(str.at(i + 2)) << 8) | (_fromHex(str.at(i + 3)) << 4) | _fromHex(str.at(i + 4))))); + i += 4; + } else { + result.append(ch); + } + } + return result; +} + +} // namespace + +AppClass *AppObject = nullptr; Application::Application(int &argc, char **argv) : QApplication(argc, argv) { QByteArray d(QFile::encodeName(QDir(cWorkingDir()).absolutePath())); @@ -468,6 +470,8 @@ void Application::stopUpdate() { } void Application::startUpdateCheck(bool forceWait) { + if (!Sandbox::started()) return; + _updateCheckTimer.stop(); if (_updateThread || _updateReply || !cAutoUpdate()) return; diff --git a/Telegram/SourceFiles/boxes/abstractbox.cpp b/Telegram/SourceFiles/boxes/abstractbox.cpp index 126f75cfd..8afbc33f9 100644 --- a/Telegram/SourceFiles/boxes/abstractbox.cpp +++ b/Telegram/SourceFiles/boxes/abstractbox.cpp @@ -53,17 +53,9 @@ void BoxContent::setInner(object_ptr inner, const style::ScrollArea &st connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); _topShadow.create(this, object_ptr(this)); - if (_innerTopSkip > 0) { - _topShadow->showFast(); - } else { - _topShadow->hideFast(); - } - - _bottomShadow.create(this); - _bottomShadow->show(); - } else { - _scroll->setGeometryToLeft(0, _innerTopSkip, width(), 0); + _bottomShadow.create(this, object_ptr(this)); } + _scroll->setGeometryToLeft(0, _innerTopSkip, width(), 0); _scroll->setOwnedWidget(std_::move(inner)); updateScrollAreaGeometry(); } else { @@ -99,17 +91,28 @@ void BoxContent::onDraggingScrollTimer() { _scroll->scrollToY(_scroll->scrollTop() + delta); } +void BoxContent::updateInnerVisibleTopBottom() { + if (auto widget = static_cast(_scroll->widget())) { + auto top = _scroll->scrollTop(); + widget->setVisibleTopBottom(top, top + _scroll->height()); + } +} + void BoxContent::onScroll() { if (_scroll) { + updateInnerVisibleTopBottom(); + auto top = _scroll->scrollTop(); - if (auto widget = static_cast(_scroll->widget())) { - widget->setVisibleTopBottom(top, top + _scroll->height()); - } if (top > 0 || _innerTopSkip > 0) { _topShadow->showAnimated(); } else { _topShadow->hideAnimated(); } + if (top < _scroll->scrollTopMax()) { + _bottomShadow->showAnimated(); + } else { + _bottomShadow->hideAnimated(); + } } } @@ -123,11 +126,6 @@ void BoxContent::setInnerTopSkip(int innerTopSkip, bool scrollBottomFixed) { if (scrollBottomFixed) { _scroll->scrollToY(scrollTopWas + delta); } - if (_innerTopSkip > 0) { - _topShadow->showFast(); - } else { - _topShadow->hideFast(); - } } } } @@ -161,10 +159,22 @@ void BoxContent::updateScrollAreaGeometry() { _scroll->setGeometryToLeft(0, _innerTopSkip, width(), newScrollHeight); _topShadow->entity()->resize(width(), st::lineWidth); _topShadow->moveToLeft(0, _innerTopSkip); - _bottomShadow->resize(width(), st::lineWidth); + _bottomShadow->entity()->resize(width(), st::lineWidth); _bottomShadow->moveToLeft(0, height() - st::lineWidth); if (changed) { - onScroll(); + updateInnerVisibleTopBottom(); + + auto top = _scroll->scrollTop(); + if (top > 0 || _innerTopSkip > 0) { + _topShadow->showFast(); + } else { + _topShadow->hideFast(); + } + if (top < _scroll->scrollTopMax()) { + _bottomShadow->showFast(); + } else { + _bottomShadow->hideFast(); + } } } @@ -182,8 +192,8 @@ void BoxContent::paintEvent(QPaintEvent *e) { } } -AbstractBox::AbstractBox(object_ptr content) -: _content(std_::move(content)) { +AbstractBox::AbstractBox(QWidget *parent, object_ptr content) : LayerWidget(parent) +, _content(std_::move(content)) { _content->setParent(this); _content->setDelegate(this); } diff --git a/Telegram/SourceFiles/boxes/abstractbox.h b/Telegram/SourceFiles/boxes/abstractbox.h index 4135de9eb..834f0337f 100644 --- a/Telegram/SourceFiles/boxes/abstractbox.h +++ b/Telegram/SourceFiles/boxes/abstractbox.h @@ -65,6 +65,7 @@ public: void setDelegate(BoxContentDelegate *newDelegate) { _delegate = newDelegate; prepare(); + setInnerFocus(); } virtual void setInnerFocus() { setFocus(); @@ -121,16 +122,16 @@ protected: template QPointer setInnerWidget(object_ptr inner, const style::ScrollArea &st, int topSkip = 0) { auto result = QPointer(inner.data()); - setInner(std_::move(inner), st); setInnerTopSkip(topSkip); + setInner(std_::move(inner), st); return result; } template QPointer setInnerWidget(object_ptr inner, int topSkip = 0) { auto result = QPointer(inner.data()); - setInner(std_::move(inner)); setInnerTopSkip(topSkip); + setInner(std_::move(inner)); return result; } @@ -154,6 +155,7 @@ private: void setInner(object_ptr inner); void setInner(object_ptr inner, const style::ScrollArea &st); void updateScrollAreaGeometry(); + void updateInnerVisibleTopBottom(); object_ptr doTakeInnerWidget(); BoxContentDelegate *getDelegate() const { @@ -166,7 +168,7 @@ private: int _innerTopSkip = 0; object_ptr _scroll = { nullptr }; object_ptr> _topShadow = { nullptr }; - object_ptr _bottomShadow = { nullptr }; + object_ptr> _bottomShadow = { nullptr }; object_ptr _draggingScrollTimer = { nullptr }; int _draggingScrollDelta = 0; @@ -175,7 +177,7 @@ private: class AbstractBox : public LayerWidget, public BoxContentDelegate, protected base::Subscriber { public: - AbstractBox(object_ptr content); + AbstractBox(QWidget *parent, object_ptr content); void parentResized() override; diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp index e746a7f7a..5e4b7e3d5 100644 --- a/Telegram/SourceFiles/boxes/addcontactbox.cpp +++ b/Telegram/SourceFiles/boxes/addcontactbox.cpp @@ -33,6 +33,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" #include "ui/widgets/labels.h" +#include "ui/toast/toast.h" #include "ui/buttons/peer_avatar_button.h" #include "mainwidget.h" #include "mainwindow.h" @@ -74,21 +75,15 @@ void AddContactBox::prepare() { connect(_last, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); connect(_phone, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); - if ((_first->getLastText().isEmpty() && _last->getLastText().isEmpty()) || !_phone->isEnabled()) { - (_invertOrder ? _last : _first)->setDisplayFocused(true); - _phone->finishAnimations(); - } else { - _phone->setDisplayFocused(true); - } - setDimensions(st::boxWideWidth, st::contactPadding.top() + _first->height() + st::contactSkip + _last->height() + st::contactPhoneSkip + _phone->height() + st::contactPadding.bottom() + st::boxPadding.bottom()); } void AddContactBox::setInnerFocus() { if ((_first->getLastText().isEmpty() && _last->getLastText().isEmpty()) || !_phone->isEnabled()) { - (_invertOrder ? _last : _first)->setFocus(); + (_invertOrder ? _last : _first)->setFocusFast(); + _phone->finishAnimations(); } else { - _phone->setFocus(); + _phone->setFocusFast(); } } @@ -284,13 +279,11 @@ void GroupInfoBox::prepare() { notifyFileQueryUpdated(update); }); - _title->setDisplayFocused(true); - updateMaxHeight(); } void GroupInfoBox::setInnerFocus() { - _title->setFocus(); + _title->setFocusFast(); } void GroupInfoBox::resizeEvent(QResizeEvent *e) { @@ -465,7 +458,7 @@ void SetupChannelBox::setInnerFocus() { if (_link->isHidden()) { setFocus(); } else { - _link->setFocus(); + _link->setFocusFast(); } } @@ -517,16 +510,6 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) { p.setFont(_linkOver ? st::boxTextFont->underline() : st::boxTextFont); p.setPen(st::defaultLinkButton.color); p.drawText(_invitationLink, _channel->inviteLink(), option); - if (!_goodTextLink.isEmpty()) { - auto opacity = _a_goodOpacity.current(getms(), 0.); - if (opacity > 0.) { - p.setOpacity(opacity); - p.setPen(st::boxTextFgGood); - p.setFont(st::boxTextFont); - p.drawTextRight(st::boxPadding.right(), _link->y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, width(), _goodTextLink); - p.setOpacity(1); - } - } } } else { if (!_errorText.isEmpty()) { @@ -559,9 +542,10 @@ void SetupChannelBox::mouseMoveEvent(QMouseEvent *e) { void SetupChannelBox::mousePressEvent(QMouseEvent *e) { if (_linkOver) { Application::clipboard()->setText(_channel->inviteLink()); - _goodTextLink = lang(lng_create_channel_link_copied); - _a_goodOpacity.finish(); - _a_goodOpacity.start([this] { update(); }, 1., 0., st::newGroupLinkFadeDuration); + + Ui::Toast::Config toast; + toast.text = lang(lng_create_channel_link_copied); + Ui::Toast::Show(App::wnd(), toast); } } @@ -669,6 +653,7 @@ void SetupChannelBox::onPrivacyChange() { return; } _link->show(); + _link->setDisplayFocused(true); _link->setFocus(); } else { _link->hide(); @@ -812,12 +797,10 @@ void EditNameTitleBox::prepare() { connect(_first, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); connect(_last, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); _last->setVisible(!_peer->isChat()); - - (_invertOrder ? _last : _first)->setDisplayFocused(true); } void EditNameTitleBox::setInnerFocus() { - (_invertOrder ? _last : _first)->setFocus(); + (_invertOrder ? _last : _first)->setFocusFast(); } void EditNameTitleBox::onSubmit() { @@ -967,13 +950,11 @@ void EditChannelBox::prepare() { _publicLink->setVisible(_channel->canEditUsername()); _sign->setVisible(!_channel->isMegagroup()); - _title->setDisplayFocused(true); - updateMaxHeight(); } void EditChannelBox::setInnerFocus() { - _title->setFocus(); + _title->setFocusFast(); } void EditChannelBox::keyPressEvent(QKeyEvent *e) { @@ -1207,7 +1188,7 @@ void RevokePublicLinkBox::paintEvent(QPaintEvent *e) { Painter p(this); p.translate(0, _rowsTop); for_const (auto &row, _rows) { - paintChat(p, row, (row.peer == _selected), (row.peer == _pressed)); + paintChat(p, row, (row.peer == _selected)); p.translate(0, _rowHeight); } } @@ -1218,7 +1199,7 @@ void RevokePublicLinkBox::resizeEvent(QResizeEvent *e) { _aboutRevoke->moveToLeft(st::boxPadding.left(), st::boxPadding.top()); } -void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selected, bool pressed) const { +void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selected) const { auto peer = row.peer; peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width()); @@ -1234,7 +1215,7 @@ void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selecte row.name.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsNameTop, namew, width()); p.setFont(selected ? st::linkOverFont : st::linkFont); - p.setPen(pressed ? st::defaultLinkButton.downColor : st::defaultLinkButton.color); + p.setPen(selected ? st::defaultLinkButton.overColor : st::defaultLinkButton.color); p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), lang(lng_channels_too_much_public_revoke), _revokeWidth); p.setPen(st::contactsStatusFg); diff --git a/Telegram/SourceFiles/boxes/addcontactbox.h b/Telegram/SourceFiles/boxes/addcontactbox.h index e3f64eb2d..456dc417a 100644 --- a/Telegram/SourceFiles/boxes/addcontactbox.h +++ b/Telegram/SourceFiles/boxes/addcontactbox.h @@ -98,6 +98,9 @@ private slots: void onNext(); void onNameSubmit(); void onDescriptionResized(); + void onClose() { + closeBox(); + } private: void notifyFileQueryUpdated(const FileDialog::QueryUpdate &update); @@ -184,9 +187,6 @@ private: mtpRequestId _checkRequestId = 0; QString _sentUsername, _checkUsername, _errorText, _goodText; - QString _goodTextLink; - Animation _a_goodOpacity; - QTimer _checkTimer; }; @@ -245,6 +245,9 @@ private slots: void onSave(); void onDescriptionResized(); void onPublicLink(); + void onClose() { + closeBox(); + } private: void updateMaxHeight(); @@ -294,7 +297,7 @@ private: PeerData *peer; Text name, status; }; - void paintChat(Painter &p, const ChatRow &row, bool selected, bool pressed) const; + void paintChat(Painter &p, const ChatRow &row, bool selected) const; void getPublicDone(const MTPmessages_Chats &result); bool getPublicFail(const RPCError &error); diff --git a/Telegram/SourceFiles/boxes/backgroundbox.cpp b/Telegram/SourceFiles/boxes/backgroundbox.cpp index 37a082d97..00811a506 100644 --- a/Telegram/SourceFiles/boxes/backgroundbox.cpp +++ b/Telegram/SourceFiles/boxes/backgroundbox.cpp @@ -65,6 +65,13 @@ BackgroundBox::Inner::Inner(QWidget *parent) : TWidget(parent) } subscribe(FileDownload::ImageLoaded(), [this] { update(); }); + using Update = Window::Theme::BackgroundUpdate; + subscribe(Window::Theme::Background(), [this](const Update &update) { + if (update.type == Update::Type::TestingTheme + || update.type == Update::Type::RevertingTheme) { + _check->invalidateCache(); + } + }); setMouseTracking(true); } diff --git a/Telegram/SourceFiles/boxes/backgroundbox.h b/Telegram/SourceFiles/boxes/backgroundbox.h index 49f70522a..c68c26170 100644 --- a/Telegram/SourceFiles/boxes/backgroundbox.h +++ b/Telegram/SourceFiles/boxes/backgroundbox.h @@ -68,6 +68,6 @@ private: int _rows = 0; int _over = -1; int _overDown = -1; - std_::unique_ptr _check; // this not a widget + std_::unique_ptr _check; // this is not a widget }; diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 011705afd..0c57435ff 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -91,17 +91,14 @@ boxTitleClose: IconButton(defaultIconButton) { icon: boxTitleCloseIcon; iconOver: boxTitleCloseIconOver; - rippleAreaPosition: point(4px, 4px); - rippleAreaSize: 48px; + rippleAreaPosition: point(6px, 6px); + rippleAreaSize: 44px; ripple: RippleAnimation(defaultRippleAnimation) { color: windowBgOver; } } -boxLinkButton: LinkButton { - color: #0080c0; - overColor: #0080c0; - downColor: #0073ad; +boxLinkButton: LinkButton(defaultLinkButton) { font: boxTextFont; overFont: font(boxFontSize underline); } @@ -114,7 +111,7 @@ boxVerticalMargin: 10px; boxWidth: 320px; boxWideWidth: 364px; boxPadding: margins(23px, 30px, 23px, 8px); -boxMaxListHeight: 600px; +boxMaxListHeight: 492px; boxLittleSkip: 10px; boxMediumSkip: 20px; @@ -145,7 +142,7 @@ boxTextStyle: TextStyle(defaultTextStyle) { } boxPhotoTitleFont: font(16px semibold); -boxPhotoTitlePosition: point(28px, 26px); +boxPhotoTitlePosition: point(28px, 20px); boxPhotoPadding: margins(28px, 28px, 28px, 18px); boxPhotoCompressedSkip: 20px; boxPhotoCaptionSkip: 8px; @@ -173,7 +170,7 @@ confirmInviteTitleTop: 106px; confirmInvitePhotoSize: 76px; confirmInvitePhotoTop: 20px; confirmInviteStatusTop: 136px; -confirmInviteUserHeight: 80px; +confirmInviteUserHeight: 84px; confirmInviteUserPhotoSize: 56px; confirmInviteUserPhotoTop: 166px; confirmInviteUserName: FlatLabel(defaultFlatLabel) { @@ -406,9 +403,8 @@ sessionTerminate: IconButton { } } sessionTerminateAllButton: LinkButton(boxLinkButton) { - color: #d15948; - overColor: #d15948; - downColor: #db6352; + color: attentionButtonFg; + overColor: attentionButtonFg; } passcodeHeaderFont: font(19px); @@ -453,7 +449,6 @@ setupChannelLink: InputField(defaultInputField) { } newGroupPublicLinkPadding: margins(0px, 20px, 0px, 5px); -newGroupLinkFadeDuration: 5000; themeWarningWidth: boxWideWidth; themeWarningHeight: 150px; @@ -462,9 +457,8 @@ themeWarningTextTop: 60px; aboutWidth: 390px; aboutVersionTop: -3px; aboutVersionLink: LinkButton(defaultLinkButton) { - color: #999999; - overColor: #999999; - downColor: #999999; + color: windowSubTextFg; + overColor: windowSubTextFg; } aboutTextTop: 34px; aboutSkip: 14px; @@ -477,7 +471,8 @@ aboutTextStyle: TextStyle(defaultTextStyle) { lineHeight: 22px; } -autoDownloadTitlePosition: point(23px, 28px); +autoDownloadTopDelta: 10px; +autoDownloadTitlePosition: point(23px, 18px); autoDownloadTitleFont: font(15px semibold); editTextArea: InputField(defaultInputField) { diff --git a/Telegram/SourceFiles/boxes/confirmbox.cpp b/Telegram/SourceFiles/boxes/confirmbox.cpp index 9c36714cd..646591bc8 100644 --- a/Telegram/SourceFiles/boxes/confirmbox.cpp +++ b/Telegram/SourceFiles/boxes/confirmbox.cpp @@ -96,11 +96,20 @@ ConfirmBox::ConfirmBox(const InformBoxTag &, const QString &text, const QString , _confirmStyle(st::defaultBoxButton) , _informative(true) , _text(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) -, _confirmedCallback(base::lambda_copy(closedCallback)) -, _cancelledCallback(base::lambda_copy(closedCallback)) { +, _confirmedCallback(generateInformCallback(closedCallback)) +, _cancelledCallback(generateInformCallback(closedCallback)) { init(text); } +base::lambda ConfirmBox::generateInformCallback(const base::lambda_copy &closedCallback) { + return base::lambda_guarded(this, [this, closedCallback] { + closeBox(); + if (closedCallback) { + closedCallback(); + } + }); +} + void ConfirmBox::init(const QString &text) { textstyleSet(&st::boxTextStyle); _text.setText(st::boxTextFont, text, _informative ? _confirmBoxTextOptions : _textPlainOptions); @@ -210,6 +219,12 @@ void ConfirmBox::paintEvent(QPaintEvent *e) { textstyleRestore(); } +InformBox::InformBox(QWidget*, const QString &text, base::lambda_copy &&closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std_::move(closedCallback)) { +} + +InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, base::lambda_copy &&closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std_::move(closedCallback)) { +} + MaxInviteBox::MaxInviteBox(QWidget*, const QString &link) : _text(st::boxTextFont, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) , _link(link) { @@ -495,11 +510,11 @@ void ConfirmInviteBox::prepare() { auto newHeight = st::confirmInviteStatusTop + _status->height() + st::boxPadding.bottom(); if (!_participants.isEmpty()) { - int skip = (width() - 4 * st::confirmInviteUserPhotoSize) / 5; + int skip = (st::boxWideWidth - 4 * st::confirmInviteUserPhotoSize) / 5; int padding = skip / 2; _userWidth = (st::confirmInviteUserPhotoSize + 2 * padding); int sumWidth = _participants.size() * _userWidth; - int left = (width() - sumWidth) / 2; + int left = (st::boxWideWidth - sumWidth) / 2; for_const (auto user, _participants) { auto name = new Ui::FlatLabel(this, st::confirmInviteUserName); name->resizeToWidth(st::confirmInviteUserPhotoSize + padding); diff --git a/Telegram/SourceFiles/boxes/confirmbox.h b/Telegram/SourceFiles/boxes/confirmbox.h index 52ed7ee73..f14b1ac80 100644 --- a/Telegram/SourceFiles/boxes/confirmbox.h +++ b/Telegram/SourceFiles/boxes/confirmbox.h @@ -63,6 +63,7 @@ private: struct InformBoxTag { }; ConfirmBox(const InformBoxTag &, const QString &text, const QString &doneText, base::lambda_copy &&closedCallback); + base::lambda generateInformCallback(const base::lambda_copy &closedCallback); friend class InformBox; void confirmed(); @@ -92,10 +93,8 @@ private: class InformBox : public ConfirmBox { public: - InformBox(QWidget*, const QString &text, base::lambda_copy &&closedCallback = base::lambda_copy()) : ConfirmBox(ConfirmBox::InformBoxTag(), text, QString(), std_::move(closedCallback)) { - } - InformBox(QWidget*, const QString &text, const QString &doneText, base::lambda_copy &&closedCallback = base::lambda_copy()) : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std_::move(closedCallback)) { - } + InformBox(QWidget*, const QString &text, base::lambda_copy &&closedCallback = base::lambda_copy()); + InformBox(QWidget*, const QString &text, const QString &doneText, base::lambda_copy &&closedCallback = base::lambda_copy()); }; diff --git a/Telegram/SourceFiles/boxes/confirmphonebox.cpp b/Telegram/SourceFiles/boxes/confirmphonebox.cpp index 16235fd83..7805b0426 100644 --- a/Telegram/SourceFiles/boxes/confirmphonebox.cpp +++ b/Telegram/SourceFiles/boxes/confirmphonebox.cpp @@ -55,7 +55,6 @@ void ConfirmPhoneBox::checkPhoneAndHash() { if (_sendCodeRequestId) { return; } - MTPaccount_SendConfirmPhoneCode::Flags flags = 0; _sendCodeRequestId = MTP::send(MTPaccount_SendConfirmPhoneCode(MTP_flags(flags), MTP_string(_hash), MTPBool()), rpcDone(&ConfirmPhoneBox::sendCodeDone), rpcFail(&ConfirmPhoneBox::sendCodeFail)); } @@ -310,7 +309,7 @@ void ConfirmPhoneBox::resizeEvent(QResizeEvent *e) { } void ConfirmPhoneBox::setInnerFocus() { - _code->setFocus(); + _code->setFocusFast(); } ConfirmPhoneBox::~ConfirmPhoneBox() { diff --git a/Telegram/SourceFiles/boxes/connectionbox.cpp b/Telegram/SourceFiles/boxes/connectionbox.cpp index e325ee9ac..86ad6f0d0 100644 --- a/Telegram/SourceFiles/boxes/connectionbox.cpp +++ b/Telegram/SourceFiles/boxes/connectionbox.cpp @@ -80,8 +80,10 @@ void ConnectionBox::updateControlsVisibility() { } void ConnectionBox::setInnerFocus() { - if (!_hostInput->isHidden()) { - _hostInput->setFocus(); + if (_hostInput->isHidden()) { + setFocus(); + } else { + _hostInput->setFocusFast(); } } @@ -120,9 +122,12 @@ void ConnectionBox::updateControlsPosition() { void ConnectionBox::onChange() { updateControlsVisibility(); if (_httpProxyRadio->checked() || _tcpProxyRadio->checked()) { - _hostInput->setFocus(); + if (!_hostInput->hasFocus() && !_portInput->hasFocus() && !_userInput->hasFocus() && !_passwordInput->hasFocus()) { + _hostInput->setFocusFast(); + } if (_httpProxyRadio->checked() && !_portInput->getLastText().toInt()) { _portInput->setText(qsl("80")); + _portInput->finishAnimations(); } } update(); @@ -217,7 +222,7 @@ void AutoDownloadBox::prepare() { addButton(lang(lng_connection_save), [this] { onSave(); }); addButton(lang(lng_cancel), [this] { closeBox(); }); - setDimensions(st::boxWidth, 3 * _sectionHeight + st::setLittleSkip + _gifPlay->heightNoMargins() + st::setLittleSkip); + setDimensions(st::boxWidth, 3 * _sectionHeight - st::autoDownloadTopDelta + st::setLittleSkip + _gifPlay->heightNoMargins() + st::setLittleSkip); } void AutoDownloadBox::paintEvent(QPaintEvent *e) { @@ -235,13 +240,14 @@ void AutoDownloadBox::paintEvent(QPaintEvent *e) { void AutoDownloadBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); - _photoPrivate->moveToLeft(st::boxTitlePosition.x(), st::boxTitleHeight + st::setLittleSkip); + auto top = st::boxTitleHeight - st::autoDownloadTopDelta; + _photoPrivate->moveToLeft(st::boxTitlePosition.x(), top + st::setLittleSkip); _photoGroups->moveToLeft(st::boxTitlePosition.x(), _photoPrivate->bottomNoMargins() + st::setLittleSkip); - _audioPrivate->moveToLeft(st::boxTitlePosition.x(), _sectionHeight + st::boxTitleHeight + st::setLittleSkip); + _audioPrivate->moveToLeft(st::boxTitlePosition.x(), _sectionHeight + top + st::setLittleSkip); _audioGroups->moveToLeft(st::boxTitlePosition.x(), _audioPrivate->bottomNoMargins() + st::setLittleSkip); - _gifPrivate->moveToLeft(st::boxTitlePosition.x(), 2 * _sectionHeight + st::boxTitleHeight + st::setLittleSkip); + _gifPrivate->moveToLeft(st::boxTitlePosition.x(), 2 * _sectionHeight + top + st::setLittleSkip); _gifGroups->moveToLeft(st::boxTitlePosition.x(), _gifPrivate->bottomNoMargins() + st::setLittleSkip); _gifPlay->moveToLeft(st::boxTitlePosition.x(), _gifGroups->bottomNoMargins() + st::setLittleSkip); } diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 486d731ca..a8f1f3803 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -40,6 +40,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/effects/ripple_animation.h" #include "boxes/photocropbox.h" #include "boxes/confirmbox.h" +#include "window/window_theme.h" #include "observer_peer.h" #include "apiwrap.h" @@ -636,6 +637,32 @@ void ContactsBox::Inner::init() { connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData *))); connect(App::main(), SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&))); connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*))); + + using Update = Window::Theme::BackgroundUpdate; + subscribe(Window::Theme::Background(), [this](const Update &update) { + if (update.type == Update::Type::TestingTheme + || update.type == Update::Type::RevertingTheme) { + invalidateCache(); + } + }); +} + +void ContactsBox::Inner::invalidateCache() { + for_const (auto data, _contactsData) { + if (data->checkbox) { + data->checkbox->invalidateCache(); + } + } + for_const (auto data, _byUsernameDatas) { + if (data->checkbox) { + data->checkbox->invalidateCache(); + } + } + for_const (auto data, d_byUsername) { + if (data->checkbox) { + data->checkbox->invalidateCache(); + } + } } void ContactsBox::Inner::initList() { @@ -894,17 +921,18 @@ ContactsBox::Inner::ContactData *ContactsBox::Inner::contactData(Dialogs::Row *r return data; } +bool ContactsBox::Inner::isRowDisabled(PeerData *peer, ContactData *data) const { + if (_chat && _membersFilter == MembersFilter::Admins) { + return (_saving || _allAdmins->checked() || peer->id == peerFromUser(_chat->creator)); + } + return (data->disabledChecked || selectedCount() >= Global::MegagroupSizeMax()); +} + void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, ContactData *data, bool selected) { auto user = peer->asUser(); - if (_chat && _membersFilter == MembersFilter::Admins) { - if (_allAdmins->checked() || peer->id == peerFromUser(_chat->creator) || _saving) { - selected = false; - } - } else { - if (data->disabledChecked || selectedCount() >= Global::MegagroupSizeMax()) { - selected = false; - } + if (isRowDisabled(peer, data)) { + selected = false; } auto paintDisabledCheck = data->disabledChecked; @@ -1229,15 +1257,15 @@ void ContactsBox::Inner::mousePressEvent(QMouseEvent *e) { setPressed(_selected); setFilteredPressed(_filteredSelected); setSearchedPressed(_searchedSelected); - if (_pressed) { - addRipple(contactData(_selected)); + if (_selected) { + addRipple(_selected->history()->peer, contactData(_selected)); } else if (_filteredSelected >= 0 && _filteredSelected < _filtered.size()) { - addRipple(contactData(_filtered[_filteredSelected])); + addRipple(_filtered[_filteredSelected]->history()->peer, contactData(_filtered[_filteredSelected])); } else if (_searchedSelected >= 0) { if (_filter.isEmpty() && _searchedSelected < d_byUsername.size()) { - addRipple(d_byUsername[_searchedSelected]); + addRipple(_byUsername[_searchedSelected], d_byUsername[_searchedSelected]); } else if (!_filter.isEmpty() && _searchedSelected < d_byUsernameFiltered.size()) { - addRipple(d_byUsernameFiltered[_searchedSelected]); + addRipple(_byUsernameFiltered[_searchedSelected], d_byUsernameFiltered[_searchedSelected]); } } } @@ -1261,7 +1289,9 @@ void ContactsBox::Inner::mouseReleaseEvent(QMouseEvent *e) { } } -void ContactsBox::Inner::addRipple(ContactData *data) { +void ContactsBox::Inner::addRipple(PeerData *peer, ContactData *data) { + if (isRowDisabled(peer, data)) return; + auto rowTop = getSelectedRowTop(); if (!data->ripple) { auto mask = Ui::RippleAnimation::rectMask(QSize(width(), _rowHeight)); @@ -1420,7 +1450,7 @@ void ContactsBox::Inner::changeCheckState(Dialogs::Row *row) { void ContactsBox::Inner::changeCheckState(ContactData *data, PeerData *peer) { t_assert(usingMultiSelect()); - if (_chat && _membersFilter == MembersFilter::Admins && _allAdmins->checked()) { + if (isRowDisabled(peer, data)) { } else if (data->checkbox->checked()) { changePeerCheckState(data, peer, false); } else if (selectedCount() < ((_channel && _channel->isMegagroup()) ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) { diff --git a/Telegram/SourceFiles/boxes/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 88d7df5f1..89bd546c0 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.h +++ b/Telegram/SourceFiles/boxes/contactsbox.h @@ -224,18 +224,20 @@ private: bool statusHasOnlineColor = false; bool disabledChecked = false; }; - void addRipple(ContactData *data); + void addRipple(PeerData *peer, ContactData *data); void stopLastRipple(ContactData *data); void setPressed(Dialogs::Row *pressed); void setFilteredPressed(int pressed); void setSearchedPressed(int pressed); void clearSearchedContactDatas(); + bool isRowDisabled(PeerData *peer, ContactData *data) const; void loadProfilePhotos(); void addBot(); void init(); void initList(); + void invalidateCache(); void updateRowWithTop(int rowTop); int getSelectedRowTop() const; diff --git a/Telegram/SourceFiles/boxes/members_box.cpp b/Telegram/SourceFiles/boxes/members_box.cpp index 570b08735..1911053ee 100644 --- a/Telegram/SourceFiles/boxes/members_box.cpp +++ b/Telegram/SourceFiles/boxes/members_box.cpp @@ -130,20 +130,9 @@ MembersBox::Inner::Inner(QWidget *parent, ChannelData *channel, MembersFilter fi , _channel(channel) , _filter(filter) , _kickText(lang(lng_profile_kick)) -, _time(0) , _kickWidth(st::normalFont->width(_kickText)) -, _sel(-1) -, _kickSel(-1) -, _kickDown(-1) -, _mouseSel(false) -, _kickConfirm(0) -, _kickRequestId(0) -, _kickBox(0) -, _loading(true) -, _loadingRequestId(0) , _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right()) -, _about(_aboutWidth) -, _aboutHeight(0) { +, _about(_aboutWidth) { subscribe(FileDownload::ImageLoaded(), [this] { update(); }); connect(App::main(), SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&))); @@ -167,6 +156,7 @@ void MembersBox::Inner::paintEvent(QPaintEvent *e) { _time = unixtime(); p.fillRect(r, st::contactsBg); + auto ms = getms(); auto yFrom = r.y() - st::membersMarginTop; auto yTo = r.y() + r.height() - st::membersMarginTop; p.translate(0, st::membersMarginTop); @@ -179,10 +169,9 @@ void MembersBox::Inner::paintEvent(QPaintEvent *e) { int32 to = ceilclamp(yTo, _rowHeight, 0, _rows.size()); p.translate(0, from * _rowHeight); for (; from < to; ++from) { - bool sel = (from == _sel); - bool kickSel = (from == _kickSel && (_kickDown < 0 || from == _kickDown)); - bool kickDown = kickSel && (from == _kickDown); - paintDialog(p, _rows[from], data(from), sel, kickSel, kickDown); + auto selected = (_pressed >= 0) ? (from == _pressed) : (from == _selected); + auto kickSelected = (_pressed >= 0) ? (from == _kickPressed && from == _kickSelected) : (from == _kickSelected); + paintDialog(p, ms, _rows[from], data(from), selected, kickSelected); p.translate(0, _rowHeight); } if (to == _rows.size() && _filter == MembersFilter::Recent && (_rows.size() < _channel->membersCount() || _rows.size() >= Global::ChatSizeMax())) { @@ -197,53 +186,91 @@ void MembersBox::Inner::enterEvent(QEvent *e) { } void MembersBox::Inner::leaveEvent(QEvent *e) { - _mouseSel = false; + _mouseSelection = false; setMouseTracking(false); - if (_sel >= 0) { + if (_selected >= 0) { clearSel(); } } void MembersBox::Inner::mouseMoveEvent(QMouseEvent *e) { - _mouseSel = true; + _mouseSelection = true; _lastMousePos = e->globalPos(); - updateSel(); + updateSelection(); } void MembersBox::Inner::mousePressEvent(QMouseEvent *e) { - _mouseSel = true; + _mouseSelection = true; _lastMousePos = e->globalPos(); - updateSel(); - if (e->button() == Qt::LeftButton && _kickSel < 0) { - chooseParticipant(); + updateSelection(); + setPressed(_selected); + _kickPressed = _kickSelected; + if (_selected >= 0 && _selected < _datas.size() && _kickSelected < 0) { + addRipple(_datas[_selected]); } - _kickDown = _kickSel; - update(); } void MembersBox::Inner::mouseReleaseEvent(QMouseEvent *e) { - _mouseSel = true; - _lastMousePos = e->globalPos(); - updateSel(); - if (_kickDown >= 0 && _kickDown == _kickSel && !_kickRequestId) { - _kickConfirm = _rows.at(_kickSel); - if (_kickBox) _kickBox->deleteLater(); - auto text = (_filter == MembersFilter::Recent ? (_channel->isMegagroup() ? lng_profile_sure_kick : lng_profile_sure_kick_channel) : lng_profile_sure_kick_admin)(lt_user, _kickConfirm->firstName); - _kickBox = Ui::show(Box(text, base::lambda_guarded(this, [this] { - if (_filter == MembersFilter::Recent) { - _kickRequestId = MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _kickConfirm->inputUser, MTP_bool(true)), rpcDone(&Inner::kickDone), rpcFail(&Inner::kickFail)); - } else { - _kickRequestId = MTP::send(MTPchannels_EditAdmin(_channel->inputChannel, _kickConfirm->inputUser, MTP_channelRoleEmpty()), rpcDone(&Inner::kickAdminDone), rpcFail(&Inner::kickFail)); + auto pressed = _pressed; + auto kickPressed = _kickPressed; + setPressed(-1); + if (e->button() == Qt::LeftButton) { + if (pressed == _selected && kickPressed == _kickSelected) { + if (kickPressed >= 0) { + if (!_kickRequestId) { + _kickConfirm = _rows.at(_kickSelected); + if (_kickBox) _kickBox->deleteLater(); + auto text = (_filter == MembersFilter::Recent ? (_channel->isMegagroup() ? lng_profile_sure_kick : lng_profile_sure_kick_channel) : lng_profile_sure_kick_admin)(lt_user, _kickConfirm->firstName); + _kickBox = Ui::show(Box(text, base::lambda_guarded(this, [this] { + if (_filter == MembersFilter::Recent) { + _kickRequestId = MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _kickConfirm->inputUser, MTP_bool(true)), rpcDone(&Inner::kickDone), rpcFail(&Inner::kickFail)); + } else { + _kickRequestId = MTP::send(MTPchannels_EditAdmin(_channel->inputChannel, _kickConfirm->inputUser, MTP_channelRoleEmpty()), rpcDone(&Inner::kickAdminDone), rpcFail(&Inner::kickFail)); + } + })), KeepOtherLayers); + } + } else if (pressed >= 0) { + chooseParticipant(); } - })), KeepOtherLayers); + } } - _kickDown = -1; } -void MembersBox::Inner::paintDialog(Painter &p, PeerData *peer, MemberData *data, bool sel, bool kickSel, bool kickDown) { +void MembersBox::Inner::addRipple(MemberData *data) { + auto rowTop = getSelectedRowTop(); + if (!data->ripple) { + auto mask = Ui::RippleAnimation::rectMask(QSize(width(), _rowHeight)); + data->ripple = std_::make_unique(st::contactsRipple, std_::move(mask), [this, data] { + updateRowWithTop(data->rippleRowTop); + }); + } + data->rippleRowTop = rowTop; + data->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(0, rowTop)); +} + +void MembersBox::Inner::stopLastRipple(MemberData *data) { + if (data->ripple) { + data->ripple->lastStop(); + } +} + +void MembersBox::Inner::setPressed(int pressed) { + if (_pressed >= 0 && _pressed < _datas.size()) { + stopLastRipple(_datas[_pressed]); + } + _pressed = pressed; +} + +void MembersBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, MemberData *data, bool selected, bool kickSelected) { UserData *user = peer->asUser(); - p.fillRect(0, 0, width(), _rowHeight, sel ? st::contactsBgOver : st::contactsBg); + p.fillRect(0, 0, width(), _rowHeight, selected ? st::contactsBgOver : st::contactsBg); + if (data->ripple) { + data->ripple->paint(p, 0, 0, width(), ms); + if (data->ripple->empty()) { + data->ripple.reset(); + } + } peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width()); p.setPen(st::contactsNameFg); @@ -258,43 +285,43 @@ void MembersBox::Inner::paintDialog(Painter &p, PeerData *peer, MemberData *data data->name.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsNameTop, namew, width()); if (data->canKick) { - p.setFont((kickSel ? st::linkOverFont : st::linkFont)->f); - p.setPen(kickDown ? st::defaultLinkButton.downColor : st::defaultLinkButton.color); + p.setFont(kickSelected ? st::linkOverFont : st::linkFont); + p.setPen(kickSelected ? st::defaultLinkButton.overColor : st::defaultLinkButton.color); p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), _kickText, _kickWidth); } p.setFont(st::contactsStatusFont->f); - p.setPen(data->onlineColor ? st::contactsStatusFgOnline : (sel ? st::contactsStatusFgOver : st::contactsStatusFg)); + p.setPen(data->onlineColor ? st::contactsStatusFgOnline : (selected ? st::contactsStatusFgOver : st::contactsStatusFg)); p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), data->online); } void MembersBox::Inner::selectSkip(int32 dir) { _time = unixtime(); - _mouseSel = false; + _mouseSelection = false; int cur = -1; - if (_sel >= 0) { - cur = _sel; + if (_selected >= 0) { + cur = _selected; } cur += dir; if (cur <= 0) { - _sel = _rows.isEmpty() ? -1 : 0; + _selected = _rows.isEmpty() ? -1 : 0; } else if (cur >= _rows.size()) { - _sel = -1; + _selected = -1; } else { - _sel = cur; + _selected = cur; } if (dir > 0) { - if (_sel < 0 || _sel >= _rows.size()) { - _sel = -1; + if (_selected < 0 || _selected >= _rows.size()) { + _selected = -1; } } else { if (!_rows.isEmpty()) { - if (_sel < 0) _sel = _rows.size() - 1; + if (_selected < 0) _selected = _rows.size() - 1; } } - if (_sel >= 0) { - emit mustScrollTo(_sel * _rowHeight, (_sel + 1) * _rowHeight); + if (_selected >= 0) { + emit mustScrollTo(st::membersMarginTop + _selected * _rowHeight, st::membersMarginTop + (_selected + 1) * _rowHeight); } update(); @@ -306,6 +333,10 @@ void MembersBox::Inner::selectSkipPage(int32 h, int32 dir) { selectSkip(points * dir); } +MembersBox::Inner::MemberData::MemberData() = default; + +MembersBox::Inner::MemberData::~MemberData() = default; + void MembersBox::Inner::loadProfilePhotos() { if (_visibleTop >= _visibleBottom) return; @@ -331,8 +362,8 @@ void MembersBox::Inner::loadProfilePhotos() { } void MembersBox::Inner::chooseParticipant() { - if (_sel < 0 || _sel >= _rows.size()) return; - if (PeerData *peer = _rows[_sel]) { + if (_selected < 0 || _selected >= _rows.size()) return; + if (auto peer = _rows[_selected]) { Ui::hideLayer(); Ui::showPeerProfile(peer); } @@ -379,9 +410,9 @@ void MembersBox::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) { void MembersBox::Inner::clearSel() { updateSelectedRow(); - _sel = _kickSel = _kickDown = -1; + _selected = _kickSelected = -1; _lastMousePos = QCursor::pos(); - updateSel(); + updateSelection(); } MembersBox::Inner::MemberData *MembersBox::Inner::data(int32 index) { @@ -419,23 +450,23 @@ MembersBox::Inner::~Inner() { clear(); } -void MembersBox::Inner::updateSel() { - if (!_mouseSel) return; +void MembersBox::Inner::updateSelection() { + if (!_mouseSelection) return; QPoint p(mapFromGlobal(_lastMousePos)); p.setY(p.y() - st::membersMarginTop); bool in = parentWidget()->rect().contains(parentWidget()->mapFromGlobal(_lastMousePos)); - int32 newSel = (in && p.y() >= 0 && p.y() < _rows.size() * _rowHeight) ? (p.y() / _rowHeight) : -1; - int32 newKickSel = newSel; - if (newSel >= 0 && (!data(newSel)->canKick || !QRect(width() - _kickWidth - st::contactsPadding.right() - st::contactsCheckPosition.x(), newSel * _rowHeight + st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, _kickWidth, st::normalFont->height).contains(p))) { - newKickSel = -1; + auto selected = (in && p.y() >= 0 && p.y() < _rows.size() * _rowHeight) ? (p.y() / _rowHeight) : -1; + auto kickSelected = selected; + if (selected >= 0 && (!data(selected)->canKick || !QRect(width() - _kickWidth - st::contactsPadding.right() - st::contactsCheckPosition.x(), selected * _rowHeight + st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, _kickWidth, st::normalFont->height).contains(p))) { + kickSelected = -1; } - if (newSel != _sel || newKickSel != _kickSel) { + if (_selected != selected || _kickSelected != kickSelected) { updateSelectedRow(); - _sel = newSel; - _kickSel = newKickSel; + _selected = selected; + _kickSelected = kickSelected; updateSelectedRow(); - setCursor(_kickSel >= 0 ? style::cur_pointer : style::cur_default); + setCursor(_kickSelected >= 0 ? style::cur_pointer : style::cur_default); } } @@ -443,9 +474,21 @@ void MembersBox::Inner::peerUpdated(PeerData *peer) { update(); } +int MembersBox::Inner::getSelectedRowTop() const { + if (_selected >= 0) { + return st::membersMarginTop + _selected * _rowHeight; + } + return -1; +} + +void MembersBox::Inner::updateRowWithTop(int rowTop) { + update(0, rowTop, width(), _rowHeight); +} + void MembersBox::Inner::updateSelectedRow() { - if (_sel >= 0) { - update(0, st::membersMarginTop + _sel * _rowHeight, width(), _rowHeight); + auto rowTop = getSelectedRowTop(); + if (rowTop >= 0) { + updateRowWithTop(rowTop); } } diff --git a/Telegram/SourceFiles/boxes/members_box.h b/Telegram/SourceFiles/boxes/members_box.h index 53cfd0086..e40376259 100644 --- a/Telegram/SourceFiles/boxes/members_box.h +++ b/Telegram/SourceFiles/boxes/members_box.h @@ -113,7 +113,6 @@ signals: public slots: void load(); - void updateSel(); void peerUpdated(PeerData *peer); void onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars); @@ -127,18 +126,29 @@ protected: private: struct MemberData { + MemberData(); + ~MemberData(); + + std_::unique_ptr ripple; + int rippleRowTop = 0; Text name; QString online; bool onlineColor; bool canKick; }; + void addRipple(MemberData *data); + void stopLastRipple(MemberData *data); + void setPressed(int pressed); + void updateSelection(); void loadProfilePhotos(); + void updateRowWithTop(int rowTop); + int getSelectedRowTop() const; void updateSelectedRow(); MemberData *data(int32 index); - void paintDialog(Painter &p, PeerData *peer, MemberData *data, bool sel, bool kickSel, bool kickDown); + void paintDialog(Painter &p, TimeMs ms, PeerData *peer, MemberData *data, bool selected, bool kickSelected); void membersReceived(const MTPchannels_ChannelParticipants &result, mtpRequestId req); bool membersFailed(const RPCError &error, mtpRequestId req); @@ -150,21 +160,25 @@ private: void clear(); - int _rowHeight; + int _rowHeight = 0; int _visibleTop = 0; int _visibleBottom = 0; - ChannelData *_channel; + ChannelData *_channel = nullptr; MembersFilter _filter; QString _kickText; - int32 _time, _kickWidth; + TimeId _time = 0; + int _kickWidth = 0; - int32 _sel, _kickSel, _kickDown; - bool _mouseSel; + int _selected = -1; + int _pressed = -1; + int _kickSelected = -1; + int _kickPressed = -1; + bool _mouseSelection = false; - UserData *_kickConfirm; - mtpRequestId _kickRequestId; + UserData *_kickConfirm = nullptr; + mtpRequestId _kickRequestId = 0; QPointer _kickBox; @@ -177,8 +191,8 @@ private: Kicked }; - bool _loading; - mtpRequestId _loadingRequestId; + bool _loading = true; + mtpRequestId _loadingRequestId = 0; typedef QVector MemberRows; typedef QVector MemberDates; typedef QVector MemberRoles; @@ -188,9 +202,9 @@ private: MemberRoles _roles; MemberDatas _datas; - int32 _aboutWidth; + int _aboutWidth = 0; Text _about; - int32 _aboutHeight; + int _aboutHeight = 0; QPoint _lastMousePos; diff --git a/Telegram/SourceFiles/boxes/passcodebox.cpp b/Telegram/SourceFiles/boxes/passcodebox.cpp index 299287312..123107e22 100644 --- a/Telegram/SourceFiles/boxes/passcodebox.cpp +++ b/Telegram/SourceFiles/boxes/passcodebox.cpp @@ -198,11 +198,11 @@ void PasscodeBox::resizeEvent(QResizeEvent *e) { void PasscodeBox::setInnerFocus() { if (_skipEmailWarning && !_recoverEmail->isHidden()) { - _recoverEmail->setFocus(); + _recoverEmail->setFocusFast(); } else if (_oldPasscode->isHidden()) { - _newPasscode->setFocus(); + _newPasscode->setFocusFast(); } else { - _oldPasscode->setFocus(); + _oldPasscode->setFocusFast(); } } @@ -469,7 +469,7 @@ void RecoverBox::resizeEvent(QResizeEvent *e) { } void RecoverBox::setInnerFocus() { - _recoverCode->setFocus(); + _recoverCode->setFocusFast(); } void RecoverBox::onSubmit() { diff --git a/Telegram/SourceFiles/boxes/report_box.cpp b/Telegram/SourceFiles/boxes/report_box.cpp index 0f78f0f51..09fc3df8c 100644 --- a/Telegram/SourceFiles/boxes/report_box.cpp +++ b/Telegram/SourceFiles/boxes/report_box.cpp @@ -78,7 +78,7 @@ void ReportBox::onChange() { connect(_reasonOtherText, SIGNAL(submitted(bool)), this, SLOT(onReport())); connect(_reasonOtherText, SIGNAL(cancelled()), this, SLOT(onClose())); } - _reasonOtherText->setFocus(); + _reasonOtherText->setFocusFast(); } else if (_reasonOtherText) { _reasonOtherText.destroy(); updateMaxHeight(); @@ -87,7 +87,7 @@ void ReportBox::onChange() { void ReportBox::setInnerFocus() { if (_reasonOtherText) { - _reasonOtherText->setFocus(); + _reasonOtherText->setFocusFast(); } else { setFocus(); } diff --git a/Telegram/SourceFiles/boxes/report_box.h b/Telegram/SourceFiles/boxes/report_box.h index 89b8ebc2b..b64e8b6ea 100644 --- a/Telegram/SourceFiles/boxes/report_box.h +++ b/Telegram/SourceFiles/boxes/report_box.h @@ -37,6 +37,9 @@ private slots: void onReport(); void onChange(); void onDescriptionResized(); + void onClose() { + closeBox(); + } protected: void prepare() override; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index f6dc7537a..81753b930 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -181,12 +181,12 @@ void SendFilesBox::onCaptionResized() { } void SendFilesBox::updateTitleText() { - setTitle((_compressConfirm == CompressConfirm::None) ? lng_send_files_selected(lt_count, _files.size()) : lng_send_images_selected(lt_count, _files.size())); + _titleText = (_compressConfirm == CompressConfirm::None) ? lng_send_files_selected(lt_count, _files.size()) : lng_send_images_selected(lt_count, _files.size()); update(); } void SendFilesBox::updateBoxSize() { - auto newHeight = 0; + auto newHeight = _titleText.isEmpty() ? 0 : st::boxTitleHeight; if (!_preview.isNull()) { newHeight += st::boxPhotoPadding.top() + _previewHeight; } else if (!_fileThumb.isNull()) { @@ -319,7 +319,7 @@ void SendFilesBox::setInnerFocus() { if (!_caption || _caption->isHidden()) { setFocus(); } else { - _caption->setFocus(); + _caption->setFocusFast(); } } @@ -609,7 +609,7 @@ void EditCaptionBox::resizeEvent(QResizeEvent *e) { } void EditCaptionBox::setInnerFocus() { - _field->setFocus(); + _field->setFocusFast(); } void EditCaptionBox::onSave(bool ctrlShiftEnter) { diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index fd0a17322..cca2759f3 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -58,6 +58,9 @@ private slots: void onCompressedChange(); void onSend(bool ctrlShiftEnter = false); void onCaptionResized(); + void onClose() { + closeBox(); + } private: void updateTitleText(); @@ -108,6 +111,9 @@ public: public slots: void onCaptionResized(); void onSave(bool ctrlShiftEnter = false); + void onClose() { + closeBox(); + } protected: void prepare() override; diff --git a/Telegram/SourceFiles/boxes/sessionsbox.cpp b/Telegram/SourceFiles/boxes/sessionsbox.cpp index db94e3006..b26fbbb06 100644 --- a/Telegram/SourceFiles/boxes/sessionsbox.cpp +++ b/Telegram/SourceFiles/boxes/sessionsbox.cpp @@ -304,7 +304,7 @@ void SessionsBox::Inner::paintEvent(QPaintEvent *e) { } void SessionsBox::Inner::onTerminate() { - for (TerminateButtons::iterator i = _terminateButtons.begin(), e = _terminateButtons.end(); i != e; ++i) { + for (auto i = _terminateButtons.begin(), e = _terminateButtons.end(); i != e; ++i) { if (i.value()->isOver()) { if (_terminateBox) _terminateBox->deleteLater(); _terminateBox = Ui::show(Box(lang(lng_settings_reset_one_sure), lang(lng_settings_reset_button), st::attentionBoxButton, base::lambda_guarded(this, [this, terminating = i.key()] { @@ -313,7 +313,7 @@ void SessionsBox::Inner::onTerminate() { _terminateBox = nullptr; } MTP::send(MTPaccount_ResetAuthorization(MTP_long(terminating)), rpcDone(&Inner::terminateDone, terminating), rpcFail(&Inner::terminateFail, terminating)); - TerminateButtons::iterator i = _terminateButtons.find(terminating); + auto i = _terminateButtons.find(terminating); if (i != _terminateButtons.cend()) { i.value()->clearState(); i.value()->hide(); @@ -330,7 +330,7 @@ void SessionsBox::Inner::onTerminateAll() { _terminateBox->closeBox(); _terminateBox = nullptr; } - MTP::send(MTPauth_ResetAuthorizations(), rpcDone(&Inner::terminateAllDone), rpcFail(&Inner::terminateAllFail)); +// MTP::send(MTPauth_ResetAuthorizations(), rpcDone(&Inner::terminateAllDone), rpcFail(&Inner::terminateAllFail)); emit terminateAll(); })), KeepOtherLayers); } diff --git a/Telegram/SourceFiles/boxes/sharebox.cpp b/Telegram/SourceFiles/boxes/sharebox.cpp index 4110a3e18..4a7f9514a 100644 --- a/Telegram/SourceFiles/boxes/sharebox.cpp +++ b/Telegram/SourceFiles/boxes/sharebox.cpp @@ -37,6 +37,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "history/history_media_types.h" #include "ui/widgets/buttons.h" #include "ui/widgets/scroll_area.h" +#include "window/window_theme.h" #include "boxes/contactsbox.h" ShareBox::ShareBox(QWidget*, CopyCallback &©Callback, SubmitCallback &&submitCallback, FilterCallback &&filterCallback) @@ -294,6 +295,20 @@ ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallbac notifyPeerUpdated(update); })); subscribe(FileDownload::ImageLoaded(), [this] { update(); }); + + using Update = Window::Theme::BackgroundUpdate; + subscribe(Window::Theme::Background(), [this](const Update &update) { + if (update.type == Update::Type::TestingTheme + || update.type == Update::Type::RevertingTheme) { + invalidateCache(); + } + }); +} + +void ShareBox::Inner::invalidateCache() { + for_const (auto data, _dataMap) { + data->checkbox.invalidateCache(); + } } void ShareBox::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) { diff --git a/Telegram/SourceFiles/boxes/sharebox.h b/Telegram/SourceFiles/boxes/sharebox.h index e29566009..60549c90a 100644 --- a/Telegram/SourceFiles/boxes/sharebox.h +++ b/Telegram/SourceFiles/boxes/sharebox.h @@ -149,6 +149,7 @@ protected: private: // Observed notifications. void notifyPeerUpdated(const Notify::PeerUpdate &update); + void invalidateCache(); int displayedChatsCount() const; diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index b62ea5a31..ac5ffaf9d 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -412,6 +412,8 @@ void StickersBox::switchTab() { auto slideLeft = wasIndex > nowIndex; _slideAnimation->start(slideLeft, [this] { update(); }, st::slideDuration); setInnerVisible(false); + + setFocus(); update(); } } diff --git a/Telegram/SourceFiles/boxes/usernamebox.cpp b/Telegram/SourceFiles/boxes/usernamebox.cpp index fec57634b..b91250367 100644 --- a/Telegram/SourceFiles/boxes/usernamebox.cpp +++ b/Telegram/SourceFiles/boxes/usernamebox.cpp @@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mainwindow.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" +#include "ui/toast/toast.h" #include "styles/style_boxes.h" UsernameBox::UsernameBox(QWidget*) @@ -60,7 +61,7 @@ void UsernameBox::prepare() { } void UsernameBox::setInnerFocus() { - _username->setFocus(); + _username->setFocusFast(); } void UsernameBox::paintEvent(QPaintEvent *e) { @@ -69,10 +70,7 @@ void UsernameBox::paintEvent(QPaintEvent *e) { Painter p(this); p.setFont(st::boxTextFont); - if (!_copiedTextLink.isEmpty()) { - p.setPen(st::usernameDefaultFg); - p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _copiedTextLink); - } else if (!_errorText.isEmpty()) { + if (!_errorText.isEmpty()) { p.setPen(st::boxTextFgError); p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _errorText); } else if (!_goodText.isEmpty()) { @@ -134,7 +132,7 @@ void UsernameBox::onChanged() { QString name = getName(); if (name.isEmpty()) { if (!_errorText.isEmpty() || !_goodText.isEmpty()) { - _copiedTextLink = _errorText = _goodText = QString(); + _errorText = _goodText = QString(); update(); } _checkTimer->stop(); @@ -143,8 +141,7 @@ void UsernameBox::onChanged() { for (int32 i = 0; i < len; ++i) { QChar ch = name.at(i); if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_' && (ch != '@' || i > 0)) { - if (_errorText != lang(lng_username_bad_symbols) || !_copiedTextLink.isEmpty()) { - _copiedTextLink = QString(); + if (_errorText != lang(lng_username_bad_symbols)) { _errorText = lang(lng_username_bad_symbols); update(); } @@ -153,15 +150,14 @@ void UsernameBox::onChanged() { } } if (name.size() < MinUsernameLength) { - if (_errorText != lang(lng_username_too_short) || !_copiedTextLink.isEmpty()) { - _copiedTextLink = QString(); + if (_errorText != lang(lng_username_too_short)) { _errorText = lang(lng_username_too_short); update(); } _checkTimer->stop(); } else { - if (!_errorText.isEmpty() || !_goodText.isEmpty() || !_copiedTextLink.isEmpty()) { - _copiedTextLink = _errorText = _goodText = QString(); + if (!_errorText.isEmpty() || !_goodText.isEmpty()) { + _errorText = _goodText = QString(); update(); } _checkTimer->start(UsernameCheckTimeout); @@ -171,8 +167,10 @@ void UsernameBox::onChanged() { void UsernameBox::onLinkClick() { Application::clipboard()->setText(qsl("https://telegram.me/") + getName()); - _copiedTextLink = lang(lng_username_copied); - update(); + + Ui::Toast::Config toast; + toast.text = lang(lng_username_copied); + Ui::Toast::Show(App::wnd(), toast); } void UsernameBox::onUpdateDone(const MTPUser &user) { @@ -192,14 +190,12 @@ bool UsernameBox::onUpdateFail(const RPCError &error) { } else if (err == qstr("USERNAME_INVALID")) { _username->setFocus(); _username->showError(); - _copiedTextLink = QString(); _errorText = lang(lng_username_invalid); update(); return true; } else if (err == qstr("USERNAME_OCCUPIED") || err == qstr("USERNAMES_UNAVAILABLE")) { _username->setFocus(); _username->showError(); - _copiedTextLink = QString(); _errorText = lang(lng_username_occupied); update(); return true; @@ -212,10 +208,9 @@ void UsernameBox::onCheckDone(const MTPBool &result) { _checkRequestId = 0; QString newError = (mtpIsTrue(result) || _checkUsername == App::self()->username) ? QString() : lang(lng_username_occupied); QString newGood = newError.isEmpty() ? lang(lng_username_available) : QString(); - if (_errorText != newError || _goodText != newGood || !_copiedTextLink.isEmpty()) { + if (_errorText != newError || _goodText != newGood) { _errorText = newError; _goodText = newGood; - _copiedTextLink = QString(); update(); } } @@ -235,7 +230,6 @@ bool UsernameBox::onCheckFail(const RPCError &error) { return true; } _goodText = QString(); - _copiedTextLink = QString(); _username->setFocus(); return true; } diff --git a/Telegram/SourceFiles/boxes/usernamebox.h b/Telegram/SourceFiles/boxes/usernamebox.h index 52b09ecd4..7feb989a9 100644 --- a/Telegram/SourceFiles/boxes/usernamebox.h +++ b/Telegram/SourceFiles/boxes/usernamebox.h @@ -63,7 +63,7 @@ private: mtpRequestId _saveRequestId = 0; mtpRequestId _checkRequestId = 0; - QString _sentUsername, _checkUsername, _errorText, _goodText, _copiedTextLink; + QString _sentUsername, _checkUsername, _errorText, _goodText; Text _about; object_ptr _checkTimer; diff --git a/Telegram/SourceFiles/codegen/style/generator.cpp b/Telegram/SourceFiles/codegen/style/generator.cpp index 63bab44d4..4568f6f70 100644 --- a/Telegram/SourceFiles/codegen/style/generator.cpp +++ b/Telegram/SourceFiles/codegen/style/generator.cpp @@ -442,6 +442,10 @@ public:\n\ bool load(const QByteArray &cache);\n\ bool setColor(QLatin1String name, uchar r, uchar g, uchar b, uchar a);\n\ bool setColor(QLatin1String name, QLatin1String from);\n\ + void reset() {\n\ + clear();\n\ + finalize();\n\ + }\n\ \n\ // Created not inited, should be finalized before usage.\n\ void finalize();\n\ @@ -486,18 +490,24 @@ public:\n\ static int32 Checksum();\n\ \n\ ~palette() {\n\ + clear();\n\ + }\n\ +\n\ +private:\n\ + void clear() {\n\ for (int i = 0; i != " << count << "; ++i) {\n\ if (_status[i] != Status::Initial) {\n\ data(i)->~ColorData();\n\ + _status[i] = Status::Initial;\n\ + _ready = false;\n\ }\n\ }\n\ }\n\ \n\ -private:\n\ struct TempColorData { uchar r, g, b, a; };\n\ void compute(int index, int fallbackIndex, TempColorData value) {\n\ if (_status[index] == Status::Initial) {\n\ - if (fallbackIndex >= 0 && _status[fallbackIndex] != Status::Initial) {\n\ + if (fallbackIndex >= 0 && _status[fallbackIndex] == Status::Loaded) {\n\ _status[index] = Status::Loaded;\n\ new (data(index)) internal::ColorData(*data(fallbackIndex));\n\ } else {\n\ @@ -550,6 +560,7 @@ bool load(const QByteArray &cache);\n\ bool setColor(QLatin1String name, uchar r, uchar g, uchar b, uchar a);\n\ bool setColor(QLatin1String name, QLatin1String from);\n\ void apply(const palette &other);\n\ +void reset();\n\ \n\ } // namespace main_palette\n"; @@ -872,6 +883,11 @@ void apply(const palette &other) {\n\ style::internal::resetIcons();\n\ }\n\ \n\ +void reset() {\n\ + _palette.reset();\n\ + style::internal::resetIcons();\n\ +}\n\ +\n\ } // namespace main_palette\n\ \n"; diff --git a/Telegram/SourceFiles/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp index 18ff045ce..ae9c83922 100644 --- a/Telegram/SourceFiles/core/click_handler_types.cpp +++ b/Telegram/SourceFiles/core/click_handler_types.cpp @@ -40,7 +40,11 @@ QString tryConvertUrlToLocal(QString url) { using namespace qthelp; auto matchOptions = RegExOption::CaseInsensitive; - if (auto telegramMeMatch = regex_match(qsl("https?://(www\\.)?telegram\\.me/(.+)$"), url, matchOptions)) { + auto telegramMeMatch = regex_match(qsl("https?://(www\\.)?telegram\\.me/(.+)$"), url, matchOptions); + if (!telegramMeMatch) { + telegramMeMatch = regex_match(qsl("https?://(www\\.)?t\\.me/(.+)$"), url, matchOptions); + } + if (telegramMeMatch) { auto query = telegramMeMatch->capturedRef(2); if (auto joinChatMatch = regex_match(qsl("^joinchat/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) { return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(1)); @@ -103,13 +107,15 @@ TextWithEntities UrlClickHandler::getExpandedLinkTextWithEntities(ExpandLinksMod return result; } -void HiddenUrlClickHandler::onClick(Qt::MouseButton button) const { - auto urlText = tryConvertUrlToLocal(url()); +void HiddenUrlClickHandler::doOpen(QString url) { + auto urlText = tryConvertUrlToLocal(url); if (urlText.startsWith(qstr("tg://"))) { App::openLocalUrl(urlText); } else { - Ui::show(Box(lang(lng_open_this_link) + qsl("\n\n") + urlText, lang(lng_open_link), [urlText] { + auto parsedUrl = QUrl::fromUserInput(urlText); + auto displayUrl = parsedUrl.isValid() ? parsedUrl.toDisplayString() : urlText; + Ui::show(Box(lang(lng_open_this_link) + qsl("\n\n") + displayUrl, lang(lng_open_link), [urlText] { Ui::hideLayer(); UrlClickHandler::doOpen(urlText); })); diff --git a/Telegram/SourceFiles/core/click_handler_types.h b/Telegram/SourceFiles/core/click_handler_types.h index d8231da31..f68de6bff 100644 --- a/Telegram/SourceFiles/core/click_handler_types.h +++ b/Telegram/SourceFiles/core/click_handler_types.h @@ -115,7 +115,13 @@ class HiddenUrlClickHandler : public UrlClickHandler { public: HiddenUrlClickHandler(QString url) : UrlClickHandler(url, false) { } - void onClick(Qt::MouseButton button) const override; + + static void doOpen(QString url); + void onClick(Qt::MouseButton button) const override { + if (button == Qt::LeftButton || button == Qt::MiddleButton) { + doOpen(url()); + } + } QString getExpandedLinkText(ExpandLinksMode mode, const QStringRef &textPart) const override; TextWithEntities getExpandedLinkTextWithEntities(ExpandLinksMode mode, int entityOffset, const QStringRef &textPart) const override; diff --git a/Telegram/SourceFiles/core/qthelp_regex.h b/Telegram/SourceFiles/core/qthelp_regex.h index 899e88b17..a70d197e9 100644 --- a/Telegram/SourceFiles/core/qthelp_regex.h +++ b/Telegram/SourceFiles/core/qthelp_regex.h @@ -28,6 +28,14 @@ public: } RegularExpressionMatch(RegularExpressionMatch &&other) : data_(std_::move(other.data_)) { } + RegularExpressionMatch &operator=(QRegularExpressionMatch &&match) { + data_ = std_::move(match); + return *this; + } + RegularExpressionMatch &operator=(RegularExpressionMatch &&other) { + data_ = std_::move(other.data_); + return *this; + } QRegularExpressionMatch *operator->() { return &data_; } diff --git a/Telegram/SourceFiles/core/qthelp_url.cpp b/Telegram/SourceFiles/core/qthelp_url.cpp index 8acd3791d..3beb98b2b 100644 --- a/Telegram/SourceFiles/core/qthelp_url.cpp +++ b/Telegram/SourceFiles/core/qthelp_url.cpp @@ -43,7 +43,10 @@ QMap url_parse_params(const QString ¶ms, UrlParamNameTrans paramName = param.mid(0, separatorPosition); paramValue = url_decode(param.mid(separatorPosition + 1)); } - result.insert(transformParamName(paramName), paramValue); + paramName = transformParamName(paramName); + if (!result.contains(paramName)) { + result.insert(paramName, paramValue); + } } } return result; diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 623b143df..414a4859c 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/utils.h" -#define BETA_VERSION_MACRO (10020001ULL) +#define BETA_VERSION_MACRO (10020002ULL) constexpr int AppVersion = 10020; constexpr str_const AppVersionStr = "0.10.20"; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index b3d9d3fde..e224fec04 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -859,7 +859,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { _menu = new Ui::PopupMenu(); App::main()->fillPeerMenu(_menuPeer, [this](const QString &text, base::lambda &&callback) { return _menu->addAction(text, std_::move(callback)); - }); + }, true); connect(_menu, SIGNAL(destroyed(QObject*)), this, SLOT(onMenuDestroyed(QObject*))); _menu->popup(e->globalPos()); e->accept(); diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 2c045de17..217c4ca5c 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -94,7 +94,17 @@ void activateBotCommand(const HistoryItem *msg, int row, int col) { case ButtonType::Url: { auto url = QString::fromUtf8(button->data); - HiddenUrlClickHandler(url).onClick(Qt::LeftButton); + auto skipConfirmation = false; + if (auto bot = msg->getMessageBot()) { + if (bot->isVerified()) { + skipConfirmation = true; + } + } + if (skipConfirmation) { + UrlClickHandler::doOpen(url); + } else { + HiddenUrlClickHandler::doOpen(url); + } } break; case ButtonType::RequestLocation: { @@ -539,9 +549,13 @@ void start() { } } +bool started() { + return (SandboxData != nullptr); +} + void finish() { delete SandboxData; - SandboxData = 0; + SandboxData = nullptr; } uint64 UserTag() { diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 785dc94b7..2b6e44ba6 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -226,6 +226,7 @@ bool CheckBetaVersionDir(); void WorkingDirReady(); void start(); +bool started(); void finish(); uint64 UserTag(); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index e2033aa7f..de9b4ac77 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -4217,6 +4217,9 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re destroyUnreadBar(); destroyPinnedBar(); _history = _migrated = nullptr; + _peer = nullptr; + _channel = NoChannel; + _canSendMessages = false; updateBotKeyboard(); } @@ -4239,10 +4242,11 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re _showAtMsgId = showAtMsgId; _histInited = false; - _peer = peerId ? App::peer(peerId) : nullptr; - _channel = _peer ? peerToChannel(_peer->id) : NoChannel; - _canSendMessages = canSendMessages(_peer); - + if (peerId) { + _peer = App::peer(peerId); + _channel = peerToChannel(_peer->id); + _canSendMessages = canSendMessages(_peer); + } updateTopBarSelection(); if (_peer && _peer->isChannel()) { diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index 6fe750c47..7ff203715 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -414,7 +414,10 @@ void LayerStackWidget::setCacheImages() { } void LayerStackWidget::onLayerClosed(LayerWidget *layer) { - layer->closing(); + if (!layer->setClosing()) { + // This layer is already closing. + return; + } layer->deleteLater(); if (layer == _specialLayer) { hideAll(); @@ -523,7 +526,7 @@ void LayerStackWidget::showBox(object_ptr box) { auto removingLayer = _layers.front(); _layers.pop_front(); - removingLayer->closing(); + removingLayer->setClosing(); removingLayer->hide(); removingLayer->deleteLater(); } @@ -615,7 +618,7 @@ LayerWidget *LayerStackWidget::pushBox(object_ptr box) { if (oldLayer) { oldLayer->hide(); } - auto layer = object_ptr(std_::move(box)); + auto layer = object_ptr(this, std_::move(box)); _layers.push_back(layer); initChildLayer(layer); @@ -637,7 +640,7 @@ void LayerStackWidget::prependBox(object_ptr box) { if (_layers.empty()) { return showBox(std_::move(box)); } - auto layer = object_ptr(std_::move(box)); + auto layer = object_ptr(this, std_::move(box)); layer->hide(); _layers.push_front(layer); initChildLayer(layer); @@ -645,7 +648,7 @@ void LayerStackWidget::prependBox(object_ptr box) { void LayerStackWidget::clearLayers() { for (auto layer : base::take(_layers)) { - layer->closing(); + layer->setClosing(); layer->hide(); layer->deleteLater(); } @@ -653,7 +656,7 @@ void LayerStackWidget::clearLayers() { void LayerStackWidget::clearSpecialLayer() { if (_specialLayer) { - _specialLayer->closing(); + _specialLayer->setClosing(); _specialLayer.destroyDelayed(); } } diff --git a/Telegram/SourceFiles/layerwidget.h b/Telegram/SourceFiles/layerwidget.h index 1067c46d4..03794f4ce 100644 --- a/Telegram/SourceFiles/layerwidget.h +++ b/Telegram/SourceFiles/layerwidget.h @@ -34,11 +34,13 @@ public: virtual void showFinished() { } void setInnerFocus(); - void closing() { + bool setClosing() { if (!_closing) { _closing = true; closeHook(); + return true; } + return false; } bool overlaps(const QRect &globalRect); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index d75fbc348..be4196344 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -3725,6 +3725,14 @@ bool readThemeUsingKey(FileKey key) { } void writeTheme(const QString &pathRelative, const QString &pathAbsolute, const QByteArray &content, const Window::Theme::Cached &cache) { + if (content.isEmpty()) { + if (_themeKey) { + clearKey(_themeKey); + _themeKey = 0; + writeSettings(); + } + return; + } if (!_themeKey) { _themeKey = genKey(); writeSettings(); @@ -3743,14 +3751,20 @@ void writeTheme(const QString &pathRelative, const QString &pathAbsolute, const file.writeEncrypted(data, _settingsKey); } +void clearTheme() { + writeTheme(QString(), QString(), QByteArray(), Window::Theme::Cached()); +} + void readTheme() { if (_themeKey && !readThemeUsingKey(_themeKey)) { - clearKey(_themeKey); - _themeKey = 0; - writeSettings(); + clearTheme(); } } +bool hasTheme() { + return (_themeKey != 0); +} + uint32 _peerSize(PeerData *peer) { uint32 result = sizeof(quint64) + sizeof(quint64) + Serialize::storageImageLocationSize(); if (peer->isUser()) { diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index 6cadf5a41..71bcf5b05 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -151,6 +151,8 @@ void writeBackground(int32 id, const QImage &img); bool readBackground(); void writeTheme(const QString &pathRelative, const QString &pathAbsolute, const QByteArray &content, const Window::Theme::Cached &cache); +void clearTheme(); +bool hasTheme(); void writeRecentHashtagsAndBots(); void readRecentHashtagsAndBots(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index ca6048190..eb844def3 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1975,33 +1975,34 @@ void MainWidget::scheduleViewIncrement(HistoryItem *item) { j.value().insert(item->id, true); } -void MainWidget::fillPeerMenu(PeerData *peer, base::lambda &&handler)> &&callback) { - auto isPinned = false; - if (auto history = App::historyLoaded(peer)) { - isPinned = history->isPinnedDialog(); - } - auto pinSubscription = MakeShared(); - auto pinAction = callback(lang(isPinned ? lng_context_unpin_from_top : lng_context_pin_to_top), [peer, pinSubscription] { - auto history = App::history(peer); - auto isPinned = !history->isPinnedDialog(); - history->setPinnedDialog(isPinned); - auto flags = MTPmessages_ToggleDialogPin::Flags(0); - if (isPinned) { - flags |= MTPmessages_ToggleDialogPin::Flag::f_pinned; +void MainWidget::fillPeerMenu(PeerData *peer, base::lambda &&handler)> &&callback, bool pinToggle) { + if (pinToggle) { + auto isPinned = false; + if (auto history = App::historyLoaded(peer)) { + isPinned = history->isPinnedDialog(); } - MTP::send(MTPmessages_ToggleDialogPin(MTP_flags(flags), peer->input)); - if (isPinned) { - if (auto main = App::main()) { - main->dialogsToUp(); + auto pinSubscription = MakeShared(); + auto pinAction = callback(lang(isPinned ? lng_context_unpin_from_top : lng_context_pin_to_top), [peer, pinSubscription] { + auto history = App::history(peer); + auto isPinned = !history->isPinnedDialog(); + history->setPinnedDialog(isPinned); + auto flags = MTPmessages_ToggleDialogPin::Flags(0); + if (isPinned) { + flags |= MTPmessages_ToggleDialogPin::Flag::f_pinned; } - } - }); - auto pinChangedHandler = Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::PinnedChanged, [pinAction, peer](const Notify::PeerUpdate &update) { - if (update.peer != peer) return; - pinAction->setText(lang(App::history(peer)->isPinnedDialog() ? lng_context_unpin_from_top : lng_context_pin_to_top)); - }); - *pinSubscription = Notify::PeerUpdated().add_subscription(std_::move(pinChangedHandler)); - + MTP::send(MTPmessages_ToggleDialogPin(MTP_flags(flags), peer->input)); + if (isPinned) { + if (auto main = App::main()) { + main->dialogsToUp(); + } + } + }); + auto pinChangedHandler = Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::PinnedChanged, [pinAction, peer](const Notify::PeerUpdate &update) { + if (update.peer != peer) return; + pinAction->setText(lang(App::history(peer)->isPinnedDialog() ? lng_context_unpin_from_top : lng_context_pin_to_top)); + }); + *pinSubscription = Notify::PeerUpdated().add_subscription(std_::move(pinChangedHandler)); + } callback(lang((peer->isChat() || peer->isMegagroup()) ? lng_context_view_group : (peer->isUser() ? lng_context_view_profile : lng_context_view_channel)), [peer] { Ui::showPeerProfile(peer); }); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index cdd10c2e1..ab12d5423 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -360,7 +360,7 @@ public: void scheduleViewIncrement(HistoryItem *item); - void fillPeerMenu(PeerData *peer, base::lambda &&handler)> &&callback); + void fillPeerMenu(PeerData *peer, base::lambda &&handler)> &&callback, bool pinToggle); void gotRangeDifference(ChannelData *channel, const MTPupdates_ChannelDifference &diff); void onSelfParticipantUpdated(ChannelData *channel); diff --git a/Telegram/SourceFiles/media/view/mediaview.style b/Telegram/SourceFiles/media/view/mediaview.style index e790c1551..e26a2e2a0 100644 --- a/Telegram/SourceFiles/media/view/mediaview.style +++ b/Telegram/SourceFiles/media/view/mediaview.style @@ -115,7 +115,6 @@ mediaviewFileIconSize: 80px; mediaviewFileLink: LinkButton(defaultLinkButton) { color: #4595d3; overColor: #4595d3; - downColor: #4595d3; } mediaviewTransparentBg: #ffffff; diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index 8ab17cc5f..824cce92e 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -149,6 +149,10 @@ public: void setActive(bool active); void setPressed(bool pressed); + void invalidateCache() { + _check.invalidateCache(); + } + private: void startAnimation(); @@ -283,6 +287,12 @@ void Photo::clickHandlerPressedChanged(const ClickHandlerPtr &action, bool press } } +void Photo::invalidateCache() { + if (_check) { + _check->invalidateCache(); + } +} + Video::Video(DocumentData *video, HistoryItem *parent) : RadialProgressItem(parent) , _data(video) , _duration(formatDurationText(_data->duration())) @@ -431,6 +441,12 @@ void Video::clickHandlerPressedChanged(const ClickHandlerPtr &action, bool press } } +void Video::invalidateCache() { + if (_check) { + _check->invalidateCache(); + } +} + void Video::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const { bool loaded = _data->loaded(); diff --git a/Telegram/SourceFiles/overview/overview_layout.h b/Telegram/SourceFiles/overview/overview_layout.h index 30437a712..50a31fccf 100644 --- a/Telegram/SourceFiles/overview/overview_layout.h +++ b/Telegram/SourceFiles/overview/overview_layout.h @@ -59,6 +59,9 @@ public: return item ? item->id : 0; } + virtual void invalidateCache() { + } + }; class ItemBase : public AbstractItem { @@ -186,6 +189,8 @@ public: void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override; + void invalidateCache() override; + private: void ensureCheckboxCreated(); @@ -211,6 +216,8 @@ public: void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override; + void invalidateCache() override; + protected: float64 dataProgress() const override { return _data->progress(); diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 5f56f6aee..c5c5a86ff 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -85,6 +85,14 @@ OverviewInner::OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, P _searchTimer.setSingleShot(true); connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages())); + using Update = Window::Theme::BackgroundUpdate; + subscribe(Window::Theme::Background(), [this](const Update &update) { + if (update.type == Update::Type::TestingTheme + || update.type == Update::Type::RevertingTheme) { + invalidateCache(); + } + }); + if (_type == OverviewLinks || _type == OverviewFiles) { _search->show(); } else { @@ -92,6 +100,15 @@ OverviewInner::OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, P } } +void OverviewInner::invalidateCache() { + for_const (auto item, _layoutItems) { + item->invalidateCache(); + } + for_const (auto item, _layoutDates) { + item->invalidateCache(); + } +} + bool OverviewInner::event(QEvent *e) { if (e->type() == QEvent::TouchBegin || e->type() == QEvent::TouchUpdate || e->type() == QEvent::TouchEnd || e->type() == QEvent::TouchCancel) { QTouchEvent *ev = static_cast(e); diff --git a/Telegram/SourceFiles/overviewwidget.h b/Telegram/SourceFiles/overviewwidget.h index d3e30ef1e..91ad75a65 100644 --- a/Telegram/SourceFiles/overviewwidget.h +++ b/Telegram/SourceFiles/overviewwidget.h @@ -128,6 +128,7 @@ public slots: private: void saveDocumentToFile(DocumentData *document); + void invalidateCache(); void itemRemoved(HistoryItem *item); MsgId complexMsgId(const HistoryItem *item) const; diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp index 8158d56b6..a40a89d17 100644 --- a/Telegram/SourceFiles/pspecific_linux.cpp +++ b/Telegram/SourceFiles/pspecific_linux.cpp @@ -482,11 +482,17 @@ void psRegisterCustomScheme() { QFile f(file); if (f.open(QIODevice::WriteOnly)) { QString icon = icons + qsl("telegram.png"); - if (!QFile(icon).exists()) { + auto iconExists = QFile(icon).exists(); + if (Local::oldSettingsVersion() < 10021 && iconExists) { + // Icon was changed. + if (QFile(icon).remove()) { + iconExists = false; + } + } + if (!iconExists) { if (QFile(qsl(":/gui/art/icon256.png")).copy(icon)) { DEBUG_LOG(("App Info: Icon copied to 'tdata'")); } - } QTextStream s(&f); diff --git a/Telegram/SourceFiles/settings/settings_background_widget.cpp b/Telegram/SourceFiles/settings/settings_background_widget.cpp index 699e553cf..689f07ae7 100644 --- a/Telegram/SourceFiles/settings/settings_background_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_background_widget.cpp @@ -42,6 +42,26 @@ BackgroundRow::BackgroundRow(QWidget *parent) : TWidget(parent) connect(_chooseFromGallery, SIGNAL(clicked()), this, SIGNAL(chooseFromGallery())); connect(_chooseFromFile, SIGNAL(clicked()), this, SIGNAL(chooseFromFile())); + checkNonDefaultTheme(); + subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { + if (update.type == Window::Theme::BackgroundUpdate::Type::ApplyingTheme) { + checkNonDefaultTheme(); + } + }); +} + +void BackgroundRow::checkNonDefaultTheme() { + if (Local::hasTheme()) { + if (!_useDefault) { + _useDefault.create(this, lang(lng_settings_bg_use_default), st::boxLinkButton); + _useDefault->show(); + connect(_useDefault, SIGNAL(clicked()), this, SIGNAL(useDefault())); + resizeToWidth(width()); + } + } else if (_useDefault) { + _useDefault.destroy(); + resizeToWidth(width()); + } } void BackgroundRow::paintEvent(QPaintEvent *e) { @@ -83,13 +103,19 @@ void BackgroundRow::paintEvent(QPaintEvent *e) { } int BackgroundRow::resizeGetHeight(int newWidth) { - int linkLeft = st::settingsBackgroundSize + st::settingsSmallSkip; - int linkWidth = newWidth - linkLeft; + 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())); - - _chooseFromGallery->moveToLeft(linkLeft, 0, newWidth); - _chooseFromFile->moveToLeft(linkLeft, _chooseFromGallery->height() + st::settingsSmallSkip, newWidth); + if (_useDefault) { + _useDefault->resizeToWidth(qMin(linkWidth, _useDefault->naturalWidth())); + _useDefault->moveToLeft(linkLeft, linkTop, newWidth); + linkTop += _useDefault->height() + st::settingsSmallSkip; + } + _chooseFromGallery->moveToLeft(linkLeft, linkTop, newWidth); + linkTop += _chooseFromGallery->height() + st::settingsSmallSkip; + _chooseFromFile->moveToLeft(linkLeft, linkTop, newWidth); return st::settingsBackgroundSize; } @@ -194,6 +220,7 @@ void BackgroundWidget::createControls() { addChildRow(_background, margin); connect(_background, SIGNAL(chooseFromGallery()), this, SLOT(onChooseFromGallery())); connect(_background, SIGNAL(chooseFromFile()), this, SLOT(onChooseFromFile())); + connect(_background, SIGNAL(useDefault()), this, SLOT(onUseDefault())); addChildRow(_tile, margin, lang(lng_settings_bg_tile), SLOT(onTile()), Window::Theme::Background()->tile()); addChildRow(_adaptive, margin, slidedPadding, lang(lng_settings_adaptive_wide), SLOT(onAdaptive()), Global::AdaptiveForWide()); @@ -213,13 +240,16 @@ void BackgroundWidget::needBackgroundUpdate(bool tile) { void BackgroundWidget::onChooseFromFile() { auto imgExtensions = cImgExtensions(); - auto filters = QStringList(qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(")")); - filters.push_back(qsl("Theme files (*.tdesktop-theme)")); + auto filters = QStringList(qsl("Theme files (*.tdesktop-theme *") + imgExtensions.join(qsl(" *")) + qsl(")")); filters.push_back(filedialogAllFilesFilter()); _chooseFromFileQueryId = FileDialog::queryReadFile(lang(lng_choose_image), filters.join(qsl(";;"))); } +void BackgroundWidget::onUseDefault() { + Window::Theme::ApplyDefault(); +} + void BackgroundWidget::notifyFileQueryUpdated(const FileDialog::QueryUpdate &update) { if (_chooseFromFileQueryId != update.queryId) { return; diff --git a/Telegram/SourceFiles/settings/settings_background_widget.h b/Telegram/SourceFiles/settings/settings_background_widget.h index 63e2129fb..fa25a4dbc 100644 --- a/Telegram/SourceFiles/settings/settings_background_widget.h +++ b/Telegram/SourceFiles/settings/settings_background_widget.h @@ -26,7 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Settings { -class BackgroundRow : public TWidget { +class BackgroundRow : public TWidget, private base::Subscriber { Q_OBJECT public: @@ -42,8 +42,11 @@ protected: signals: void chooseFromGallery(); void chooseFromFile(); + void useDefault(); private: + void checkNonDefaultTheme(); + float64 radialProgress() const; bool radialLoading() const; QRect radialRect() const; @@ -52,6 +55,7 @@ private: void step_radial(TimeMs ms, bool timer); QPixmap _background; + object_ptr _useDefault = { nullptr }; object_ptr _chooseFromGallery; object_ptr _chooseFromFile; @@ -68,6 +72,7 @@ public: private slots: void onChooseFromGallery(); void onChooseFromFile(); + void onUseDefault(); void onTile(); void onAdaptive(); diff --git a/Telegram/SourceFiles/ui/effects/round_checkbox.cpp b/Telegram/SourceFiles/ui/effects/round_checkbox.cpp index bbf7355a7..cf5f60fb4 100644 --- a/Telegram/SourceFiles/ui/effects/round_checkbox.cpp +++ b/Telegram/SourceFiles/ui/effects/round_checkbox.cpp @@ -144,6 +144,15 @@ void RoundCheckbox::setChecked(bool newChecked, SetStyle speed) { } } +void RoundCheckbox::invalidateCache() { + if (!_wideCheckBgCache.isNull() || !_wideCheckFullCache.isNull()) { + prepareCheckCaches(&_st, _displayInactive, _wideCheckBgCache, _wideCheckFullCache); + } + if (!_inactiveCacheBg.isNull() || !_inactiveCacheFg.isNull()) { + prepareInactiveCache(); + } +} + void RoundCheckbox::setDisplayInactive(bool displayInactive) { if (_displayInactive != displayInactive) { _displayInactive = displayInactive; diff --git a/Telegram/SourceFiles/ui/effects/round_checkbox.h b/Telegram/SourceFiles/ui/effects/round_checkbox.h index 4d11bff91..c26ead8ec 100644 --- a/Telegram/SourceFiles/ui/effects/round_checkbox.h +++ b/Telegram/SourceFiles/ui/effects/round_checkbox.h @@ -40,6 +40,8 @@ public: }; void setChecked(bool newChecked, SetStyle speed = SetStyle::Animated); + void invalidateCache(); + private: struct Icon { Animation fadeIn; @@ -79,6 +81,10 @@ public: using SetStyle = RoundCheckbox::SetStyle; void setChecked(bool newChecked, SetStyle speed = SetStyle::Animated); + void invalidateCache() { + _check.invalidateCache(); + } + private: void prepareWideCache(); diff --git a/Telegram/SourceFiles/ui/twidget.cpp b/Telegram/SourceFiles/ui/twidget.cpp index 65ef1f622..21ab8052d 100644 --- a/Telegram/SourceFiles/ui/twidget.cpp +++ b/Telegram/SourceFiles/ui/twidget.cpp @@ -74,7 +74,7 @@ QPixmap myGrab(TWidget *target, QRect rect, QColor bg) { } target->grabStart(); - target->render(&result, QPoint(0, 0), rect, QWidget::DrawChildren | QWidget::IgnoreMask); + target->render(&result, QPoint(0, 0), rect, QWidget::DrawChildren | QWidget::IgnoreMask); target->grabFinish(); return std_::move(result); diff --git a/Telegram/SourceFiles/ui/widgets/buttons.cpp b/Telegram/SourceFiles/ui/widgets/buttons.cpp index f55bb7d33..fbb449c5c 100644 --- a/Telegram/SourceFiles/ui/widgets/buttons.cpp +++ b/Telegram/SourceFiles/ui/widgets/buttons.cpp @@ -41,7 +41,7 @@ int LinkButton::naturalWidth() const { void LinkButton::paintEvent(QPaintEvent *e) { Painter p(this); auto &font = (isOver() ? _st.overFont : _st.font); - auto &pen = (isDown() ? _st.downColor : (isOver() ? _st.overColor : _st.color)); + auto &pen = (isOver() ? _st.overColor : _st.color); p.setFont(font); p.setPen(pen); if (_textWidth > width()) { diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.cpp b/Telegram/SourceFiles/ui/widgets/input_fields.cpp index decd457c1..237350907 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.cpp +++ b/Telegram/SourceFiles/ui/widgets/input_fields.cpp @@ -1830,7 +1830,7 @@ void InputArea::paintEvent(QPaintEvent *e) { p.fillRect(0, height() - _st.border, width(), _st.border, _st.borderFg); } auto errorDegree = _a_error.current(ms, _error ? 1. : 0.); - auto focusedDegree = _a_focused.current(ms, hasFocus() ? 1. : 0.); + auto focusedDegree = _a_focused.current(ms, _focused ? 1. : 0.); auto borderShownDegree = _a_borderShown.current(ms, 1.); auto borderOpacity = _a_borderOpacity.current(ms, _borderVisible ? 1. : 0.); if (_st.borderActive && (borderOpacity > 0.)) { @@ -2547,7 +2547,7 @@ void InputField::paintEvent(QPaintEvent *e) { p.fillRect(0, height() - _st.border, width(), _st.border, _st.borderFg); } auto errorDegree = _a_error.current(ms, _error ? 1. : 0.); - auto focusedDegree = _a_focused.current(ms, hasFocus() ? 1. : 0.); + auto focusedDegree = _a_focused.current(ms, _focused ? 1. : 0.); auto borderShownDegree = _a_borderShown.current(ms, 1.); auto borderOpacity = _a_borderOpacity.current(ms, _borderVisible ? 1. : 0.); if (_st.borderActive && (borderOpacity > 0.)) { @@ -3307,7 +3307,7 @@ void MaskedInputField::paintEvent(QPaintEvent *e) { p.fillRect(0, height() - _st.border, width(), _st.border, _st.borderFg->b); } auto errorDegree = _a_error.current(ms, _error ? 1. : 0.); - auto focusedDegree = _a_focused.current(ms, hasFocus() ? 1. : 0.); + auto focusedDegree = _a_focused.current(ms, _focused ? 1. : 0.); auto borderShownDegree = _a_borderShown.current(ms, 1.); auto borderOpacity = _a_borderOpacity.current(ms, _borderVisible ? 1. : 0.); if (_st.borderActive && (borderOpacity > 0.)) { diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.h b/Telegram/SourceFiles/ui/widgets/input_fields.h index a59444902..9470d9407 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.h +++ b/Telegram/SourceFiles/ui/widgets/input_fields.h @@ -344,6 +344,10 @@ public: } void setDisplayFocused(bool focused); void finishAnimations(); + void setFocusFast() { + setDisplayFocused(true); + setFocus(); + } QSize sizeHint() const override; QSize minimumSizeHint() const override; @@ -517,6 +521,10 @@ public: void setPlaceholderHidden(bool forcePlaceholderHidden); void setDisplayFocused(bool focused); void finishAnimations(); + void setFocusFast() { + setDisplayFocused(true); + setFocus(); + } QSize sizeHint() const override; QSize minimumSizeHint() const override; @@ -698,6 +706,10 @@ public: void setPlaceholderHidden(bool forcePlaceholderHidden); void setDisplayFocused(bool focused); void finishAnimations(); + void setFocusFast() { + setDisplayFocused(true); + setFocus(); + } void setText(const QString &text) { QLineEdit::setText(text); diff --git a/Telegram/SourceFiles/ui/widgets/multi_select.cpp b/Telegram/SourceFiles/ui/widgets/multi_select.cpp index 13f01a649..42200e994 100644 --- a/Telegram/SourceFiles/ui/widgets/multi_select.cpp +++ b/Telegram/SourceFiles/ui/widgets/multi_select.cpp @@ -460,7 +460,7 @@ bool MultiSelect::Inner::setInnerFocus() { if (_active >= 0) { setFocus(); } else if (!_field->hasFocus()) { - _field->setFocus(); + _field->setFocusFast(); return true; } return false; diff --git a/Telegram/SourceFiles/ui/widgets/widgets.style b/Telegram/SourceFiles/ui/widgets/widgets.style index d0fb9815e..841e4bc92 100644 --- a/Telegram/SourceFiles/ui/widgets/widgets.style +++ b/Telegram/SourceFiles/ui/widgets/widgets.style @@ -39,7 +39,6 @@ FlatLabel { LinkButton { color: color; overColor: color; - downColor: color; font: font; overFont: font; } @@ -441,7 +440,6 @@ defaultFlatLabel: FlatLabel { defaultLinkButton: LinkButton { color: windowActiveTextFg; overColor: windowActiveTextFg; - downColor: windowActiveTextFg; font: linkFont; overFont: linkOverFont; } diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 11ec3e30e..af2f0c879 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -32,9 +32,10 @@ MainWindow::MainWindow() : QWidget() , _positionUpdatedTimer(this) , _body(this) , _titleText(qsl("Telegram")) { - subscribe(Theme::Background(), [this](const Theme::BackgroundUpdate &data) { - using Type = Theme::BackgroundUpdate::Type; - if (data.type == Type::TestingTheme || data.type == Type::RevertingTheme || data.type == Type::ApplyingTheme) { + using Update = Theme::BackgroundUpdate; + subscribe(Theme::Background(), [this](const Update &data) { + if (data.type == Update::Type::TestingTheme + || data.type == Update::Type::RevertingTheme) { if (_title) { _title->update(); } diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 03b88ae1c..ff0316d2d 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -62,6 +62,10 @@ void Manager::notificationActivated(PeerId peerId, MsgId msgId) { if (auto window = App::wnd()) { auto history = App::history(peerId); window->showFromTray(); +#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 + window->onReActivate(); + QTimer::singleShot(200, window, SLOT(onReActivate())); +#endif if (App::passcoded()) { window->setInnerFocus(); window->notifyClear(); diff --git a/Telegram/SourceFiles/window/top_bar_widget.cpp b/Telegram/SourceFiles/window/top_bar_widget.cpp index d954e8152..b0f1c4d26 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.cpp +++ b/Telegram/SourceFiles/window/top_bar_widget.cpp @@ -126,7 +126,7 @@ void TopBarWidget::showMenu() { _menuToggle->installEventFilter(_menu); App::main()->fillPeerMenu(peer, [this](const QString &text, base::lambda &&callback) { return _menu->addAction(text, std_::move(callback)); - }); + }, false); _menu->moveToRight(st::topBarMenuPosition.x(), st::topBarMenuPosition.y()); _menu->showAnimated(Ui::PanelAnimation::Origin::TopRight); } diff --git a/Telegram/SourceFiles/window/window_theme.cpp b/Telegram/SourceFiles/window/window_theme.cpp index aa8a2d260..a63dfca3c 100644 --- a/Telegram/SourceFiles/window/window_theme.cpp +++ b/Telegram/SourceFiles/window/window_theme.cpp @@ -539,6 +539,16 @@ void ChatBackground::setTestingTheme(Instance &&theme) { notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, _tile), true); } +void ChatBackground::setTestingDefaultTheme() { + style::main_palette::reset(); + if (_id != kDefaultBackground) { + saveForRevert(); + setImage(internal::kTestingDefaultBackground); + setTile(false); + } + notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, _tile), true); +} + void ChatBackground::keepApplied() { if (_id == internal::kTestingThemeBackground) { _id = kThemeBackground; @@ -613,13 +623,24 @@ bool Apply(const QString &filepath) { return true; } +void ApplyDefault() { + instance.createIfNull(); + instance->applying.path = QString(); + instance->applying.content = QByteArray(); + instance->applying.cached = Cached(); + if (instance->applying.paletteForRevert.isEmpty()) { + instance->applying.paletteForRevert = style::main_palette::save(); + } + Background()->setTestingDefaultTheme(); +} + void KeepApplied() { - auto filepath = instance ? instance->applying.path : QString(); - if (filepath.isEmpty()) { + if (!instance) { return; } - auto pathRelative = QDir().relativeFilePath(filepath); - auto pathAbsolute = QFileInfo(filepath).absoluteFilePath(); + auto filepath = instance->applying.path; + auto pathRelative = filepath.isEmpty() ? QString() : QDir().relativeFilePath(filepath); + auto pathAbsolute = filepath.isEmpty() ? QString() : QFileInfo(filepath).absoluteFilePath(); Local::writeTheme(pathRelative, pathAbsolute, instance->applying.content, instance->applying.cached); instance->applying = Data::Applying(); Background()->keepApplied(); diff --git a/Telegram/SourceFiles/window/window_theme.h b/Telegram/SourceFiles/window/window_theme.h index 06b21e224..f2e1800ad 100644 --- a/Telegram/SourceFiles/window/window_theme.h +++ b/Telegram/SourceFiles/window/window_theme.h @@ -46,6 +46,7 @@ bool Load(const QString &pathRelative, const QString &pathAbsolute, const QByteA void Unload(); bool Apply(const QString &filepath); +void ApplyDefault(); void KeepApplied(); void Revert(); @@ -85,6 +86,7 @@ public: void reset(); void setTestingTheme(Instance &&theme); + void setTestingDefaultTheme(); void keepApplied(); void revert(); diff --git a/Telegram/build/build.bat b/Telegram/build/build.bat index 281781a7c..4117476c5 100644 --- a/Telegram/build/build.bat +++ b/Telegram/build/build.bat @@ -45,9 +45,15 @@ set "DeployPath=%ReleasePath%\deploy\%AppVersionStrMajor%\%AppVersionStrFull%" set "SignPath=%HomePath%\..\..\TelegramPrivate\Sign.bat" set "BinaryName=Telegram" set "DropboxSymbolsPath=X:\Telegram\symbols" +set "FinalReleasePath=Y:\TBuild\tother\tsetup" if not exist %DropboxSymbolsPath% ( - echo Dropbox path not found! + echo Dropbox path %DropboxSymbolsPath% not found! + exit /b 1 +) + +if not exist %FinalReleasePath% ( + echo Release path %FinalReleasePath% not found! exit /b 1 ) @@ -176,7 +182,6 @@ echo . echo Version %AppVersionStrFull% is ready for deploy! echo . -set "FinalReleasePath=Y:\TBuild\tother\tsetup" set "FinalDeployPath=%FinalReleasePath%\%AppVersionStrMajor%\%AppVersionStrFull%" if not exist "%DeployPath%\%UpdateFile%" goto error diff --git a/Telegram/build/version b/Telegram/build/version index 91a62546d..aa37f0cb3 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -3,4 +3,4 @@ AppVersionStrMajor 0.10 AppVersionStrSmall 0.10.20 AppVersionStr 0.10.20 AlphaChannel 0 -BetaVersion 10020001 +BetaVersion 10020002