diff options
Diffstat (limited to 'tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp')
-rw-r--r-- | tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp | 859 |
1 files changed, 857 insertions, 2 deletions
diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index ba1a95f..2c3ec7c 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -66,6 +66,8 @@ #define SRCDIR "." #endif +Q_DECLARE_METATYPE(QDeclarativeTextEdit::SelectionMode) + QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual) { // XXX This will be replaced by some clever persistent platform image store. @@ -100,6 +102,7 @@ private slots: // ### these tests may be trivial void hAlign(); + void hAlign_RightToLeft(); void vAlign(); void font(); void color(); @@ -107,11 +110,19 @@ private slots: void persistentSelection(); void focusOnPress(); void selection(); + void moveCursorSelection_data(); + void moveCursorSelection(); + void moveCursorSelectionSequence_data(); + void moveCursorSelectionSequence(); void mouseSelection_data(); void mouseSelection(); + void mouseSelectionMode_data(); + void mouseSelectionMode(); + void dragMouseSelection(); void inputMethodHints(); void cursorDelegate(); + void cursorVisible(); void delegateLoading_data(); void delegateLoading(); void navigation(); @@ -122,6 +133,13 @@ private slots: void openInputPanelOnFocus(); void geometrySignals(); void pastingRichText_QTBUG_14003(); + void implicitSize_data(); + void implicitSize(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); + + void preeditMicroFocus(); + void inputContextMouseHandler(); private: void simulateKey(QDeclarativeView *, int key); @@ -144,7 +162,9 @@ private: tst_qdeclarativetextedit::tst_qdeclarativetextedit() { standard << "the quick brown fox jumped over the lazy dog" - << "the quick brown fox\n jumped over the lazy dog"; + << "the quick brown fox\n jumped over the lazy dog" + << "Hello, world!" + << "!dlrow ,olleH"; richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>" << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>"; @@ -413,6 +433,30 @@ void tst_qdeclarativetextedit::hAlign() } +void tst_qdeclarativetextedit::hAlign_RightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/horizontalAlignment_RightToLeft.qml"); + QDeclarativeTextEdit *textEdit = canvas->rootObject()->findChild<QDeclarativeTextEdit*>("text"); + QVERIFY(textEdit != 0); + canvas->show(); + + QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2); + + // "Right" align + textEdit->setHAlign(QDeclarativeTextEdit::AlignRight); + QCOMPARE(textEdit->hAlign(), QDeclarativeTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2); + + // Center align + // Note that position 0 is on the right-hand side + textEdit->setHAlign(QDeclarativeTextEdit::AlignHCenter); + QCOMPARE(textEdit->hAlign(), QDeclarativeTextEdit::AlignHCenter); + QVERIFY(textEdit->positionToRectangle(0).x() - textEdit->width() < canvas->width()/2); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2); + + delete canvas; +} + void tst_qdeclarativetextedit::vAlign() { //test one align each, and then test if two align fails. @@ -704,8 +748,351 @@ void tst_qdeclarativetextedit::selection() QVERIFY(textEditObject->selectedText().size() == 10); textEditObject->select(0,100); QVERIFY(textEditObject->selectedText().size() == 10); + + textEditObject->deselect(); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(0,10); + QVERIFY(textEditObject->selectedText().size() == 10); + textEditObject->deselect(); + QVERIFY(textEditObject->selectedText().isNull()); +} + +void tst_qdeclarativetextedit::moveCursorSelection_data() +{ + QTest::addColumn<QString>("testStr"); + QTest::addColumn<int>("cursorPosition"); + QTest::addColumn<int>("movePosition"); + QTest::addColumn<QDeclarativeTextEdit::SelectionMode>("mode"); + QTest::addColumn<int>("selectionStart"); + QTest::addColumn<int>("selectionEnd"); + QTest::addColumn<bool>("reversible"); + + QTest::newRow("(t)he|characters") + << standard[0] << 0 << 1 << QDeclarativeTextEdit::SelectCharacters << 0 << 1 << true; + QTest::newRow("do(g)|characters") + << standard[0] << 43 << 44 << QDeclarativeTextEdit::SelectCharacters << 43 << 44 << true; + QTest::newRow("jum(p)ed|characters") + << standard[0] << 23 << 24 << QDeclarativeTextEdit::SelectCharacters << 23 << 24 << true; + QTest::newRow("jumped( )over|characters") + << standard[0] << 26 << 27 << QDeclarativeTextEdit::SelectCharacters << 26 << 27 << true; + QTest::newRow("(the )|characters") + << standard[0] << 0 << 4 << QDeclarativeTextEdit::SelectCharacters << 0 << 4 << true; + QTest::newRow("( dog)|characters") + << standard[0] << 40 << 44 << QDeclarativeTextEdit::SelectCharacters << 40 << 44 << true; + QTest::newRow("( jumped )|characters") + << standard[0] << 19 << 27 << QDeclarativeTextEdit::SelectCharacters << 19 << 27 << true; + QTest::newRow("th(e qu)ick|characters") + << standard[0] << 2 << 6 << QDeclarativeTextEdit::SelectCharacters << 2 << 6 << true; + QTest::newRow("la(zy d)og|characters") + << standard[0] << 38 << 42 << QDeclarativeTextEdit::SelectCharacters << 38 << 42 << true; + QTest::newRow("jum(ped ov)er|characters") + << standard[0] << 23 << 29 << QDeclarativeTextEdit::SelectCharacters << 23 << 29 << true; + QTest::newRow("()the|characters") + << standard[0] << 0 << 0 << QDeclarativeTextEdit::SelectCharacters << 0 << 0 << true; + QTest::newRow("dog()|characters") + << standard[0] << 44 << 44 << QDeclarativeTextEdit::SelectCharacters << 44 << 44 << true; + QTest::newRow("jum()ped|characters") + << standard[0] << 23 << 23 << QDeclarativeTextEdit::SelectCharacters << 23 << 23 << true; + + QTest::newRow("<(t)he>|words") + << standard[0] << 0 << 1 << QDeclarativeTextEdit::SelectWords << 0 << 3 << true; + QTest::newRow("<do(g)>|words") + << standard[0] << 43 << 44 << QDeclarativeTextEdit::SelectWords << 41 << 44 << true; + QTest::newRow("<jum(p)ed>|words") + << standard[0] << 23 << 24 << QDeclarativeTextEdit::SelectWords << 20 << 26 << true; + QTest::newRow("<jumped( )>over|words") + << standard[0] << 26 << 27 << QDeclarativeTextEdit::SelectWords << 20 << 27 << false; + QTest::newRow("jumped<( )over>|words,reversed") + << standard[0] << 27 << 26 << QDeclarativeTextEdit::SelectWords << 26 << 31 << false; + QTest::newRow("<(the )>quick|words") + << standard[0] << 0 << 4 << QDeclarativeTextEdit::SelectWords << 0 << 4 << false; + QTest::newRow("<(the )quick>|words,reversed") + << standard[0] << 4 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 9 << false; + QTest::newRow("<lazy( dog)>|words") + << standard[0] << 40 << 44 << QDeclarativeTextEdit::SelectWords << 36 << 44 << false; + QTest::newRow("lazy<( dog)>|words,reversed") + << standard[0] << 44 << 40 << QDeclarativeTextEdit::SelectWords << 40 << 44 << false; + QTest::newRow("<fox( jumped )>over|words") + << standard[0] << 19 << 27 << QDeclarativeTextEdit::SelectWords << 16 << 27 << false; + QTest::newRow("fox<( jumped )over>|words,reversed") + << standard[0] << 27 << 19 << QDeclarativeTextEdit::SelectWords << 19 << 31 << false; + QTest::newRow("<th(e qu)ick>|words") + << standard[0] << 2 << 6 << QDeclarativeTextEdit::SelectWords << 0 << 9 << true; + QTest::newRow("<la(zy d)og|words>") + << standard[0] << 38 << 42 << QDeclarativeTextEdit::SelectWords << 36 << 44 << true; + QTest::newRow("<jum(ped ov)er>|words") + << standard[0] << 23 << 29 << QDeclarativeTextEdit::SelectWords << 20 << 31 << true; + QTest::newRow("<()>the|words") + << standard[0] << 0 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 0 << true; + QTest::newRow("dog<()>|words") + << standard[0] << 44 << 44 << QDeclarativeTextEdit::SelectWords << 44 << 44 << true; + QTest::newRow("jum<()>ped|words") + << standard[0] << 23 << 23 << QDeclarativeTextEdit::SelectWords << 23 << 23 << true; + + QTest::newRow("Hello<(,)> |words") + << standard[2] << 5 << 6 << QDeclarativeTextEdit::SelectWords << 5 << 6 << true; + QTest::newRow("Hello<(, )>world|words") + << standard[2] << 5 << 7 << QDeclarativeTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello<(, )world>|words,reversed") + << standard[2] << 7 << 5 << QDeclarativeTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("<Hel(lo, )>world|words") + << standard[2] << 3 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("<Hel(lo, )world>|words,reversed") + << standard[2] << 7 << 3 << QDeclarativeTextEdit::SelectWords << 0 << 12 << false; + QTest::newRow("<Hel(lo)>,|words") + << standard[2] << 3 << 5 << QDeclarativeTextEdit::SelectWords << 0 << 5 << true; + QTest::newRow("Hello<()>,|words") + << standard[2] << 5 << 5 << QDeclarativeTextEdit::SelectWords << 5 << 5 << true; + QTest::newRow("Hello,<()>|words") + << standard[2] << 6 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 6 << true; + QTest::newRow("Hello<,( )>world|words") + << standard[2] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello,<( )world>|words,reversed") + << standard[2] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world)>|words") + << standard[2] << 6 << 12 << QDeclarativeTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("Hello,<( world)>|words,reversed") + << standard[2] << 12 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world!)>|words") + << standard[2] << 6 << 13 << QDeclarativeTextEdit::SelectWords << 5 << 13 << false; + QTest::newRow("Hello,<( world!)>|words,reversed") + << standard[2] << 13 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow("Hello<(, world!)>|words") + << standard[2] << 5 << 13 << QDeclarativeTextEdit::SelectWords << 5 << 13 << true; + QTest::newRow("world<(!)>|words") + << standard[2] << 12 << 13 << QDeclarativeTextEdit::SelectWords << 12 << 13 << true; + QTest::newRow("world!<()>)|words") + << standard[2] << 13 << 13 << QDeclarativeTextEdit::SelectWords << 13 << 13 << true; + QTest::newRow("world<()>!)|words") + << standard[2] << 12 << 12 << QDeclarativeTextEdit::SelectWords << 12 << 12 << true; + + QTest::newRow("<(,)>olleH |words") + << standard[3] << 7 << 8 << QDeclarativeTextEdit::SelectWords << 7 << 8 << true; + QTest::newRow("<dlrow( ,)>olleH|words") + << standard[3] << 6 << 8 << QDeclarativeTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("dlrow<( ,)>olleH|words,reversed") + << standard[3] << 8 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("<dlrow( ,ol)leH>|words") + << standard[3] << 6 << 10 << QDeclarativeTextEdit::SelectWords << 1 << 13 << false; + QTest::newRow("dlrow<( ,ol)leH>|words,reversed") + << standard[3] << 10 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow(",<(ol)leH>,|words") + << standard[3] << 8 << 10 << QDeclarativeTextEdit::SelectWords << 8 << 13 << true; + QTest::newRow(",<()>olleH|words") + << standard[3] << 8 << 8 << QDeclarativeTextEdit::SelectWords << 8 << 8 << true; + QTest::newRow("<()>,olleH|words") + << standard[3] << 7 << 7 << QDeclarativeTextEdit::SelectWords << 7 << 7 << true; + QTest::newRow("<dlrow( )>,olleH|words") + << standard[3] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("dlrow<( ),>olleH|words,reversed") + << standard[3] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("<(dlrow )>,olleH|words") + << standard[3] << 1 << 7 << QDeclarativeTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("<(dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 1 << QDeclarativeTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("<(!dlrow )>,olleH|words") + << standard[3] << 0 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("<(!dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 8 << false; + QTest::newRow("(!dlrow ,)olleH|words") + << standard[3] << 0 << 8 << QDeclarativeTextEdit::SelectWords << 0 << 8 << true; + QTest::newRow("<(!)>dlrow|words") + << standard[3] << 0 << 1 << QDeclarativeTextEdit::SelectWords << 0 << 1 << true; + QTest::newRow("<()>!dlrow|words") + << standard[3] << 0 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 0 << true; + QTest::newRow("!<()>dlrow|words") + << standard[3] << 1 << 1 << QDeclarativeTextEdit::SelectWords << 1 << 1 << true; +} + +void tst_qdeclarativetextedit::moveCursorSelection() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition); + QFETCH(QDeclarativeTextEdit::SelectionMode, mode); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(bool, reversible); + + QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextEdit *texteditObject = qobject_cast<QDeclarativeTextEdit*>(textinputComponent.create()); + QVERIFY(texteditObject != 0); + + texteditObject->setCursorPosition(cursorPosition); + texteditObject->moveCursorSelection(movePosition, mode); + + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(texteditObject->selectionStart(), selectionStart); + QCOMPARE(texteditObject->selectionEnd(), selectionEnd); + + if (reversible) { + texteditObject->setCursorPosition(movePosition); + texteditObject->moveCursorSelection(cursorPosition, mode); + + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(texteditObject->selectionStart(), selectionStart); + QCOMPARE(texteditObject->selectionEnd(), selectionEnd); + } +} + +void tst_qdeclarativetextedit::moveCursorSelectionSequence_data() +{ + QTest::addColumn<QString>("testStr"); + QTest::addColumn<int>("cursorPosition"); + QTest::addColumn<int>("movePosition1"); + QTest::addColumn<int>("movePosition2"); + QTest::addColumn<int>("selection1Start"); + QTest::addColumn<int>("selection1End"); + QTest::addColumn<int>("selection2Start"); + QTest::addColumn<int>("selection2End"); + + QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr") + << standard[0] + << 9 << 13 << 17 + << 4 << 15 + << 4 << 19; + QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") + << standard[0] + << 13 << 9 << 17 + << 9 << 15 + << 10 << 19; + QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr") + << standard[0] + << 9 << 13 << 16 + << 4 << 15 + << 4 << 16; + QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") + << standard[0] + << 13 << 9 << 16 + << 9 << 15 + << 10 << 16; + QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr") + << standard[0] + << 9 << 13 << 15 + << 4 << 15 + << 4 << 15; + QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") + << standard[0] + << 13 << 9 << 15 + << 9 << 15 + << 10 << 15; + QTest::newRow("the {<quick() ^}bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 10 + << 4 << 15 + << 4 << 10; + QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 10 + << 9 << 15 + << 10 << 15; + QTest::newRow("the {<quick^}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 9 + << 4 << 15 + << 4 << 9; + QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 9 + << 9 << 15 + << 9 << 15; + QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 7 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 7 + << 9 << 15 + << 4 << 15; + QTest::newRow("the {<^quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 4 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<^quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 4 + << 9 << 15 + << 4 << 15; + QTest::newRow("the{^ <quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 3 + << 4 << 15 + << 3 << 9; + QTest::newRow("the{^ <quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 3 + << 9 << 15 + << 3 << 15; + QTest::newRow("{t^he <quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 1 + << 4 << 15 + << 0 << 9; + QTest::newRow("{t^he <quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 1 + << 9 << 15 + << 0 << 15; + + QTest::newRow("{<He(ll)o>, w^orld}!|ltr") + << standard[2] + << 2 << 4 << 8 + << 0 << 5 + << 0 << 12; + QTest::newRow("{<He(ll)o>, w^orld}!|rtl") + << standard[2] + << 4 << 2 << 8 + << 0 << 5 + << 0 << 12; + + QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr") + << standard[3] + << 9 << 11 << 5 + << 8 << 13 + << 1 << 13; + QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl") + << standard[3] + << 11 << 9 << 5 + << 8 << 13 + << 1 << 13; } +void tst_qdeclarativetextedit::moveCursorSelectionSequence() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition1); + QFETCH(int, movePosition2); + QFETCH(int, selection1Start); + QFETCH(int, selection1End); + QFETCH(int, selection2Start); + QFETCH(int, selection2End); + + QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextEdit *texteditObject = qobject_cast<QDeclarativeTextEdit*>(texteditComponent.create()); + QVERIFY(texteditObject != 0); + + texteditObject->setCursorPosition(cursorPosition); + + texteditObject->moveCursorSelection(movePosition1, QDeclarativeTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); + QCOMPARE(texteditObject->selectionStart(), selection1Start); + QCOMPARE(texteditObject->selectionEnd(), selection1End); + + texteditObject->moveCursorSelection(movePosition2, QDeclarativeTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); + QCOMPARE(texteditObject->selectionStart(), selection2Start); + QCOMPARE(texteditObject->selectionEnd(), selection2End); +} + + void tst_qdeclarativetextedit::mouseSelection_data() { QTest::addColumn<QString>("qmlfile"); @@ -751,6 +1138,102 @@ void tst_qdeclarativetextedit::mouseSelection() delete canvas; } +void tst_qdeclarativetextedit::dragMouseSelection() +{ + QString qmlfile = SRCDIR "/data/mouseselection_true.qml"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextEdit *textEditObject = qobject_cast<QDeclarativeTextEdit *>(canvas->rootObject()); + QVERIFY(textEditObject != 0); + + textEditObject->setAcceptDrops(true); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str1 = textEditObject->selectedText(); + QVERIFY(str1.length() > 3); + + // press and drag the current selection. + x1 = 40; + x2 = 100; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str2 = textEditObject->selectedText(); + QVERIFY(str2.length() > 3); + + QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved. + + delete canvas; +} + +void tst_qdeclarativetextedit::mouseSelectionMode_data() +{ + QTest::addColumn<QString>("qmlfile"); + QTest::addColumn<bool>("selectWords"); + + // import installed + QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true; + QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false; + QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false; +} + +void tst_qdeclarativetextedit::mouseSelectionMode() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, selectWords); + + QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextEdit *textEditObject = qobject_cast<QDeclarativeTextEdit *>(canvas->rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str = textEditObject->selectedText(); + if (selectWords) { + QCOMPARE(str, text); + } else { + QVERIFY(str.length() > 3); + QVERIFY(str != text); + } + + delete canvas; +} + void tst_qdeclarativetextedit::inputMethodHints() { QDeclarativeView *canvas = createView(SRCDIR "/data/inputmethodhints.qml"); @@ -795,6 +1278,76 @@ void tst_qdeclarativetextedit::cursorDelegate() delete view; } +void tst_qdeclarativetextedit::cursorVisible() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + view.setFocus(); + + QDeclarativeTextEdit edit; + QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool))); + + QCOMPARE(edit.isCursorVisible(), false); + + edit.setCursorVisible(true); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 1); + + edit.setCursorVisible(false); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + edit.setFocus(true); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + scene.addItem(&edit); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 3); + + edit.setFocus(false); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 4); + + edit.setFocus(true); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 5); + + scene.clearFocus(); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 6); + + scene.setFocus(); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 7); + + view.clearFocus(); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 8); + + view.setFocus(); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 9); + + // on mac, setActiveWindow(0) on mac does not deactivate the current application + // (you have to switch to a different app or hide the current app to trigger this) +#if !defined(Q_WS_MAC) + QApplication::setActiveWindow(0); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(0)); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 10); + + QApplication::setActiveWindow(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 11); +#endif +} + void tst_qdeclarativetextedit::delegateLoading_data() { QTest::addColumn<QString>("qmlfile"); @@ -906,10 +1459,18 @@ void tst_qdeclarativetextedit::copyAndPaste() { QCOMPARE(textEdit->selectedText(), QString("Hello world!")); QCOMPARE(textEdit->selectedText().length(), 12); textEdit->setCursorPosition(0); + QVERIFY(textEdit->canPaste()); textEdit->paste(); QCOMPARE(textEdit->text(), QString("Hello world!Hello world!")); QCOMPARE(textEdit->text().length(), 24); + // canPaste + QVERIFY(textEdit->canPaste()); + textEdit->setReadOnly(true); + QVERIFY(!textEdit->canPaste()); + textEdit->setReadOnly(false); + QVERIFY(textEdit->canPaste()); + // QTBUG-12339 // test that document and internal text attribute are in sync QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(textEdit); @@ -975,7 +1536,7 @@ QDeclarativeView *tst_qdeclarativetextedit::createView(const QString &filename) class MyInputContext : public QInputContext { public: - MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false) {} + MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {} ~MyInputContext() {} QString identifierName() { return QString(); } @@ -993,8 +1554,40 @@ public: closeInputPanelReceived = true; return QInputContext::filterEvent(event); } + + void update() { updateReceived = true; } + + void sendPreeditText(const QString &text, int cursor) + { + QList<QInputMethodEvent::Attribute> attributes; + attributes.append(QInputMethodEvent::Attribute( + QInputMethodEvent::Cursor, cursor, text.length(), QVariant())); + + QInputMethodEvent event(text, attributes); + sendEvent(event); + } + + void mouseHandler(int x, QMouseEvent *event) + { + cursor = x; + eventType = event->type(); + eventPosition = event->pos(); + eventGlobalPosition = event->globalPos(); + eventButton = event->button(); + eventButtons = event->buttons(); + eventModifiers = event->modifiers(); + } + bool openInputPanelReceived; bool closeInputPanelReceived; + bool updateReceived; + int cursor; + QEvent::Type eventType; + QPoint eventPosition; + QPoint eventGlobalPosition; + Qt::MouseButton eventButton; + Qt::MouseButtons eventButtons; + Qt::KeyboardModifiers eventModifiers; }; void tst_qdeclarativetextedit::textInput() @@ -1191,6 +1784,16 @@ void tst_qdeclarativetextedit::openInputPanelOnFocus() QApplication::processEvents(); QVERIFY(view.inputContext() == 0); QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); + + // input method should not be enabled + // if TextEdit is read only. + edit.setReadOnly(true); + ic.openInputPanelReceived = false; + edit.setFocus(true); + QApplication::processEvents(); + QCOMPARE(ic.openInputPanelReceived, false); + QVERIFY(view.inputContext() == 0); + QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); } void tst_qdeclarativetextedit::geometrySignals() @@ -1224,6 +1827,258 @@ void tst_qdeclarativetextedit::pastingRichText_QTBUG_14003() #endif } +void tst_qdeclarativetextedit::implicitSize_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("wrap"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; + QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; + QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap"; +} + +void tst_qdeclarativetextedit::implicitSize() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QString componentStr = "import QtQuick 1.1\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeTextEdit *textObject = qobject_cast<QDeclarativeTextEdit*>(textComponent.create()); + + QVERIFY(textObject->width() < textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + + textObject->resetWidth(); + QVERIFY(textObject->width() == textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); +} + +void tst_qdeclarativetextedit::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; TextEdit { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qdeclarativetextedit::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("canPaste") << "property bool foo: canPaste" + << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste" + << ""; + + QTest::newRow("lineCount") << "property int foo: lineCount" + << "<Unknown File>:1: ReferenceError: Can't find variable: lineCount" + << ""; + + QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)" + << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection" + << ""; + + QTest::newRow("deselect") << "Component.onCompleted: deselect()" + << "<Unknown File>:1: ReferenceError: Can't find variable: deselect" + << ""; + + QTest::newRow("onLinkActivated") << "onLinkActivated: {}" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n"; +} + +void tst_qdeclarativetextedit::preeditMicroFocus() +{ + QString preeditText = "super"; + + QGraphicsScene scene; + QGraphicsView view(&scene); + MyInputContext ic; + view.setInputContext(&ic); + QDeclarativeTextEdit edit; + edit.setFocus(true); + scene.addItem(&edit); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + + QRect currentRect; + QRect previousRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect(); + + // Verify that the micro focus rect is positioned the same for position 0 as + // it would be if there was no preedit text. + ic.updateReceived = false; + ic.sendPreeditText(preeditText, 0); + currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect(); + QCOMPARE(currentRect, previousRect); +#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) + QCOMPARE(ic.updateReceived, true); +#endif + + // Verify that the micro focus rect moves to the left as the cursor position + // is incremented. + for (int i = 1; i <= 5; ++i) { + ic.updateReceived = false; + ic.sendPreeditText(preeditText, i); + currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect(); + QVERIFY(previousRect.left() < currentRect.left()); +#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) + QCOMPARE(ic.updateReceived, true); +#endif + previousRect = currentRect; + } + + // Verify that if there is no preedit cursor then the micro focus rect is the + // same as it would be if it were positioned at the end of the preedit text. + ic.sendPreeditText(preeditText, 0); + ic.updateReceived = false; + ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>())); + currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect(); + QCOMPARE(currentRect, previousRect); +#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) + QCOMPARE(ic.updateReceived, true); +#endif +} + +void tst_qdeclarativetextedit::inputContextMouseHandler() +{ + QString text = "supercalifragisiticexpialidocious!"; + + QGraphicsScene scene; + QGraphicsView view(&scene); + MyInputContext ic; + view.setInputContext(&ic); + QDeclarativeTextEdit edit; + edit.setPos(0, 0); + edit.setWidth(200); + edit.setText(text.mid(0, 12)); + edit.setPos(0, 0); + edit.setCursorPosition(12); + edit.setFocus(true); + scene.addItem(&edit); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + view.setFocus(); + + QFontMetricsF fm(edit.font()); + const qreal y = fm.height() / 2; + + QPoint position2 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 2)), y))); + QPoint position8 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 8)), y))); + QPoint position20 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 20)), y))); + QPoint position27 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 27)), y))); + QPoint globalPosition2 = view.viewport()->mapToGlobal(position2); + QPoint globalposition8 = view.viewport()->mapToGlobal(position8); + QPoint globalposition20 = view.viewport()->mapToGlobal(position20); + QPoint globalposition27 = view.viewport()->mapToGlobal(position27); + + ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>())); + + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; + + QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonPress); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::None); + + { QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::MouseMove); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); // 15 is expected but some platforms may be off by one. + ic.eventType = QEvent::None; + + QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position27); + QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); + ic.eventType = QEvent::None; + + // And in the other direction. + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position27); + QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); + ic.eventType = QEvent::None; + + QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position27); + QCOMPARE(ic.eventType, QEvent::MouseButtonPress); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::MouseMove); + QCOMPARE(ic.eventPosition, position20); + QCOMPARE(ic.eventGlobalPosition, globalposition20); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QVERIFY(ic.cursor >= 7 && ic.cursor <= 9); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::None); + + QTest::mouseRelease(view.viewport(), Qt::RightButton, Qt::ControlModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; +} + QTEST_MAIN(tst_qdeclarativetextedit) #include "tst_qdeclarativetextedit.moc" |