diff options
Diffstat (limited to 'tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp')
-rw-r--r-- | tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp | 99 |
1 files changed, 92 insertions, 7 deletions
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 7cdaf6819e..66d1d29ae6 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -101,6 +101,8 @@ public: tst_qquicktextedit(); private slots: + void initTestCase() override; + void cleanup(); void text(); void width(); @@ -182,6 +184,7 @@ private slots: void implicitSizeBinding(); void largeTextObservesViewport_data(); void largeTextObservesViewport(); + void renderingAroundSelection(); void signal_editingfinished(); @@ -369,6 +372,56 @@ tst_qquicktextedit::tst_qquicktextedit() // } +class NodeCheckerTextEdit : public QQuickTextEdit +{ +public: + NodeCheckerTextEdit(QQuickItem *parent = nullptr) : QQuickTextEdit(parent) {} + + void populateLinePositions(QSGNode *node) + { + linePositions.clear(); + lastLinePosition = 0; + QSGNode *ch = node->firstChild(); + while (ch != node->lastChild()) { + QCOMPARE(ch->type(), QSGNode::TransformNodeType); + QSGTransformNode *tn = static_cast<QSGTransformNode *>(ch); + int y = 0; + if (!tn->matrix().isIdentity()) + y = tn->matrix().column(3).y(); + if (tn->childCount() == 0) { + // A TransformNode with no children is a waste of memory. + // So far, QQuickTextEdit still creates a couple of extras. + qCDebug(lcTests) << "ignoring leaf TransformNode" << tn << "@ y" << y; + } else { + qCDebug(lcTests) << "child" << tn << "@ y" << y << "has children" << tn->childCount(); + if (!linePositions.contains(y)) { + linePositions.append(y); + lastLinePosition = qMax(lastLinePosition, y); + } + } + ch = ch->nextSibling(); + } + std::sort(linePositions.begin(), linePositions.end()); + } + + QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) override + { + QSGNode *ret = QQuickTextEdit::updatePaintNode(node, data); + qCDebug(lcTests) << "updated root node" << ret; + populateLinePositions(ret); + return ret; + } + + QList<int> linePositions; + int lastLinePosition; +}; + +void tst_qquicktextedit::initTestCase() +{ + QQmlDataTest::initTestCase(); + qmlRegisterType<NodeCheckerTextEdit>("Qt.test", 1, 0, "NodeCheckerTextEdit"); +} + void tst_qquicktextedit::cleanup() { // ensure not even skipped tests with custom input context leave it dangling @@ -935,7 +988,7 @@ void tst_qquicktextedit::hAlignVisual() // Try to check whether alignment works by checking the number of black // pixels in the thirds of the grabbed image. - const int windowWidth = 200; + const int windowWidth = view.width(); const int textWidth = qCeil(text->implicitWidth()); QVERIFY2(textWidth < windowWidth, "System font too large."); const int sectionWidth = textWidth / 3; @@ -983,7 +1036,7 @@ void tst_qquicktextedit::hAlignVisual() { // Left Align QImage image = view.grabWindow(); - int x = qCeil(text->implicitWidth()); + int x = qCeil(text->implicitWidth() * view.devicePixelRatio()); int left = numberOfNonWhitePixels(0, x, image); int right = numberOfNonWhitePixels(x, image.width() - x, image); QVERIFY2(left > 0, msgNotGreaterThan(left, 0).constData()); @@ -993,7 +1046,7 @@ void tst_qquicktextedit::hAlignVisual() // HCenter Align text->setHAlign(QQuickText::AlignHCenter); QImage image = view.grabWindow(); - int x1 = qFloor(image.width() - text->implicitWidth()) / 2; + int x1 = qFloor(image.width() - text->implicitWidth() * view.devicePixelRatio()) / 2; int x2 = image.width() - x1; int left = numberOfNonWhitePixels(0, x1, image); int mid = numberOfNonWhitePixels(x1, x2 - x1, image); @@ -1006,7 +1059,7 @@ void tst_qquicktextedit::hAlignVisual() // Right Align text->setHAlign(QQuickText::AlignRight); QImage image = view.grabWindow(); - int x = image.width() - qCeil(text->implicitWidth()); + int x = image.width() - qCeil(text->implicitWidth() * view.devicePixelRatio()); int left = numberOfNonWhitePixels(0, x, image); int right = numberOfNonWhitePixels(x, image.width() - x, image); QCOMPARE(left, 0); @@ -2612,8 +2665,6 @@ void tst_qquicktextedit::linkHover() QCOMPARE(window.cursor().shape(), Qt::IBeamCursor); QCOMPARE(hover.last()[0].toString(), QString()); - texteditObject->setCursor(Qt::OpenHandCursor); - QCursor::setPos(linkPos); QTRY_COMPARE(hover.count(), 3); QCOMPARE(window.cursor().shape(), Qt::PointingHandCursor); @@ -2621,7 +2672,7 @@ void tst_qquicktextedit::linkHover() QCursor::setPos(textPos); QTRY_COMPARE(hover.count(), 4); - QCOMPARE(window.cursor().shape(), Qt::OpenHandCursor); + QCOMPARE(window.cursor().shape(), Qt::IBeamCursor); QCOMPARE(hover.last()[0].toString(), QString()); } #endif @@ -3826,6 +3877,40 @@ void tst_qquicktextedit::largeTextObservesViewport() QCOMPARE(textPriv->cursorItem->isVisible(), textPriv->renderedRegion.intersects(textItem->cursorRectangle())); } +void tst_qquicktextedit::renderingAroundSelection() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("threeLines.qml"))); + NodeCheckerTextEdit *textItem = qmlobject_cast<NodeCheckerTextEdit*>(window.rootObject()); + QVERIFY(textItem); + QTRY_VERIFY(textItem->linePositions.count() > 0); + const auto linePositions = textItem->linePositions; + const int lastLinePosition = textItem->lastLinePosition; + QQuickTextEditPrivate *textPriv = QQuickTextEditPrivate::get(textItem); + QSignalSpy renderSpy(&window, &QQuickWindow::afterRendering); + + if (lcTests().isDebugEnabled()) + QTest::qWait(500); // for visual check; not needed in CI + + const int renderCount = renderSpy.count(); + QPoint p1 = textItem->mapToScene(textItem->positionToRectangle(8).center()).toPoint(); + QPoint p2 = textItem->mapToScene(textItem->positionToRectangle(10).center()).toPoint(); + qCDebug(lcTests) << "drag from" << p1 << "to" << p2; + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p1); + QTest::mouseMove(&window, p2); + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p2); + // ensure that QQuickTextEdit::updatePaintNode() has a chance to run + QTRY_VERIFY(renderSpy.count() > renderCount); + + if (lcTests().isDebugEnabled()) + QTest::qWait(500); // for visual check; not needed in CI + + qCDebug(lcTests) << "TextEdit's nodes" << textPriv->textNodeMap; + qCDebug(lcTests) << "font" << textItem->font() << "line positions" << textItem->linePositions << "should be" << linePositions; + QCOMPARE(textItem->lastLinePosition, lastLinePosition); + QTRY_COMPARE(textItem->linePositions, linePositions); +} + void tst_qquicktextedit::signal_editingfinished() { QQuickView *window = new QQuickView(nullptr); |