From 0a9db8533b34a665c52b1eebe64d5f1992b8a0c1 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 24 Jun 2017 20:05:32 +0300 Subject: [PATCH] Save admin log state to memento and restore it. --- .../history/history_admin_log_inner.cpp | 65 ++++++++++--------- .../history/history_admin_log_inner.h | 9 ++- .../history/history_admin_log_section.cpp | 18 ++--- .../history/history_admin_log_section.h | 44 +++++++++++-- Telegram/SourceFiles/mainwidget.cpp | 38 ++++++----- Telegram/SourceFiles/mainwidget.h | 4 +- .../profile/profile_block_widget.h | 4 +- .../profile/profile_common_groups_section.cpp | 18 ++--- .../profile/profile_common_groups_section.h | 16 ++--- .../profile/profile_inner_widget.cpp | 4 +- .../profile/profile_inner_widget.h | 4 +- .../profile/profile_section_memento.cpp | 2 +- .../profile/profile_section_memento.h | 2 +- .../SourceFiles/profile/profile_widget.cpp | 12 ++-- Telegram/SourceFiles/profile/profile_widget.h | 10 +-- Telegram/SourceFiles/window/section_memento.h | 2 +- Telegram/SourceFiles/window/section_widget.h | 8 ++- 17 files changed, 152 insertions(+), 108 deletions(-) diff --git a/Telegram/SourceFiles/history/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/history_admin_log_inner.cpp index 865cc53156..d38b33e60a 100644 --- a/Telegram/SourceFiles/history/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/history_admin_log_inner.cpp @@ -335,35 +335,22 @@ QPoint InnerWidget::tooltipPos() const { return _mousePosition; } -void InnerWidget::saveState(gsl::not_null memento) const { - //if (auto count = _items.size()) { - // QList> groups; - // groups.reserve(count); - // for_const (auto item, _items) { - // groups.push_back(item->peer); - // } - // memento->setCommonGroups(groups); - //} +void InnerWidget::saveState(gsl::not_null memento) { + memento->setItems(std::move(_items), std::move(_itemsByIds), _upLoaded, _downLoaded); + memento->setIdManager(std::move(_idManager)); + _upLoaded = _downLoaded = true; // Don't load or handle anything anymore. } -void InnerWidget::restoreState(gsl::not_null memento) { - //auto list = memento->getCommonGroups(); - //_allLoaded = false; - //if (!list.empty()) { - // showInitial(list); - //} +void InnerWidget::restoreState(gsl::not_null memento) { + _items = memento->takeItems(); + _itemsByIds = memento->takeItemsByIds(); + _idManager = memento->takeIdManager(); + _upLoaded = memento->upLoaded(); + _downLoaded = memento->downLoaded(); + updateMinMaxIds(); + updateSize(); } -//void InnerWidget::showInitial(const QList &list) { -// for_const (auto group, list) { -// if (auto item = computeItem(group)) { -// _items.push_back(item); -// } -// _preloadGroupId = group->bareId(); -// } -// updateSize(); -//} - void InnerWidget::preloadMore(Direction direction) { auto &requestId = (direction == Direction::Up) ? _preloadUpRequestId : _preloadDownRequestId; auto &loadedFlag = (direction == Direction::Up) ? _upLoaded : _downLoaded; @@ -394,6 +381,10 @@ void InnerWidget::preloadMore(Direction direction) { auto &results = result.c_channels_adminLogResults(); App::feedUsers(results.vusers); App::feedChats(results.vchats); + + if (loadedFlag) { + return; + } auto &events = results.vevents.v; if (!events.empty()) { auto oldItemsCount = _items.size(); @@ -401,10 +392,14 @@ void InnerWidget::preloadMore(Direction direction) { for_const (auto &event, events) { t_assert(event.type() == mtpc_channelAdminLogEvent); auto &data = event.c_channelAdminLogEvent(); + if (_itemsByIds.find(data.vid.v) != _itemsByIds.cend()) { + continue; + } + auto count = 0; GenerateItems(_history, _idManager, data, [this, id = data.vid.v, &count](HistoryItemOwned item) { - _items.push_back(std::move(item)); _itemsByIds.emplace(id, item.get()); + _items.push_back(std::move(item)); ++count; }); if (count > 1) { @@ -433,11 +428,7 @@ void InnerWidget::preloadMore(Direction direction) { } } } - _maxId = (--_itemsByIds.end())->first; - _minId = _itemsByIds.begin()->first; - if (_minId == 1) { - _upLoaded = true; - } + updateMinMaxIds(); itemsAdded(direction); } } else { @@ -449,6 +440,18 @@ void InnerWidget::preloadMore(Direction direction) { }).send(); } +void InnerWidget::updateMinMaxIds() { + if (_itemsByIds.empty()) { + _maxId = _minId = 0; + } else { + _maxId = (--_itemsByIds.end())->first; + _minId = _itemsByIds.begin()->first; + if (_minId == 1) { + _upLoaded = true; + } + } +} + void InnerWidget::itemsAdded(Direction direction) { updateSize(); } diff --git a/Telegram/SourceFiles/history/history_admin_log_inner.h b/Telegram/SourceFiles/history/history_admin_log_inner.h index 1eb839d920..a64bdf504c 100644 --- a/Telegram/SourceFiles/history/history_admin_log_inner.h +++ b/Telegram/SourceFiles/history/history_admin_log_inner.h @@ -76,8 +76,8 @@ public: return TWidget::resizeToWidth(newWidth); } - void saveState(gsl::not_null memento) const; - void restoreState(gsl::not_null memento); + void saveState(gsl::not_null memento); + void restoreState(gsl::not_null memento); void setCancelledCallback(base::lambda callback) { _cancelledCallback = std::move(callback); } @@ -151,6 +151,7 @@ private: void preloadMore(Direction direction); void itemsAdded(Direction direction); void updateSize(); + void updateMinMaxIds(); void paintEmpty(Painter &p); void toggleScrollDateShown(); @@ -213,7 +214,9 @@ private: uint64 _minId = 0; mtpRequestId _preloadUpRequestId = 0; mtpRequestId _preloadDownRequestId = 0; - bool _upLoaded = false; + + // Don't load anything until the memento was read. + bool _upLoaded = true; bool _downLoaded = true; MouseAction _mouseAction = MouseAction::None; diff --git a/Telegram/SourceFiles/history/history_admin_log_section.cpp b/Telegram/SourceFiles/history/history_admin_log_section.cpp index 78c17e91b6..35bc07232a 100644 --- a/Telegram/SourceFiles/history/history_admin_log_section.cpp +++ b/Telegram/SourceFiles/history/history_admin_log_section.cpp @@ -61,7 +61,7 @@ private: }; -object_ptr SectionMemento::createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) const { +object_ptr SectionMemento::createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) { auto result = object_ptr(parent, controller, _channel); result->setInternalState(geometry, this); return std::move(result); @@ -168,34 +168,34 @@ void Widget::doSetInnerFocus() { _inner->setFocus(); } -bool Widget::showInternal(const Window::SectionMemento *memento) { - if (auto profileMemento = dynamic_cast(memento)) { - if (profileMemento->getChannel() == channel()) { - restoreState(profileMemento); +bool Widget::showInternal(gsl::not_null memento) { + if (auto logMemento = dynamic_cast(memento.get())) { + if (logMemento->getChannel() == channel()) { + restoreState(logMemento); return true; } } return false; } -void Widget::setInternalState(const QRect &geometry, gsl::not_null memento) { +void Widget::setInternalState(const QRect &geometry, gsl::not_null memento) { setGeometry(geometry); myEnsureResized(this); restoreState(memento); } -std::unique_ptr Widget::createMemento() const { +std::unique_ptr Widget::createMemento() { auto result = std::make_unique(channel()); saveState(result.get()); return std::move(result); } -void Widget::saveState(gsl::not_null memento) const { +void Widget::saveState(gsl::not_null memento) { memento->setScrollTop(_scroll->scrollTop()); _inner->saveState(memento); } -void Widget::restoreState(gsl::not_null memento) { +void Widget::restoreState(gsl::not_null memento) { _inner->restoreState(memento); auto scrollTop = memento->getScrollTop(); _scroll->scrollToY(scrollTop); diff --git a/Telegram/SourceFiles/history/history_admin_log_section.h b/Telegram/SourceFiles/history/history_admin_log_section.h index a0188ebecc..6a8c29663a 100644 --- a/Telegram/SourceFiles/history/history_admin_log_section.h +++ b/Telegram/SourceFiles/history/history_admin_log_section.h @@ -22,6 +22,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "window/section_widget.h" #include "window/section_memento.h" +#include "history/history_admin_log_item.h" +#include "history/history_admin_log_inner.h" namespace Notify { struct PeerUpdate; @@ -58,10 +60,10 @@ public: QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms) override; - bool showInternal(const Window::SectionMemento *memento) override; - std::unique_ptr createMemento() const override; + bool showInternal(gsl::not_null memento) override; + std::unique_ptr createMemento() override; - void setInternalState(const QRect &geometry, gsl::not_null memento); + void setInternalState(const QRect &geometry, gsl::not_null memento); // Float player interface. bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; @@ -81,8 +83,8 @@ protected: private: void onScroll(); void updateAdaptiveLayout(); - void saveState(gsl::not_null memento) const; - void restoreState(gsl::not_null memento); + void saveState(gsl::not_null memento); + void restoreState(gsl::not_null memento); object_ptr _scroll; QPointer _inner; @@ -97,7 +99,7 @@ public: SectionMemento(gsl::not_null channel) : _channel(channel) { } - object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) const override; + object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) override; gsl::not_null getChannel() const { return _channel; @@ -109,9 +111,39 @@ public: return _scrollTop; } + void setItems(std::vector &&items, std::map &&itemsByIds, bool upLoaded, bool downLoaded) { + _items = std::move(items); + _itemsByIds = std::move(itemsByIds); + _upLoaded = upLoaded; + _downLoaded = downLoaded; + } + void setIdManager(LocalIdManager &&manager) { + _idManager = std::move(manager); + } + std::vector takeItems() { + return std::move(_items); + } + std::map takeItemsByIds() { + return std::move(_itemsByIds); + } + LocalIdManager takeIdManager() { + return std::move(_idManager); + } + bool upLoaded() const { + return _upLoaded; + } + bool downLoaded() const { + return _downLoaded; + } + private: gsl::not_null _channel; int _scrollTop = 0; + std::vector _items; + std::map _itemsByIds; + bool _upLoaded = false; + bool _downLoaded = true; + LocalIdManager _idManager; }; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 21e972996b..823686d4bd 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -2517,15 +2517,6 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show } } - dlgUpdated(); - if (back || (way == Ui::ShowWay::ClearStack)) { - _peerInStack = nullptr; - _msgIdInStack = 0; - } else { - saveSectionInStack(); - } - dlgUpdated(); - auto wasActivePeer = activePeer(); Ui::hideSettingsAndLayer(); @@ -2556,6 +2547,16 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show auto animationParams = animatedShow() ? prepareHistoryAnimation(peerId) : Window::SectionSlideParams(); + dlgUpdated(); + if (back || (way == Ui::ShowWay::ClearStack)) { + _peerInStack = nullptr; + _msgIdInStack = 0; + } else { + // This may modify the current section, for example remove its contents. + saveSectionInStack(); + } + dlgUpdated(); + if (_history->peer() && _history->peer()->id != peerId && way != Ui::ShowWay::Forward) { clearBotStartToken(_history->peer()); } @@ -2708,11 +2709,11 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool return false; }; auto animationParams = animatedShow() ? prepareOverviewAnimation() : Window::SectionSlideParams(); + setFocus(); // otherwise dialogs widget could be focused. + if (!back) { saveSectionInStack(); } - - setFocus(); // otherwise dialogs widget could be focused. if (_overview) { _overview->hide(); _overview->clear(); @@ -2751,12 +2752,12 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool orderWidgets(); } -void MainWidget::showWideSection(const Window::SectionMemento &memento) { +void MainWidget::showWideSection(Window::SectionMemento &&memento) { Ui::hideSettingsAndLayer(); if (_wideSection && _wideSection->showInternal(&memento)) { return; } - showNewWideSection(&memento, false, true); + showNewWideSection(std::move(memento), false, true); } Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarShadow, bool willHaveTabbedSection) { @@ -2856,7 +2857,7 @@ Window::SectionSlideParams MainWidget::prepareDialogsAnimation() { return prepareShowAnimation(false, false); } -void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool back, bool saveInStack) { +void MainWidget::showNewWideSection(Window::SectionMemento &&memento, bool back, bool saveInStack) { QPixmap animCache; _controller->dialogsListFocused().set(false, true); @@ -2864,7 +2865,7 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool auto sectionTop = getSectionTop(); auto newWideGeometry = QRect(_history->x(), sectionTop, _history->width(), height() - sectionTop); - auto newWideSection = memento->createWidget(this, _controller, newWideGeometry); + auto newWideSection = memento.createWidget(this, _controller, newWideGeometry); auto animatedShow = [this] { if (_a_show.animating() || App::passcoded()) { return false; @@ -2876,11 +2877,12 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool }; auto animationParams = animatedShow() ? prepareWideSectionAnimation(newWideSection) : Window::SectionSlideParams(); + setFocus(); // otherwise dialogs widget could be focused. + if (saveInStack) { + // This may modify the current section, for example remove its contents. saveSectionInStack(); } - - setFocus(); // otherwise dialogs widget could be focused. if (_overview) { _overview->hide(); _overview->clear(); @@ -2949,7 +2951,7 @@ void MainWidget::showBackFromStack() { _history->setReplyReturns(historyItem->peer->id, historyItem->replyReturns); } else if (item->type() == SectionStackItem) { auto sectionItem = static_cast(item.get()); - showNewWideSection(sectionItem->memento(), true, false); + showNewWideSection(std::move(*sectionItem->memento()), true, false); } else if (item->type() == OverviewStackItem) { auto overviewItem = static_cast(item.get()); showMediaOverview(overviewItem->peer, overviewItem->mediaType, true, overviewItem->lastScrollTop); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index e594fc4998..b5cfcbb927 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -215,7 +215,7 @@ public: int backgroundFromY() const; PeerData *overviewPeer(); bool showMediaTypeSwitch() const; - void showWideSection(const Window::SectionMemento &memento); + void showWideSection(Window::SectionMemento &&memento); void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1); bool stackIsEmpty() const; void showBackFromStack(); @@ -521,7 +521,7 @@ private: void mediaOverviewUpdated(const Notify::PeerUpdate &update); Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow, bool willHaveTabbedSection); - void showNewWideSection(const Window::SectionMemento *memento, bool back, bool saveInStack); + void showNewWideSection(Window::SectionMemento &&memento, bool back, bool saveInStack); // All this methods use the prepareShowAnimation(). Window::SectionSlideParams prepareWideSectionAnimation(Window::SectionWidget *section); diff --git a/Telegram/SourceFiles/profile/profile_block_widget.h b/Telegram/SourceFiles/profile/profile_block_widget.h index fc4c451e7b..0e73317f9b 100644 --- a/Telegram/SourceFiles/profile/profile_block_widget.h +++ b/Telegram/SourceFiles/profile/profile_block_widget.h @@ -35,9 +35,9 @@ public: virtual void showFinished() { } - virtual void saveState(SectionMemento *memento) const { + virtual void saveState(gsl::not_null memento) { } - virtual void restoreState(const SectionMemento *memento) { + virtual void restoreState(gsl::not_null memento) { } protected: diff --git a/Telegram/SourceFiles/profile/profile_common_groups_section.cpp b/Telegram/SourceFiles/profile/profile_common_groups_section.cpp index 26835862b4..77b25cc2ae 100644 --- a/Telegram/SourceFiles/profile/profile_common_groups_section.cpp +++ b/Telegram/SourceFiles/profile/profile_common_groups_section.cpp @@ -42,7 +42,7 @@ constexpr int kCommonGroupsPerPage = 40; } // namespace -object_ptr SectionMemento::createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) const { +object_ptr SectionMemento::createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) { auto result = object_ptr(parent, controller, _user); result->setInternalState(geometry, this); return std::move(result); @@ -118,7 +118,7 @@ void InnerWidget::checkPreloadMore() { } } -void InnerWidget::saveState(SectionMemento *memento) const { +void InnerWidget::saveState(gsl::not_null memento) { if (auto count = _items.size()) { QList> groups; groups.reserve(count); @@ -129,7 +129,7 @@ void InnerWidget::saveState(SectionMemento *memento) const { } } -void InnerWidget::restoreState(const SectionMemento *memento) { +void InnerWidget::restoreState(gsl::not_null memento) { auto list = memento->getCommonGroups(); _allLoaded = false; if (!list.empty()) { @@ -374,8 +374,8 @@ void Widget::doSetInnerFocus() { _inner->setFocus(); } -bool Widget::showInternal(const Window::SectionMemento *memento) { - if (auto profileMemento = dynamic_cast(memento)) { +bool Widget::showInternal(gsl::not_null memento) { + if (auto profileMemento = dynamic_cast(memento.get())) { if (profileMemento->getUser() == user()) { restoreState(profileMemento); return true; @@ -384,24 +384,24 @@ bool Widget::showInternal(const Window::SectionMemento *memento) { return false; } -void Widget::setInternalState(const QRect &geometry, const SectionMemento *memento) { +void Widget::setInternalState(const QRect &geometry, gsl::not_null memento) { setGeometry(geometry); myEnsureResized(this); restoreState(memento); } -std::unique_ptr Widget::createMemento() const { +std::unique_ptr Widget::createMemento() { auto result = std::make_unique(user()); saveState(result.get()); return std::move(result); } -void Widget::saveState(SectionMemento *memento) const { +void Widget::saveState(gsl::not_null memento) { memento->setScrollTop(_scroll->scrollTop()); _inner->saveState(memento); } -void Widget::restoreState(const SectionMemento *memento) { +void Widget::restoreState(gsl::not_null memento) { _inner->restoreState(memento); auto scrollTop = memento->getScrollTop(); _scroll->scrollToY(scrollTop); diff --git a/Telegram/SourceFiles/profile/profile_common_groups_section.h b/Telegram/SourceFiles/profile/profile_common_groups_section.h index 6eea2da6a0..808990dafa 100644 --- a/Telegram/SourceFiles/profile/profile_common_groups_section.h +++ b/Telegram/SourceFiles/profile/profile_common_groups_section.h @@ -43,7 +43,7 @@ public: SectionMemento(gsl::not_null user) : _user(user) { } - object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) const override; + object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) override; gsl::not_null getUser() const { return _user; @@ -110,8 +110,8 @@ public: return TWidget::resizeToWidth(newWidth); } - void saveState(SectionMemento *memento) const; - void restoreState(const SectionMemento *memento); + void saveState(gsl::not_null memento); + void restoreState(gsl::not_null memento); ~InnerWidget(); @@ -184,10 +184,10 @@ public: QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms) override; - bool showInternal(const Window::SectionMemento *memento) override; - std::unique_ptr createMemento() const override; + bool showInternal(gsl::not_null memento) override; + std::unique_ptr createMemento() override; - void setInternalState(const QRect &geometry, const SectionMemento *memento); + void setInternalState(const QRect &geometry, gsl::not_null memento); // Float player interface. bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; @@ -205,8 +205,8 @@ private slots: private: void updateAdaptiveLayout(); - void saveState(SectionMemento *memento) const; - void restoreState(const SectionMemento *memento); + void saveState(gsl::not_null memento); + void restoreState(gsl::not_null memento); object_ptr _scroll; QPointer _inner; diff --git a/Telegram/SourceFiles/profile/profile_inner_widget.cpp b/Telegram/SourceFiles/profile/profile_inner_widget.cpp index a54323babd..2c7a187c5d 100644 --- a/Telegram/SourceFiles/profile/profile_inner_widget.cpp +++ b/Telegram/SourceFiles/profile/profile_inner_widget.cpp @@ -89,13 +89,13 @@ bool InnerWidget::shareContactButtonShown() const { return _cover->shareContactButtonShown(); } -void InnerWidget::saveState(SectionMemento *memento) const { +void InnerWidget::saveState(gsl::not_null memento) { for_const (auto &blockData, _blocks) { blockData.block->saveState(memento); } } -void InnerWidget::restoreState(const SectionMemento *memento) { +void InnerWidget::restoreState(gsl::not_null memento) { for_const (auto &blockData, _blocks) { blockData.block->restoreState(memento); } diff --git a/Telegram/SourceFiles/profile/profile_inner_widget.h b/Telegram/SourceFiles/profile/profile_inner_widget.h index 701b4aaea8..aa3b5d7891 100644 --- a/Telegram/SourceFiles/profile/profile_inner_widget.h +++ b/Telegram/SourceFiles/profile/profile_inner_widget.h @@ -49,8 +49,8 @@ public: // It should show it only if it is hidden in the cover. bool shareContactButtonShown() const; - void saveState(SectionMemento *memento) const; - void restoreState(const SectionMemento *memento); + void saveState(gsl::not_null memento); + void restoreState(gsl::not_null memento); void showFinished(); diff --git a/Telegram/SourceFiles/profile/profile_section_memento.cpp b/Telegram/SourceFiles/profile/profile_section_memento.cpp index 5998c86e98..c07bbe4118 100644 --- a/Telegram/SourceFiles/profile/profile_section_memento.cpp +++ b/Telegram/SourceFiles/profile/profile_section_memento.cpp @@ -24,7 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace Profile { -object_ptr SectionMemento::createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) const { +object_ptr SectionMemento::createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) { auto result = object_ptr(parent, controller, _peer); result->setInternalState(geometry, this); return std::move(result); diff --git a/Telegram/SourceFiles/profile/profile_section_memento.h b/Telegram/SourceFiles/profile/profile_section_memento.h index 979a32fb3c..cc7140ad79 100644 --- a/Telegram/SourceFiles/profile/profile_section_memento.h +++ b/Telegram/SourceFiles/profile/profile_section_memento.h @@ -31,7 +31,7 @@ public: SectionMemento(PeerData *peer) : _peer(peer) { } - object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) const override; + object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) override; PeerData *getPeer() const { return _peer; diff --git a/Telegram/SourceFiles/profile/profile_widget.cpp b/Telegram/SourceFiles/profile/profile_widget.cpp index 1264e6e699..c70c2ef1aa 100644 --- a/Telegram/SourceFiles/profile/profile_widget.cpp +++ b/Telegram/SourceFiles/profile/profile_widget.cpp @@ -76,8 +76,8 @@ void Widget::doSetInnerFocus() { _inner->setFocus(); } -bool Widget::showInternal(const Window::SectionMemento *memento) { - if (auto profileMemento = dynamic_cast(memento)) { +bool Widget::showInternal(gsl::not_null memento) { + if (auto profileMemento = dynamic_cast(memento.get())) { if (profileMemento->getPeer() == peer()) { restoreState(profileMemento); return true; @@ -86,24 +86,24 @@ bool Widget::showInternal(const Window::SectionMemento *memento) { return false; } -void Widget::setInternalState(const QRect &geometry, const SectionMemento *memento) { +void Widget::setInternalState(const QRect &geometry, gsl::not_null memento) { setGeometry(geometry); myEnsureResized(this); restoreState(memento); } -std::unique_ptr Widget::createMemento() const { +std::unique_ptr Widget::createMemento() { auto result = std::make_unique(peer()); saveState(result.get()); return std::move(result); } -void Widget::saveState(SectionMemento *memento) const { +void Widget::saveState(gsl::not_null memento) { memento->setScrollTop(_scroll->scrollTop()); _inner->saveState(memento); } -void Widget::restoreState(const SectionMemento *memento) { +void Widget::restoreState(gsl::not_null memento) { _inner->restoreState(memento); auto scrollTop = memento->getScrollTop(); _scroll->scrollToY(scrollTop); diff --git a/Telegram/SourceFiles/profile/profile_widget.h b/Telegram/SourceFiles/profile/profile_widget.h index bd57297787..82438996dc 100644 --- a/Telegram/SourceFiles/profile/profile_widget.h +++ b/Telegram/SourceFiles/profile/profile_widget.h @@ -49,10 +49,10 @@ public: QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms) override; - bool showInternal(const Window::SectionMemento *memento) override; - std::unique_ptr createMemento() const override; + bool showInternal(gsl::not_null memento) override; + std::unique_ptr createMemento() override; - void setInternalState(const QRect &geometry, const SectionMemento *memento); + void setInternalState(const QRect &geometry, gsl::not_null memento); // Float player interface. bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; @@ -71,8 +71,8 @@ private slots: private: void updateScrollState(); void updateAdaptiveLayout(); - void saveState(SectionMemento *memento) const; - void restoreState(const SectionMemento *memento); + void saveState(gsl::not_null memento); + void restoreState(gsl::not_null memento); object_ptr _scroll; QPointer _inner; diff --git a/Telegram/SourceFiles/window/section_memento.h b/Telegram/SourceFiles/window/section_memento.h index 46c22f3d91..9151fa49f8 100644 --- a/Telegram/SourceFiles/window/section_memento.h +++ b/Telegram/SourceFiles/window/section_memento.h @@ -27,7 +27,7 @@ class SectionWidget; class SectionMemento { public: - virtual object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) const = 0; + virtual object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) = 0; virtual ~SectionMemento() { } diff --git a/Telegram/SourceFiles/window/section_widget.h b/Telegram/SourceFiles/window/section_widget.h index 72dfc06b71..0a283e3445 100644 --- a/Telegram/SourceFiles/window/section_widget.h +++ b/Telegram/SourceFiles/window/section_widget.h @@ -96,10 +96,14 @@ public: // Attempt to show the required section inside the existing one. // For example if this section already shows exactly the required // memento it can simply return true - it is shown already. - virtual bool showInternal(const SectionMemento *memento) = 0; + // + // If this method returns false it is not supposed to modify the memento. + // If this method returns true it may modify the memento ("take" heavy items). + virtual bool showInternal(gsl::not_null memento) = 0; // Create a memento of that section to store it in the history stack. - virtual std::unique_ptr createMemento() const = 0; + // This method may modify the section ("take" heavy items). + virtual std::unique_ptr createMemento() = 0; void setInnerFocus() { doSetInnerFocus();