From 6a2b0291389fa32bd70a2c03119890275d5e0681 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 24 May 2023 12:20:12 +0200 Subject: [PATCH] QLabel: always show the context menu created by the control Amends e718818745e6db8df09ea55c4071e116f00851c9, after which a context menu was only shown if the format was rich text and there was a link at the position of the click. We always want to leave it up to the control to create a context menu, so only return early if there is no control. The control will then respect content at the position (i.e. link or not) and text interaction flags, and create the menu based on that. I.e. a rich text label with selectable text should still show "Select All" in the context menu, also if not clicking on a link. Add a test case to verify that the context menu event got accepted as expected, which indicates that the label showed a menu. Pick-to: 6.5 Change-Id: Ib2b36286e4f1253d10489b5add83e8cdd7197a06 Reviewed-by: Oliver Eftevaag --- src/widgets/widgets/qlabel.cpp | 7 +--- .../widgets/widgets/qlabel/tst_qlabel.cpp | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 4d1c4ebb741..bc40b0f4424 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -1652,15 +1652,10 @@ QPoint QLabelPrivate::layoutPoint(const QPoint& p) const #ifndef QT_NO_CONTEXTMENU QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos) { - if (!control || effectiveTextFormat == Qt::PlainText) + if (!control) return nullptr; const QPoint p = layoutPoint(pos); - QString linkToCopy = control->document()->documentLayout()->anchorAt(p); - - if (linkToCopy.isEmpty()) - return nullptr; - return control->createStandardContextMenu(p, q_func()); } #endif diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp index 2775e2c683b..9193a34c45c 100644 --- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp +++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp @@ -77,6 +77,8 @@ private Q_SLOTS: #ifndef QT_NO_CONTEXTMENU void taskQTBUG_7902_contextMenuCrash(); + void contextMenu_data(); + void contextMenu(); #endif void taskQTBUG_48157_dprPixmap(); @@ -561,6 +563,43 @@ void tst_QLabel::taskQTBUG_7902_contextMenuCrash() QTest::qWait(350); // No crash, it's allright. } + +void tst_QLabel::contextMenu_data() +{ + QTest::addColumn("text"); + QTest::addColumn("interactionFlags"); + QTest::addColumn("showsContextMenu"); + + QTest::addRow("Read-only") << "Plain Text" + << Qt::NoTextInteraction + << false; + QTest::addRow("Selectable") << "Plain Text" + << Qt::TextEditorInteraction + << true; + QTest::addRow("Link") << "Rich text with link" + << Qt::TextBrowserInteraction + << true; + QTest::addRow("Rich text") << "Rich text without link" + << Qt::TextBrowserInteraction + << true; +} + +void tst_QLabel::contextMenu() +{ + QFETCH(QString, text); + QFETCH(Qt::TextInteractionFlag, interactionFlags); + QFETCH(bool, showsContextMenu); + + QLabel label(text); + label.setTextInteractionFlags(interactionFlags); + label.show(); + QVERIFY(QTest::qWaitForWindowExposed(&label)); + + const QPoint menuPosition = label.rect().center(); + QContextMenuEvent cme(QContextMenuEvent::Mouse, menuPosition, label.mapToGlobal(menuPosition)); + QApplication::sendEvent(&label, &cme); + QCOMPARE(cme.isAccepted(), showsContextMenu); +} #endif void tst_QLabel::taskQTBUG_48157_dprPixmap()