From c3468987cb44baf81b7782b3b90c4f5a527e740e Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 7 Oct 2026 17:33:26 +0200 Subject: [PATCH] Handle poll questions rendered as a standalone emoji --- tools/chatgui/src/messagedelegate.cpp | 3 ++- tools/chatgui/tests/test_invite_links.cpp | 29 ++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tools/chatgui/src/messagedelegate.cpp b/tools/chatgui/src/messagedelegate.cpp index 6d90a2f0..415daabf 100644 --- a/tools/chatgui/src/messagedelegate.cpp +++ b/tools/chatgui/src/messagedelegate.cpp @@ -144,7 +144,8 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const bool onReaction = mouse->button() == Qt::LeftButton && reaction != -2; const bool onAvatar=mouse->button()==Qt::LeftButton && !L.narrow && L.avatarRect.contains(mouse->pos()-option.rect.topLeft()); const bool onPoll = index.data(MsgContentTypeRole).toString() == "poll" - && !index.data(MsgChannelIdRole).toString().startsWith("dm:") && L.bubbleRect.contains(point) + && !index.data(MsgChannelIdRole).toString().startsWith("dm:") + && (L.bubbleRect.contains(point) || L.emojiArea.contains(point)) && (!L.reactionHeart.isValid() || point.y() < L.reactionHeart.top()); if (event->type()==QEvent::MouseButtonPress) { m_reactionPress = onReaction ? index : QModelIndex(); m_pressedReaction = reaction; m_reactionPressPosition = mouse->pos(); diff --git a/tools/chatgui/tests/test_invite_links.cpp b/tools/chatgui/tests/test_invite_links.cpp index 60d275c5..ced15dbe 100644 --- a/tools/chatgui/tests/test_invite_links.cpp +++ b/tools/chatgui/tests/test_invite_links.cpp @@ -18,6 +18,7 @@ extern "C" { class InviteLinksTest : public QObject { Q_OBJECT private slots: + void initTestCase() { debug_config_init(); } void pollLeftClick_data() { QTest::addColumn("outgoing"); QTest::addColumn("width"); for (bool outgoing : {false, true}) for (int width : {280, 600}) @@ -38,7 +39,7 @@ private slots: ChatView view; MessageDelegate delegate; view.setModel(&model); view.setItemDelegate(&delegate); view.setFrameShape(QFrame::NoFrame); view.setSelectionMode(QAbstractItemView::NoSelection); view.setEditTriggers(QAbstractItemView::NoEditTriggers); - QFont font = view.font(); font.setPixelSize(14); view.setFont(font); + QFont font = view.font(); font.setPointSize(10); view.setFont(font); view.resize(width, 400); view.show(); QTest::qWait(20); QSignalSpy polls(&delegate, &MessageDelegate::pollRequested); const QModelIndex index = model.index(0, 0); @@ -76,6 +77,32 @@ private slots: QCOMPARE(polls.count(), 2); } + void pollEmojiQuestion() { + QStandardItemModel model; + auto* message = new QStandardItem; + const QString key(64, 'a'); + message->setData(QString::fromUtf8("😀"), MsgTextRole); message->setData("poll", MsgContentTypeRole); + message->setData("1001", MsgChannelIdRole); message->setData(key, MsgMessageKeyRole); + model.appendRow(message); + ChatView view; MessageDelegate delegate; + view.setModel(&model); view.setItemDelegate(&delegate); view.setFrameShape(QFrame::NoFrame); + view.setSelectionMode(QAbstractItemView::NoSelection); view.resize(300, 250); view.show(); QTest::qWait(20); + QStyleOptionViewItem option; option.initFrom(&view); option.widget = &view; option.rect = view.visualRect(model.index(0, 0)); + const QColor background(1, 2, 3); + QImage image(option.rect.size(), QImage::Format_ARGB32); image.fill(background); + QPainter painter(&image); delegate.paint(&painter, option, model.index(0, 0)); painter.end(); + qint64 xTotal = 0, yTotal = 0, pixels = 0; + for (int y = 0; y < image.height(); ++y) for (int x = 0; x < image.width(); ++x) { + if (image.pixelColor(x, y) == background) continue; + xTotal += x; yTotal += y; ++pixels; + } + QVERIFY(pixels > 0); + QSignalSpy polls(&delegate, &MessageDelegate::pollRequested); + const QPoint question(int(xTotal / pixels), int(yTotal / pixels)); // Нажимаем на реально нарисованный вопрос. + QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, question); + QCOMPARE(polls.count(), 1); QCOMPARE(polls.first().first().toString(), key); + } + void reactionFooter_data() { QTest::addColumn("type"); QTest::addColumn("outgoing"); QTest::addColumn("width"); for (const auto& type : {"text/plain", "audio/opus", "image/png", "video/mp4", "application/octet-stream", "poll"})