Make HistoryView::Message a ClickHandlerHost.

This commit is contained in:
John Preston 2018-01-11 18:51:59 +03:00
parent 062b0b2165
commit 4740d44159
22 changed files with 185 additions and 189 deletions

View file

@ -525,12 +525,6 @@ inline int ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) {
return qMax(qMin(static_cast<int>(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);

View file

@ -164,6 +164,13 @@ MessageIdsList Session::groupToIds(
return result;
}
MessageIdsList Session::itemOrItsGroup(not_null<HistoryItem*> 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

View file

@ -142,6 +142,7 @@ public:
HistoryItemsList idsToItems(const MessageIdsList &ids) const;
MessageIdsList itemsToIds(const HistoryItemsList &items) const;
MessageIdsList groupToIds(not_null<HistoryMessageGroup*> group) const;
MessageIdsList itemOrItsGroup(not_null<HistoryItem*> item) const;
int pinnedDialogsCount() const;
const std::deque<Dialogs::Key> &pinnedDialogsOrder() const;
@ -155,6 +156,9 @@ public:
not_null<Data::Feed*> 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<Dialogs::Key> _pinnedDialogs;
base::flat_map<FeedId, std::unique_ptr<Data::Feed>> _feeds;
MessageIdsList _mimeForwardIds;
rpl::lifetime _lifetime;
};

View file

@ -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();

View file

@ -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<Message*> 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<Message*> 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<HistoryMessage*> message, int userpicTop) {
enumerateUserpics([&](not_null<Message*> 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<HistoryItem*> item, int itemtop, int dateTop) {
enumerateDates([&](not_null<Message*> 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<HistoryMessage*> message, int userpicTop) -> bool {
enumerateUserpics([&](not_null<Message*> 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() });
// }
// }
// }

View file

@ -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<HistoryMessage*> message, int userpicTop) {
enumerateUserpics([&](not_null<Message*> 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<HistoryItem*> item, int itemtop, int dateTop) {
enumerateDates([&](not_null<Message*> 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<HistoryMessageDate>()) {
if (const auto date = item->Get<HistoryMessageDate>()) {
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<HistoryItem*> item, int itemtop, int dateTop) {
enumerateDates([&](not_null<Message*> 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<HistoryMessage*> message, int userpicTop) -> bool {
enumerateUserpics([&](not_null<Message*> 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;

View file

@ -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<HistoryMessage*> message, int userpicTop)" signature
// Method has "bool (*Method)(not_null<Message*> view, int userpicTop)" signature
// if it returns false the enumeration stops immidiately.
template <typename Method>
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<HistoryItem*> item, int itemtop, int dateTop)" signature
// Method has "bool (*Method)(not_null<Message*> view, int itemtop, int dateTop)" signature
// if it returns false the enumeration stops immidiately.
template <typename Method>
void enumerateDates(Method method);

View file

@ -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<HistoryMessageReplyMarkup>()) {
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<HistoryMessageReplyMarkup>()) {
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());

View file

@ -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;
}

View file

@ -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);
}

View file

@ -270,12 +270,9 @@ void FastShareMessage(not_null<HistoryItem*> item) {
MessageIdsList msgIds;
base::flat_set<mtpRequestId> requests;
};
const auto data = std::make_shared<ShareData>(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<ShareData>(
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();
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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<Message*> 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<Message*> 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<HistoryMessage*> message, int userpicTop) {
enumerateUserpics([&](not_null<Message*> 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<HistoryItem*> item, int itemtop, int dateTop) {
enumerateDates([&](not_null<Message*> 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<HistoryMessageDate>()) {
if (const auto date = item->Get<HistoryMessageDate>()) {
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<HistoryMessage*> message, int userpicTop) -> bool {
enumerateUserpics([&](not_null<Message*> 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");
// }
// }
// }

View file

@ -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<HistoryItem*> 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<HistoryMessageReplyMarkup>()) {
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<HistoryMessageReplyMarkup>()) {
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);
}

View file

@ -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:

View file

@ -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");
// }
// }
// }

View file

@ -590,44 +590,6 @@ void MainWidget::finishFloatPlayerDrag(not_null<Float*> 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()) {

View file

@ -175,7 +175,6 @@ public:
void inlineSwitchLayer(const QString &botAndQuery);
void hiderLayer(object_ptr<HistoryHider> h);
void noHider(HistoryHider *destroyed);
bool setForwardDraft(PeerId peer, ForwardWhatMessages what);
bool setForwardDraft(PeerId peer, MessageIdsList &&items);
bool shareUrl(
not_null<PeerData*> peer,

View file

@ -120,8 +120,6 @@ ItemBase::ItemBase(not_null<HistoryItem*> 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);

View file

@ -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;
}