diff --git a/Telegram/SourceFiles/core/utils.h b/Telegram/SourceFiles/core/utils.h index fdfff3be2..fc27d5f88 100644 --- a/Telegram/SourceFiles/core/utils.h +++ b/Telegram/SourceFiles/core/utils.h @@ -525,12 +525,6 @@ inline int ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) { return qMax(qMin(static_cast(std::ceil(value / step)), highest), lowest); } -enum ForwardWhatMessages { - ForwardSelectedMessages, - ForwardPressedMessage, - ForwardPressedLinkMessage -}; - static int32 FullArcLength = 360 * 16; static int32 QuarterArcLength = (FullArcLength / 4); static int32 MinArcLength = (FullArcLength / 360); diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 3dcf0f1b9..ca47a347f 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -164,6 +164,13 @@ MessageIdsList Session::groupToIds( return result; } +MessageIdsList Session::itemOrItsGroup(not_null item) const { + if (const auto group = item->getFullGroup()) { + return groupToIds(group); + } + return { 1, item->fullId() }; +} + void Session::setPinnedDialog(const Dialogs::Key &key, bool pinned) { setIsPinned(key, pinned); } @@ -292,4 +299,12 @@ Data::Feed *Session::feedLoaded(FeedId id) { return (it == _feeds.end()) ? nullptr : it->second.get(); } +void Session::setMimeForwardIds(MessageIdsList &&list) { + _mimeForwardIds = std::move(list); +} + +MessageIdsList Session::takeMimeForwardIds() { + return std::move(_mimeForwardIds); +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 3d27d4cc0..f20c884ec 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -142,6 +142,7 @@ public: HistoryItemsList idsToItems(const MessageIdsList &ids) const; MessageIdsList itemsToIds(const HistoryItemsList &items) const; MessageIdsList groupToIds(not_null group) const; + MessageIdsList itemOrItsGroup(not_null item) const; int pinnedDialogsCount() const; const std::deque &pinnedDialogsOrder() const; @@ -155,6 +156,9 @@ public: not_null feed(FeedId id); Data::Feed *feedLoaded(FeedId id); + void setMimeForwardIds(MessageIdsList &&list); + MessageIdsList takeMimeForwardIds(); + private: bool stickersUpdateNeeded(TimeMs lastUpdate, TimeMs now) const { constexpr auto kStickersUpdateTimeout = TimeMs(3600'000); @@ -196,6 +200,8 @@ private: std::deque _pinnedDialogs; base::flat_map> _feeds; + MessageIdsList _mimeForwardIds; + rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 154ebdf6e..b8b577a7e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -737,9 +737,7 @@ void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) { _dragInScroll = false; _dragForward = Adaptive::OneColumn() ? false - : (data->hasFormat(qsl("application/x-td-forward-selected")) - || data->hasFormat(qsl("application/x-td-forward-pressed-link")) - || data->hasFormat(qsl("application/x-td-forward-pressed"))); + : data->hasFormat(qsl("application/x-td-forward")); if (_dragForward) { e->setDropAction(Qt::CopyAction); e->accept(); diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index a5e9582df..d28e26c0a 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -115,10 +115,9 @@ void InnerWidget::enumerateUserpics(Method method) { // -1 means we didn't find an attached to next message yet. int lowestAttachedItemTop = -1; - auto userpicCallback = [&](Message *view, int itemtop, int itembottom) { + auto userpicCallback = [&](not_null view, int itemtop, int itembottom) { // Skip all service messages. - const auto item = view->data(); - auto message = item->toHistoryMessage(); + const auto message = view->data()->toHistoryMessage(); if (!message) return true; if (lowestAttachedItemTop < 0 && message->isAttachedToNext()) { @@ -140,7 +139,7 @@ void InnerWidget::enumerateUserpics(Method method) { // Call the template callback function that was passed // and return if it finished everything it needed. - if (!method(message, userpicBottom - st::msgPhotoSize)) { + if (!method(view, userpicBottom - st::msgPhotoSize)) { return false; } } @@ -162,7 +161,7 @@ void InnerWidget::enumerateDates(Method method) { // -1 means we didn't find a same-day with previous message yet. auto lowestInOneDayItemBottom = -1; - auto dateCallback = [&](Message *view, int itemtop, int itembottom) { + auto dateCallback = [&](not_null view, int itemtop, int itembottom) { const auto item = view->data(); if (lowestInOneDayItemBottom < 0 && item->isInOneDayWithPrevious()) { lowestInOneDayItemBottom = itembottom - item->marginBottom(); @@ -183,7 +182,7 @@ void InnerWidget::enumerateDates(Method method) { // Call the template callback function that was passed // and return if it finished everything it needed. - if (!method(item, itemtop, dateTop)) { + if (!method(view, itemtop, dateTop)) { return false; } } @@ -660,7 +659,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } p.translate(0, -top); - enumerateUserpics([&](not_null message, int userpicTop) { + enumerateUserpics([&](not_null view, int userpicTop) { // stop the enumeration if the userpic is below the painted rect if (userpicTop >= clip.top() + clip.height()) { return false; @@ -668,6 +667,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { // paint the userpic if it intersects the painted rect if (userpicTop + st::msgPhotoSize > clip.top()) { + const auto message = view->data()->toHistoryMessage(); + Assert(message != nullptr); + message->from()->paintUserpicLeft(p, st::historyPhotoLeft, userpicTop, message->width(), st::msgPhotoSize); } return true; @@ -675,16 +677,17 @@ void InnerWidget::paintEvent(QPaintEvent *e) { auto dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top(); auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.); - enumerateDates([&](not_null item, int itemtop, int dateTop) { + enumerateDates([&](not_null view, int itemtop, int dateTop) { // stop the enumeration if the date is above the painted rect if (dateTop + dateHeight <= clip.top()) { return false; } - bool displayDate = item->displayDate(); - bool dateInPlace = displayDate; + const auto item = view->data(); + const auto displayDate = item->displayDate(); + auto dateInPlace = displayDate; if (dateInPlace) { - int correctDateTop = itemtop + st::msgServiceMargin.top(); + const auto correctDateTop = itemtop + st::msgServiceMargin.top(); dateInPlace = (dateTop < correctDateTop + dateHeight); } //bool noFloatingDate = (item->date.date() == lastDate && displayDate); @@ -1352,11 +1355,11 @@ void InnerWidget::updateSelected() { selectingText = false; } dragState = item->getState(itemPoint, request); - lnkhost = item; + lnkhost = view; if (!dragState.link && itemPoint.x() >= st::historyPhotoLeft && itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) { if (auto message = item->toHistoryMessage()) { if (message->hasFromPhoto()) { - enumerateUserpics([&dragState, &lnkhost, &point](not_null message, int userpicTop) -> bool { + enumerateUserpics([&](not_null view, int userpicTop) { // stop enumeration if the userpic is below our point if (userpicTop > point.y()) { return false; @@ -1364,8 +1367,11 @@ void InnerWidget::updateSelected() { // stop enumeration if we've found a userpic under the cursor if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { + const auto message = view->data()->toHistoryMessage(); + Assert(message != nullptr); + dragState.link = message->from()->openLink(); - lnkhost = message; + lnkhost = view; return false; } return true; @@ -1492,7 +1498,8 @@ void InnerWidget::performDrag() { // if (uponSelected && !Adaptive::OneColumn()) { // auto selectedState = getSelectionState(); // if (selectedState.count > 0 && selectedState.count == selectedState.canForwardCount) { - // mimeData->setData(qsl("application/x-td-forward-selected"), "1"); + // Auth().data().setMimeForwardIds(getSelectedItems()); + // mimeData->setData(qsl("application/x-td-forward"), "1"); // } // } // _controller->window()->launchDrag(std::move(mimeData)); @@ -1503,13 +1510,15 @@ void InnerWidget::performDrag() { // if (auto pressedItem = App::pressedItem()) { // pressedMedia = pressedItem->getMedia(); // if (_mouseCursorState == HistoryInDateCursorState || (pressedMedia && pressedMedia->dragItem())) { - // forwardMimeType = qsl("application/x-td-forward-pressed"); + // forwardMimeType = qsl("application/x-td-forward"); + // Auth().data().setMimeForwardIds(Auth().data().itemOrItsGroup(pressedItem)); // } // } // if (auto pressedLnkItem = App::pressedLinkItem()) { // if ((pressedMedia = pressedLnkItem->getMedia())) { // if (forwardMimeType.isEmpty() && pressedMedia->dragItemByHandler(pressedHandler)) { - // forwardMimeType = qsl("application/x-td-forward-pressed-link"); + // forwardMimeType = qsl("application/x-td-forward"); + // Auth().data().setMimeForwardIds({ 1, pressedLnkItem->fullId() }); // } // } // } diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 671dd1938..4d3e0213c 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -328,7 +328,7 @@ void HistoryInner::enumerateUserpics(Method method) { // Call the template callback function that was passed // and return if it finished everything it needed. - if (!method(message, userpicBottom - st::msgPhotoSize)) { + if (!method(view, userpicBottom - st::msgPhotoSize)) { return false; } } @@ -385,7 +385,7 @@ void HistoryInner::enumerateDates(Method method) { // Call the template callback function that was passed // and return if it finished everything it needed. - if (!method(item, itemtop, dateTop)) { + if (!method(view, itemtop, dateTop)) { return false; } } @@ -598,7 +598,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) { } if (mtop >= 0 || htop >= 0) { - enumerateUserpics([&p, &clip](not_null message, int userpicTop) { + enumerateUserpics([&](not_null view, int userpicTop) { // stop the enumeration if the userpic is below the painted rect if (userpicTop >= clip.top() + clip.height()) { return false; @@ -606,7 +606,13 @@ void HistoryInner::paintEvent(QPaintEvent *e) { // paint the userpic if it intersects the painted rect if (userpicTop + st::msgPhotoSize > clip.top()) { - message->displayFrom()->paintUserpicLeft(p, st::historyPhotoLeft, userpicTop, message->history()->width, st::msgPhotoSize); + const auto message = view->data()->toHistoryMessage(); + message->displayFrom()->paintUserpicLeft( + p, + st::historyPhotoLeft, + userpicTop, + message->history()->width, + st::msgPhotoSize); } return true; }); @@ -621,16 +627,17 @@ void HistoryInner::paintEvent(QPaintEvent *e) { //int showFloatingBefore = height() - 2 * (_visibleAreaBottom - _visibleAreaTop) - dateHeight; auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.); - enumerateDates([&p, &clip, scrollDateOpacity, dateHeight/*, lastDate, showFloatingBefore*/](not_null item, int itemtop, int dateTop) { + enumerateDates([&](not_null view, int itemtop, int dateTop) { // stop the enumeration if the date is above the painted rect if (dateTop + dateHeight <= clip.top()) { return false; } - bool displayDate = item->displayDate(); - bool dateInPlace = displayDate; + const auto item = view->data(); + const auto displayDate = item->displayDate(); + auto dateInPlace = displayDate; if (dateInPlace) { - int correctDateTop = itemtop + st::msgServiceMargin.top(); + const auto correctDateTop = itemtop + st::msgServiceMargin.top(); dateInPlace = (dateTop < correctDateTop + dateHeight); } //bool noFloatingDate = (item->date.date() == lastDate && displayDate); @@ -647,7 +654,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) { p.setOpacity(opacity); int dateY = /*noFloatingDate ? itemtop :*/ (dateTop - st::msgServiceMargin.top()); int width = item->history()->width; - if (auto date = item->Get()) { + if (const auto date = item->Get()) { date->paint(p, dateY, width); } else { HistoryView::ServiceMessagePainter::paintDate( @@ -1066,7 +1073,8 @@ void HistoryInner::performDrag() { if (uponSelected && !Adaptive::OneColumn()) { auto selectedState = getSelectionState(); if (selectedState.count > 0 && selectedState.count == selectedState.canForwardCount) { - mimeData->setData(qsl("application/x-td-forward-selected"), "1"); + Auth().data().setMimeForwardIds(getSelectedItems()); + mimeData->setData(qsl("application/x-td-forward"), "1"); } } _controller->window()->launchDrag(std::move(mimeData)); @@ -1077,13 +1085,15 @@ void HistoryInner::performDrag() { if (auto pressedItem = App::pressedItem()) { pressedMedia = pressedItem->data()->getMedia(); if (_mouseCursorState == HistoryInDateCursorState || (pressedMedia && pressedMedia->dragItem())) { - forwardMimeType = qsl("application/x-td-forward-pressed"); + Auth().data().setMimeForwardIds(Auth().data().itemOrItsGroup(pressedItem->data())); + forwardMimeType = qsl("application/x-td-forward"); } } if (const auto pressedLnkItem = _mouseActionItem) { if ((pressedMedia = pressedLnkItem->getMedia())) { if (forwardMimeType.isEmpty() && pressedMedia->dragItemByHandler(pressedHandler)) { - forwardMimeType = qsl("application/x-td-forward-pressed-link"); + Auth().data().setMimeForwardIds({ 1, pressedLnkItem->fullId() }); + forwardMimeType = qsl("application/x-td-forward"); } } } @@ -2267,16 +2277,17 @@ void HistoryInner::onUpdateSelected() { auto dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top(); auto scrollDateOpacity = _scrollDateOpacity.current(_scrollDateShown ? 1. : 0.); - enumerateDates([&](not_null item, int itemtop, int dateTop) { + enumerateDates([&](not_null view, int itemtop, int dateTop) { // stop enumeration if the date is above our point if (dateTop + dateHeight <= point.y()) { return false; } - bool displayDate = item->displayDate(); - bool dateInPlace = displayDate; + const auto item = view->data(); + const auto displayDate = item->displayDate(); + auto dateInPlace = displayDate; if (dateInPlace) { - int correctDateTop = itemtop + st::msgServiceMargin.top(); + const auto correctDateTop = itemtop + st::msgServiceMargin.top(); dateInPlace = (dateTop < correctDateTop + dateHeight); } @@ -2310,7 +2321,7 @@ void HistoryInner::onUpdateSelected() { nullptr, _scrollDateLink); _dragStateItem = App::histItemById(dragState.itemId); - lnkhost = item; + lnkhost = view; } } return false; @@ -2326,11 +2337,11 @@ void HistoryInner::onUpdateSelected() { } dragState = item->getState(m, request); _dragStateItem = App::histItemById(dragState.itemId); - lnkhost = item; + lnkhost = view; if (!dragState.link && m.x() >= st::historyPhotoLeft && m.x() < st::historyPhotoLeft + st::msgPhotoSize) { if (auto msg = item->toHistoryMessage()) { if (msg->hasFromPhoto()) { - enumerateUserpics([&](not_null message, int userpicTop) -> bool { + enumerateUserpics([&](not_null view, int userpicTop) -> bool { // stop enumeration if the userpic is below our point if (userpicTop > point.y()) { return false; @@ -2338,11 +2349,14 @@ void HistoryInner::onUpdateSelected() { // stop enumeration if we've found a userpic under the cursor if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { + const auto message = view->data()->toHistoryMessage(); + Assert(message != nullptr); + dragState = HistoryTextState( nullptr, message->displayFrom()->openLink()); _dragStateItem = App::histItemById(dragState.itemId); - lnkhost = message; + lnkhost = view; return false; } return true; diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index dce0d73e7..f79c999fe 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -160,7 +160,7 @@ private: // This function finds all userpics on the left that are displayed and calls template method // for each found userpic (from the top to the bottom) using enumerateItems() method. // - // Method has "bool (*Method)(not_null message, int userpicTop)" signature + // Method has "bool (*Method)(not_null view, int userpicTop)" signature // if it returns false the enumeration stops immidiately. template void enumerateUserpics(Method method); @@ -168,7 +168,7 @@ private: // This function finds all date elements that are displayed and calls template method // for each found date element (from the bottom to the top) using enumerateItems() method. // - // Method has "bool (*Method)(not_null item, int itemtop, int dateTop)" signature + // Method has "bool (*Method)(not_null view, int itemtop, int dateTop)" signature // if it returns false the enumeration stops immidiately. template void enumerateDates(Method method); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index aa75fdde4..cb6f1cda8 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -253,28 +253,6 @@ MTPDreplyKeyboardMarkup::Flags HistoryItem::replyKeyboardFlags() const { return MTPDreplyKeyboardMarkup_ClientFlag::f_zero | 0; } -void HistoryItem::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { - if (auto markup = Get()) { - if (markup->inlineKeyboard) { - markup->inlineKeyboard->clickHandlerActiveChanged(p, active); - } - } - // #TODO hoveredLinkItem - // App::hoveredLinkItem(active ? this : nullptr); - Auth().data().requestItemRepaint(this); -} - -void HistoryItem::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) { - if (auto markup = Get()) { - if (markup->inlineKeyboard) { - markup->inlineKeyboard->clickHandlerPressedChanged(p, pressed); - } - } - // #TODO hoveredLinkItem - // App::pressedLinkItem(pressed ? this : nullptr); - Auth().data().requestItemRepaint(this); -} - void HistoryItem::addLogEntryOriginal(WebPageId localId, const QString &label, const TextWithEntities &content) { Expects(isLogEntry()); AddComponents(HistoryMessageLogEntryOriginal::Bit()); diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index cf75bdee6..02b8e4fd5 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -173,8 +173,7 @@ inline TextSelection shiftSelection(TextSelection selection, const Text &byText) class HistoryItem : public HistoryElement - , public RuntimeComposer - , public ClickHandlerHost { + , public RuntimeComposer { public: int resizeGetHeight(int newWidth) { if (_flags & MTPDmessage_ClientFlag::f_pending_init_dimensions) { @@ -300,10 +299,6 @@ public: return selection; } - // ClickHandlerHost interface - void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override; - void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override; - virtual bool serviceMsg() const { return false; } diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index 34900a913..77db04b08 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -138,7 +138,9 @@ void HistoryFileMedia::thumbAnimationCallback() { Auth().data().requestItemRepaint(_parent); } -void HistoryFileMedia::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) { +void HistoryFileMedia::clickHandlerPressedChanged( + const ClickHandlerPtr &handler, + bool pressed) { Auth().data().requestItemRepaint(_parent); } diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 89665071c..7a10ad738 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -270,12 +270,9 @@ void FastShareMessage(not_null item) { MessageIdsList msgIds; base::flat_set requests; }; - const auto data = std::make_shared(item->history()->peer, [&] { - if (const auto group = item->getFullGroup()) { - return Auth().data().groupToIds(group); - } - return MessageIdsList(1, item->fullId()); - }()); + const auto data = std::make_shared( + item->history()->peer, + Auth().data().itemOrItsGroup(item)); const auto isGroup = (item->getFullGroup() != nullptr); const auto isGame = item->getMessageBot() && item->getMedia() @@ -2521,21 +2518,6 @@ TextSelection HistoryMessage::adjustSelection(TextSelection selection, TextSelec return result; } -void HistoryMessage::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { - HistoryItem::clickHandlerActiveChanged(p, active); - if (_media) { - _media->clickHandlerActiveChanged(p, active); - } -} - -void HistoryMessage::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) { - HistoryItem::clickHandlerPressedChanged(p, pressed); - if (_media) { - // HistoryGroupedMedia overrides HistoryItem App::pressedLinkItem(). - _media->clickHandlerPressedChanged(p, pressed); - } -} - QString HistoryMessage::notificationHeader() const { return (!_history->peer->isUser() && !isPost()) ? from()->name : QString(); } diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h index 5f26e8f3d..7dcae1064 100644 --- a/Telegram/SourceFiles/history/history_message.h +++ b/Telegram/SourceFiles/history/history_message.h @@ -182,10 +182,6 @@ public: TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override; - // ClickHandlerHost interface - void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override; - void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override; - QString notificationHeader() const override; void applyEdition(const MTPDmessage &message) override; diff --git a/Telegram/SourceFiles/history/history_service.cpp b/Telegram/SourceFiles/history/history_service.cpp index 3ffc7f5a7..f787f6bf6 100644 --- a/Telegram/SourceFiles/history/history_service.cpp +++ b/Telegram/SourceFiles/history/history_service.cpp @@ -717,16 +717,6 @@ void HistoryService::createFromMtp(const MTPDmessageService &message) { setMessageByAction(message.vaction); } -void HistoryService::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { - if (_media) _media->clickHandlerActiveChanged(p, active); - HistoryItem::clickHandlerActiveChanged(p, active); -} - -void HistoryService::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) { - if (_media) _media->clickHandlerPressedChanged(p, pressed); - HistoryItem::clickHandlerPressedChanged(p, pressed); -} - void HistoryService::applyEdition(const MTPDmessageService &message) { clearDependency(); UpdateComponents(0); diff --git a/Telegram/SourceFiles/history/history_service.h b/Telegram/SourceFiles/history/history_service.h index 8919bdf28..0fb191b40 100644 --- a/Telegram/SourceFiles/history/history_service.h +++ b/Telegram/SourceFiles/history/history_service.h @@ -88,9 +88,6 @@ public: return _text.adjustSelection(selection, type); } - void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override; - void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override; - void applyEdition(const MTPDmessageService &message) override; TimeMs getSelfDestructIn(TimeMs now) override; diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index dadb47e67..da6b448ae 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -125,7 +125,7 @@ void ListWidget::enumerateUserpics(Method method) { // -1 means we didn't find an attached to next message yet. int lowestAttachedItemTop = -1; - auto userpicCallback = [this, &lowestAttachedItemTop, &method](Message *view, int itemtop, int itembottom) { + auto userpicCallback = [&](not_null view, int itemtop, int itembottom) { // Skip all service messages. auto message = view->data()->toHistoryMessage(); if (!message) return true; @@ -149,7 +149,7 @@ void ListWidget::enumerateUserpics(Method method) { // Call the template callback function that was passed // and return if it finished everything it needed. - if (!method(message, userpicBottom - st::msgPhotoSize)) { + if (!method(view, userpicBottom - st::msgPhotoSize)) { return false; } } @@ -171,7 +171,7 @@ void ListWidget::enumerateDates(Method method) { // -1 means we didn't find a same-day with previous message yet. auto lowestInOneDayItemBottom = -1; - auto dateCallback = [this, &lowestInOneDayItemBottom, &method](Message *view, int itemtop, int itembottom) { + auto dateCallback = [&](not_null view, int itemtop, int itembottom) { const auto item = view->data(); if (lowestInOneDayItemBottom < 0 && item->isInOneDayWithPrevious()) { lowestInOneDayItemBottom = itembottom - item->marginBottom(); @@ -192,7 +192,7 @@ void ListWidget::enumerateDates(Method method) { // Call the template callback function that was passed // and return if it finished everything it needed. - if (!method(item, itemtop, dateTop)) { + if (!method(view, itemtop, dateTop)) { return false; } } @@ -586,7 +586,7 @@ void ListWidget::paintEvent(QPaintEvent *e) { } p.translate(0, -top); - enumerateUserpics([&p, &clip](not_null message, int userpicTop) { + enumerateUserpics([&](not_null view, int userpicTop) { // stop the enumeration if the userpic is below the painted rect if (userpicTop >= clip.top() + clip.height()) { return false; @@ -594,23 +594,32 @@ void ListWidget::paintEvent(QPaintEvent *e) { // paint the userpic if it intersects the painted rect if (userpicTop + st::msgPhotoSize > clip.top()) { - message->from()->paintUserpicLeft(p, st::historyPhotoLeft, userpicTop, message->width(), st::msgPhotoSize); + const auto message = view->data()->toHistoryMessage(); + Assert(message != nullptr); + + message->from()->paintUserpicLeft( + p, + st::historyPhotoLeft, + userpicTop, + message->width(), + st::msgPhotoSize); } return true; }); auto dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top(); auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.); - enumerateDates([&p, &clip, scrollDateOpacity, dateHeight/*, lastDate, showFloatingBefore*/](not_null item, int itemtop, int dateTop) { + enumerateDates([&](not_null view, int itemtop, int dateTop) { // stop the enumeration if the date is above the painted rect if (dateTop + dateHeight <= clip.top()) { return false; } - bool displayDate = item->displayDate(); - bool dateInPlace = displayDate; + const auto item = view->data(); + const auto displayDate = item->displayDate(); + auto dateInPlace = displayDate; if (dateInPlace) { - int correctDateTop = itemtop + st::msgServiceMargin.top(); + const auto correctDateTop = itemtop + st::msgServiceMargin.top(); dateInPlace = (dateTop < correctDateTop + dateHeight); } //bool noFloatingDate = (item->date.date() == lastDate && displayDate); @@ -627,7 +636,7 @@ void ListWidget::paintEvent(QPaintEvent *e) { p.setOpacity(opacity); int dateY = /*noFloatingDate ? itemtop :*/ (dateTop - st::msgServiceMargin.top()); int width = item->width(); - if (auto date = item->Get()) { + if (const auto date = item->Get()) { date->paint(p, dateY, width); } else { ServiceMessagePainter::paintDate( @@ -1178,11 +1187,11 @@ void ListWidget::updateSelected() { selectingText = false; } dragState = item->getState(itemPoint, request); - lnkhost = item; + lnkhost = view; if (!dragState.link && itemPoint.x() >= st::historyPhotoLeft && itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) { if (auto message = item->toHistoryMessage()) { if (message->hasFromPhoto()) { - enumerateUserpics([&dragState, &lnkhost, &point](not_null message, int userpicTop) -> bool { + enumerateUserpics([&](not_null view, int userpicTop) -> bool { // stop enumeration if the userpic is below our point if (userpicTop > point.y()) { return false; @@ -1190,8 +1199,11 @@ void ListWidget::updateSelected() { // stop enumeration if we've found a userpic under the cursor if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { + const auto message = view->data()->toHistoryMessage(); + Assert(message != nullptr); + dragState.link = message->from()->openLink(); - lnkhost = message; + lnkhost = view; return false; } return true; @@ -1316,7 +1328,8 @@ void ListWidget::performDrag() { // if (uponSelected && !Adaptive::OneColumn()) { // auto selectedState = getSelectionState(); // if (selectedState.count > 0 && selectedState.count == selectedState.canForwardCount) { - // mimeData->setData(qsl("application/x-td-forward-selected"), "1"); + // Auth().data().setMimeForwardIds(getSelectedItems()); + // mimeData->setData(qsl("application/x-td-forward"), "1"); // } // } // _controller->window()->launchDrag(std::move(mimeData)); @@ -1327,13 +1340,15 @@ void ListWidget::performDrag() { // if (auto pressedItem = App::pressedItem()) { // pressedMedia = pressedItem->getMedia(); // if (_mouseCursorState == HistoryInDateCursorState || (pressedMedia && pressedMedia->dragItem())) { - // forwardMimeType = qsl("application/x-td-forward-pressed"); + // Auth().data().setMimeForwardIds(Auth().data().itemOrItsGroup(pressedItem)); + // forwardMimeType = qsl("application/x-td-forward"); // } // } // if (auto pressedLnkItem = App::pressedLinkItem()) { // if ((pressedMedia = pressedLnkItem->getMedia())) { // if (forwardMimeType.isEmpty() && pressedMedia->dragItemByHandler(pressedHandler)) { - // forwardMimeType = qsl("application/x-td-forward-pressed-link"); + // Auth().data().setMimeForwardIds({ 1, pressedLnkItem->fullId() }); + // forwardMimeType = qsl("application/x-td-forward"); // } // } // } diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index d56d4694b..997f78f86 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -7,6 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/history_view_message.h" +#include "history/history_item_components.h" +#include "history/history_media.h" +#include "data/data_session.h" +#include "auth_session.h" + namespace HistoryView { Message::Message(not_null data, Context context) @@ -62,6 +67,36 @@ Message *Message::nextInBlocks() const { return nullptr; } +void Message::clickHandlerActiveChanged( + const ClickHandlerPtr &handler, + bool active) { + if (const auto markup = _data->Get()) { + if (const auto keyboard = markup->inlineKeyboard.get()) { + keyboard->clickHandlerActiveChanged(handler, active); + } + } + App::hoveredLinkItem(active ? this : nullptr); + Auth().data().requestItemRepaint(_data); + if (const auto media = _data->getMedia()) { + media->clickHandlerActiveChanged(handler, active); + } +} + +void Message::clickHandlerPressedChanged( + const ClickHandlerPtr &handler, + bool pressed) { + if (const auto markup = _data->Get()) { + if (const auto keyboard = markup->inlineKeyboard.get()) { + keyboard->clickHandlerPressedChanged(handler, pressed); + } + } + App::pressedLinkItem(pressed ? this : nullptr); + Auth().data().requestItemRepaint(_data); + if (const auto media = _data->getMedia()) { + media->clickHandlerPressedChanged(handler, pressed); + } +} + Message::~Message() { App::messageViewDestroyed(this); } diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 357414fb9..cd8578b22 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -55,6 +55,14 @@ public: Message *previousInBlocks() const; Message *nextInBlocks() const; + // ClickHandlerHost interface + void clickHandlerActiveChanged( + const ClickHandlerPtr &handler, + bool active) override; + void clickHandlerPressedChanged( + const ClickHandlerPtr &handler, + bool pressed) override; + ~Message(); private: diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index b45ec413f..f099dd7b0 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -1905,7 +1905,8 @@ void ListWidget::performDrag() { // if (uponSelected && !Adaptive::OneColumn()) { // auto selectedState = getSelectionState(); // if (selectedState.count > 0 && selectedState.count == selectedState.canForwardCount) { - // mimeData->setData(qsl("application/x-td-forward-selected"), "1"); + // Auth().data().setMimeForwardIds(collectSelectedIds()); + // mimeData->setData(qsl("application/x-td-forward"), "1"); // } // } // _controller->parentController()->window()->launchDrag(std::move(mimeData)); @@ -1916,13 +1917,15 @@ void ListWidget::performDrag() { // if (auto pressedItem = _pressState.layout) { // pressedMedia = pressedItem->getMedia(); // if (_mouseCursorState == HistoryInDateCursorState || (pressedMedia && pressedMedia->dragItem())) { - // forwardMimeType = qsl("application/x-td-forward-pressed"); + // Auth().data().setMimeForwardIds(Auth().data().itemOrItsGroup(pressedItem)); + // forwardMimeType = qsl("application/x-td-forward"); // } // } // if (auto pressedLnkItem = App::pressedLinkItem()) { // if ((pressedMedia = pressedLnkItem->getMedia())) { // if (forwardMimeType.isEmpty() && pressedMedia->dragItemByHandler(pressedHandler)) { - // forwardMimeType = qsl("application/x-td-forward-pressed-link"); + // Auth().data().setMimeForwardIds({ 1, pressedLnkItem->fullId() }); + // forwardMimeType = qsl("application/x-td-forward"); // } // } // } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 07dcbde77..1c2a63d67 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -590,44 +590,6 @@ void MainWidget::finishFloatPlayerDrag(not_null instance, bool closed) { } } -bool MainWidget::setForwardDraft(PeerId peerId, ForwardWhatMessages what) { - const auto collect = [&]() -> MessageIdsList { - if (what == ForwardSelectedMessages) { - return _history->getSelectedItems(); - } - auto item = (HistoryItem*)nullptr; - if (what == ForwardPressedMessage) { - item = App::pressedItem() - ? App::pressedItem()->data().get() - : nullptr; - if (const auto group = item ? item->getFullGroup() : nullptr) { - if (item->id > 0) { - return Auth().data().groupToIds(group); - } - } - } else if (what == ForwardPressedLinkMessage) { - item = App::pressedLinkItem() - ? App::pressedLinkItem()->data().get() - : nullptr; - } - if (item && item->toHistoryMessage() && item->id > 0) { - return { 1, item->fullId() }; - } - return {}; - }; - const auto result = setForwardDraft(peerId, collect()); - if (!result) { - if (what == ForwardPressedMessage || what == ForwardPressedLinkMessage) { - // We've already released the mouse button, so the forwarding is cancelled. - if (_hider) { - _hider->startHide(); - noHider(_hider); - } - } - } - return result; -} - bool MainWidget::setForwardDraft(PeerId peerId, MessageIdsList &&items) { Expects(peerId != 0); const auto peer = App::peer(peerId); @@ -791,14 +753,19 @@ bool MainWidget::onSendPaths(const PeerId &peerId) { return _history->confirmSendingFiles(cSendPaths()); } -void MainWidget::onFilesOrForwardDrop(const PeerId &peerId, const QMimeData *data) { +void MainWidget::onFilesOrForwardDrop( + const PeerId &peerId, + const QMimeData *data) { Expects(peerId != 0); - if (data->hasFormat(qsl("application/x-td-forward-selected"))) { - setForwardDraft(peerId, ForwardSelectedMessages); - } else if (data->hasFormat(qsl("application/x-td-forward-pressed-link"))) { - setForwardDraft(peerId, ForwardPressedLinkMessage); - } else if (data->hasFormat(qsl("application/x-td-forward-pressed"))) { - setForwardDraft(peerId, ForwardPressedMessage); + + if (data->hasFormat(qsl("application/x-td-forward"))) { + if (!setForwardDraft(peerId, Auth().data().takeMimeForwardIds())) { + // We've already released the mouse button, so the forwarding is cancelled. + if (_hider) { + _hider->startHide(); + noHider(_hider); + } + } } else { auto peer = App::peer(peerId); if (!peer->canWrite()) { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 004e29630..8d1738b81 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -175,7 +175,6 @@ public: void inlineSwitchLayer(const QString &botAndQuery); void hiderLayer(object_ptr h); void noHider(HistoryHider *destroyed); - bool setForwardDraft(PeerId peer, ForwardWhatMessages what); bool setForwardDraft(PeerId peer, MessageIdsList &&items); bool shareUrl( not_null peer, diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index 52bf2a597..c9bf134c4 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -120,8 +120,6 @@ ItemBase::ItemBase(not_null parent) : _parent(parent) { void ItemBase::clickHandlerActiveChanged( const ClickHandlerPtr &action, bool active) { - // #TODO hoveredLinkItem -// App::hoveredLinkItem(active ? _parent.get() : nullptr); Auth().data().requestItemRepaint(_parent); if (_check) { _check->setActive(active); @@ -131,8 +129,6 @@ void ItemBase::clickHandlerActiveChanged( void ItemBase::clickHandlerPressedChanged( const ClickHandlerPtr &action, bool pressed) { - // #TODO pressedLinkItem -// App::pressedLinkItem(pressed ? _parent.get() : nullptr); Auth().data().requestItemRepaint(_parent); if (_check) { _check->setPressed(pressed); diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp index f46affe6b..97d9943c9 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp +++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp @@ -135,10 +135,7 @@ PreparedFile &PreparedFile::operator=(PreparedFile &&other) = default; PreparedFile::~PreparedFile() = default; MimeDataState ComputeMimeDataState(const QMimeData *data) { - if (!data - || data->hasFormat(qsl("application/x-td-forward-selected")) - || data->hasFormat(qsl("application/x-td-forward-pressed")) - || data->hasFormat(qsl("application/x-td-forward-pressed-link"))) { + if (!data || data->hasFormat(qsl("application/x-td-forward"))) { return MimeDataState::None; }