Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
6.9.1
-
None
-
Manjaro GNU/Linux x64, X11, Xfce
Description
The member function createStandardContextMenu(const QPoint &position) of both QTextEdit and QPlainTextEdit is documented to take "the position in document coordinates".
The documentation is correct for QTextEdit, but translating from the viewport coordinates provided by the signal QTextEdit::customContextMenuRequested() to the document coordinates is not trivial and requires copying implementation ideas from QTextEditPrivate::horizontalOffset and QTextEditPrivate::verticalOffset (poor usability). For example:
void MyWidget::textViewContextMenuRequested(const QPoint& viewportPosition) { const auto horizontalScrollBar = textEdit->horizontalScrollBar(); const auto horizontalOffset = textEdit->isRightToLeft() ? horizontalScrollBar->maximum() - horizontalScrollBar->value() : horizontalScrollBar->value(); const auto verticalOffset = textEdit->verticalScrollBar()->value(); const auto documentPosition = viewportPosition + QPoint{horizontalOffset, verticalOffset}; auto* popup = textEdit->createStandardContextMenu(documentPosition);
Ideally, either createStandardContextMenu() should take the position in the viewport coordinates or QTextEdit should provide coordinate conversion API.
As for QPlainTextEdit, due to the use of horizontalOffset() and verticalOffset() in QPlainTextEdit::anchorAt, its createStandardContextMenu() actually expects the position in the viewport coordinates. This is convenient for a user slot connected to QPlainTextEdit::customContextMenuRequested() because the already available position in the viewport coordinates just needs to be forwarded to createStandardContextMenu(). However, when createStandardContextMenu() is invoked from the standard context menu event handler of QPlainTextEdit (when user code does not override the default context menu policy and does not override QPlainTextEdit::contextMenuEvent()), its coordinates are translated to the document coordinates as well, which results in repeated/duplicate coordinate translation and incorrect end result (bug). For example, the default context menu handler of QPlainTextEdit incorrectly determines whether or not the user right-clicks a link when the scroll bars are not in their top-left-most states.
I have tested this behavior in my application as follows:
// configure the Q(Plain|)TextEdit instance textEdit->setTextInteractionFlags(textEdit->textInteractionFlags() | Qt::LinksAccessibleByMouse); textEdit->setWordWrapMode(QTextOption::WordWrap); // optional textEdit->setLayoutDirection(Qt::RightToLeft); // optional // insert several HTML links among lots of plain text const auto line = QStringLiteral("<a href=\"https://example.com\">loooong link</a>"); QTextDocument *document = textEdit->document(); QTextCursor cursor(document); cursor.movePosition(QTextCursor::End); cursor.insertHtml(line);