/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "base/timer.h" #include "dialogs/dialogs_key.h" #include "window/section_widget.h" #include "ui/effects/animations.h" #include "ui/widgets/scroll_area.h" #include "mtproto/sender.h" #include "api/api_single_message_search.h" namespace MTP { class Error; } // namespace MTP namespace Data { class Forum; } // namespace Data namespace Main { class Session; } // namespace Main namespace HistoryView { class TopBarWidget; class ContactStatus; } // namespace HistoryView namespace Ui { class AbstractButton; class IconButton; class PopupMenu; class DropdownMenu; class FlatButton; class InputField; class CrossButton; class PlainShadow; class DownloadBar; class GroupCallBar; class RequestsBar; class JumpDownButton; template class FadeWrapScaled; } // namespace Ui namespace Window { class SessionController; class ConnectionState; struct SectionShow; } // namespace Window namespace Dialogs { struct RowDescriptor; class Row; class FakeRow; class Key; struct ChosenRow; class InnerWidget; enum class SearchRequestType; class Widget final : public Window::AbstractSectionWidget { public: enum class Layout { Main, Child, }; Widget( QWidget *parent, not_null controller, Layout layout); // When resizing the widget with top edge moved up or down and we // want to add this top movement to the scroll position, so inner // content will not move. void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta); void updateDragInScroll(bool inScroll); void showForum( not_null forum, const Window::SectionShow ¶ms); void searchInChat(Key chat); void setInnerFocus(); void jumpToTop(bool belowPinned = false); void startWidthAnimation(); void stopWidthAnimation(); bool hasTopBarShadow() const { return true; } void showAnimated( Window::SlideDirection direction, const Window::SectionSlideParams ¶ms); void showFast(); [[nodiscard]] rpl::producer shownProgressValue() const; void scrollToEntry(const RowDescriptor &entry); void searchMessages(const QString &query, Key inChat = {}); void searchTopics(); void searchMore(); [[nodiscard]] RowDescriptor resolveChatNext(RowDescriptor from = {}) const; [[nodiscard]] RowDescriptor resolveChatPrevious(RowDescriptor from = {}) const; // Float player interface. bool floatPlayerHandleWheelEvent(QEvent *e) override; QRect floatPlayerAvailableRect() override; bool cancelSearch(); ~Widget(); protected: void dragEnterEvent(QDragEnterEvent *e) override; void dragMoveEvent(QDragMoveEvent *e) override; void dragLeaveEvent(QDragLeaveEvent *e) override; void dropEvent(QDropEvent *e) override; void resizeEvent(QResizeEvent *e) override; void keyPressEvent(QKeyEvent *e) override; void paintEvent(QPaintEvent *e) override; private: void chosenRow(const ChosenRow &row); void listScrollUpdated(); void cancelSearchInChat(); void filterCursorMoved(); void completeHashtag(QString tag); [[nodiscard]] QString currentSearchQuery() const; void clearSearchField(); bool searchMessages(bool searchCache = false); void needSearchMessages(); void slideFinished(); void searchReceived( SearchRequestType type, const MTPmessages_Messages &result, mtpRequestId requestId); void peerSearchReceived( const MTPcontacts_Found &result, mtpRequestId requestId); void escape(); void submit(); void cancelSearchRequest(); [[nodiscard]] PeerData *searchInPeer() const; [[nodiscard]] Data::ForumTopic *searchInTopic() const; void setupSupportMode(); void setupConnectingWidget(); void setupMainMenuToggle(); void setupDownloadBar(); void setupShortcuts(); [[nodiscard]] bool searchForPeersRequired(const QString &query) const; [[nodiscard]] bool searchForTopicsRequired(const QString &query) const; bool setSearchInChat(Key chat, PeerData *from = nullptr); void showCalendar(); void showSearchFrom(); void showMainMenu(); void clearSearchCache(); void setSearchQuery(const QString &query); void updateControlsVisibility(bool fast = false); void updateLockUnlockVisibility(); void updateLoadMoreChatsVisibility(); void updateJumpToDateVisibility(bool fast = false); void updateSearchFromVisibility(bool fast = false); void updateControlsGeometry(); void refreshTopBars(); void showSearchInTopBar(anim::type animated); void checkUpdateStatus(); void changeOpenedSubsection( FnMut change, bool fromRight, anim::type animated); void changeOpenedFolder(Data::Folder *folder, anim::type animated); void changeOpenedForum(Data::Forum *forum, anim::type animated); void hideChildList(); void destroyChildListCanvas(); [[nodiscard]] QPixmap grabForFolderSlideAnimation(); void startSlideAnimation( QPixmap oldContentCache, QPixmap newContentCache, Window::SlideDirection direction); void openChildList( not_null forum, const Window::SectionShow ¶ms); void closeChildList(anim::type animated); void fullSearchRefreshOn(rpl::producer<> events); void applyFilterUpdate(bool force = false); void refreshLoadMoreButton(bool mayBlock, bool isBlocked); void loadMoreBlockedByDate(); void searchFailed( SearchRequestType type, const MTP::Error &error, mtpRequestId requestId); void peopleFailed(const MTP::Error &error, mtpRequestId requestId); void scrollToTop(); void setupScrollUpButton(); void updateScrollUpVisibility(); void startScrollUpButtonAnimation(bool shown); void updateScrollUpPosition(); MTP::Sender _api; bool _dragInScroll = false; bool _dragForward = false; base::Timer _chooseByDragTimer; Layout _layout = Layout::Main; int _narrowWidth = 0; object_ptr _searchControls; object_ptr _subsectionTopBar = { nullptr } ; struct { object_ptr toggle; object_ptr under; } _mainMenu; object_ptr _searchForNarrowFilters; object_ptr _filter; object_ptr> _chooseFromUser; object_ptr> _jumpToDate; object_ptr _cancelSearch; object_ptr _lockUnlock; std::unique_ptr _forumTopShadow; std::unique_ptr _forumGroupCallBar; std::unique_ptr _forumRequestsBar; std::unique_ptr _forumReportBar; object_ptr _scroll; QPointer _inner; class BottomButton; object_ptr _updateTelegram = { nullptr }; object_ptr _loadMoreChats = { nullptr }; std::unique_ptr _downloadBar; std::unique_ptr _connecting; Ui::Animations::Simple _scrollToAnimation; std::unique_ptr _showAnimation; rpl::variable _shownProgressValue; Ui::Animations::Simple _scrollToTopShown; object_ptr _scrollToTop; bool _scrollToTopIsShown = false; bool _forumSearchRequested = false; Data::Folder *_openedFolder = nullptr; Data::Forum *_openedForum = nullptr; Dialogs::Key _searchInChat; History *_searchInMigrated = nullptr; PeerData *_searchFromAuthor = nullptr; QString _lastFilterText; base::Timer _searchTimer; QString _peerSearchQuery; bool _peerSearchFull = false; mtpRequestId _peerSearchRequest = 0; QString _topicSearchQuery; TimeId _topicSearchOffsetDate = 0; MsgId _topicSearchOffsetId = 0; MsgId _topicSearchOffsetTopicId = 0; bool _topicSearchFull = false; mtpRequestId _topicSearchRequest = 0; QString _searchQuery; PeerData *_searchQueryFrom = nullptr; int32 _searchNextRate = 0; bool _searchFull = false; bool _searchFullMigrated = false; int _searchInHistoryRequest = 0; // Not real mtpRequestId. mtpRequestId _searchRequest = 0; PeerData *_lastSearchPeer = nullptr; MsgId _lastSearchId = 0; MsgId _lastSearchMigratedId = 0; base::flat_map _searchCache; Api::SingleMessageSearch _singleMessageSearch; base::flat_map _searchQueries; base::flat_map _peerSearchCache; base::flat_map _peerSearchQueries; QPixmap _widthAnimationCache; int _topDelta = 0; std::unique_ptr _childList; std::unique_ptr _childListShadow; rpl::variable _childListShown; rpl::variable _childListPeerId; std::unique_ptr _hideChildListCanvas; }; } // namespace Dialogs