1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QSignalSpy>
43 #include "../../declarative/shared/testhttpserver.h"
46 #include <QTextDocument>
47 #include <QtDeclarative/qdeclarativeengine.h>
48 #include <QtDeclarative/qdeclarativecontext.h>
49 #include <QtDeclarative/qdeclarativeexpression.h>
50 #include <QtDeclarative/qdeclarativecomponent.h>
51 #include <QtQuick1/private/qdeclarativetextedit_p.h>
52 #include <QtQuick1/private/qdeclarativetextedit_p_p.h>
53 #include <QFontMetrics>
54 #include <QtQuick1/QDeclarativeView>
57 #include <QInputContext>
60 #include <QtWidgets/5.0.0/QtWidgets/private/qapplication_p.h>
61 #include <private/qtextcontrol_p.h>
63 Q_DECLARE_METATYPE(QDeclarative1TextEdit::SelectionMode)
65 QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual)
67 // XXX This will be replaced by some clever persistent platform image store.
68 QString persistent_dir = SRCDIR "/data";
69 QString arch = "unknown-architecture"; // QTest needs to help with this.
71 QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
73 if (!QFile::exists(expectfile)) {
74 actual.save(expectfile);
75 qWarning() << "created" << expectfile;
82 class tst_qdeclarativetextedit : public QObject
87 tst_qdeclarativetextedit();
95 void alignments_data();
97 // ### these tests may be trivial
99 void hAlign_RightToLeft();
104 void persistentSelection();
107 void isRightToLeft_data();
108 void isRightToLeft();
110 void moveCursorSelection_data();
111 void moveCursorSelection();
112 void moveCursorSelectionSequence_data();
113 void moveCursorSelectionSequence();
114 void mouseSelection_data();
115 void mouseSelection();
116 void multilineMouseSelection();
117 void deferEnableSelectByMouse_data();
118 void deferEnableSelectByMouse();
119 void deferDisableSelectByMouse_data();
120 void deferDisableSelectByMouse();
121 void mouseSelectionMode_data();
122 void mouseSelectionMode();
123 void dragMouseSelection();
124 void inputMethodHints();
128 void cursorDelegate();
129 void cursorVisible();
130 void delegateLoading_data();
131 void delegateLoading();
136 void canPasteEmpty();
138 void openInputPanelOnClick();
139 void openInputPanelOnFocus();
140 void geometrySignals();
141 void pastingRichText_QTBUG_14003();
142 void implicitSize_data();
144 void testQtQuick11Attributes();
145 void testQtQuick11Attributes_data();
147 void preeditMicroFocus();
148 void inputContextMouseHandler();
149 void inputMethodComposing();
150 void cursorRectangleSize();
153 void simulateKey(QDeclarativeView *, int key, Qt::KeyboardModifiers modifiers = 0);
154 QDeclarativeView *createView(const QString &filename);
156 QStringList standard;
157 QStringList richText;
159 QStringList hAlignmentStrings;
160 QStringList vAlignmentStrings;
162 QList<Qt::Alignment> vAlignments;
163 QList<Qt::Alignment> hAlignments;
165 QStringList colorStrings;
167 QDeclarativeEngine engine;
170 tst_qdeclarativetextedit::tst_qdeclarativetextedit()
172 standard << "the quick brown fox jumped over the lazy dog"
173 << "the quick brown fox\n jumped over the lazy dog"
177 richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
178 << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
180 hAlignmentStrings << "AlignLeft"
184 vAlignmentStrings << "AlignTop"
188 hAlignments << Qt::AlignLeft
192 vAlignments << Qt::AlignTop
196 colorStrings << "aliceblue"
209 // need a different test to do alpha channel test
215 void tst_qdeclarativetextedit::text()
218 QDeclarativeComponent texteditComponent(&engine);
219 texteditComponent.setData("import QtQuick 1.0\nTextEdit { text: \"\" }", QUrl());
220 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
222 QVERIFY(textEditObject != 0);
223 QCOMPARE(textEditObject->text(), QString(""));
226 for (int i = 0; i < standard.size(); i++)
228 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
229 QDeclarativeComponent texteditComponent(&engine);
230 texteditComponent.setData(componentStr.toLatin1(), QUrl());
231 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
233 QVERIFY(textEditObject != 0);
234 QCOMPARE(textEditObject->text(), standard.at(i));
237 for (int i = 0; i < richText.size(); i++)
239 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
240 QDeclarativeComponent texteditComponent(&engine);
241 texteditComponent.setData(componentStr.toLatin1(), QUrl());
242 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
244 QVERIFY(textEditObject != 0);
245 QString actual = textEditObject->text();
246 QString expected = richText.at(i);
247 actual.replace(QRegExp(".*<body[^>]*>"),"");
248 actual.replace(QRegExp("(<[^>]*>)+"),"<>");
249 expected.replace(QRegExp("(<[^>]*>)+"),"<>");
250 QCOMPARE(actual.simplified(),expected.simplified());
254 void tst_qdeclarativetextedit::width()
256 // uses Font metrics to find the width for standard and document to find the width for rich
258 QDeclarativeComponent texteditComponent(&engine);
259 texteditComponent.setData("import QtQuick 1.0\nTextEdit { text: \"\" }", QUrl());
260 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
262 QVERIFY(textEditObject != 0);
263 QCOMPARE(textEditObject->width(), 0.0);
266 for (int i = 0; i < standard.size(); i++)
270 qreal metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
271 metricWidth = ceil(metricWidth);
273 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
274 QDeclarativeComponent texteditComponent(&engine);
275 texteditComponent.setData(componentStr.toLatin1(), QUrl());
276 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
278 QVERIFY(textEditObject != 0);
279 QCOMPARE(textEditObject->width(), qreal(metricWidth));
282 for (int i = 0; i < richText.size(); i++)
284 QTextDocument document;
285 document.setHtml(richText.at(i));
286 document.setDocumentMargin(0);
288 int documentWidth = ceil(document.idealWidth());
290 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
291 QDeclarativeComponent texteditComponent(&engine);
292 texteditComponent.setData(componentStr.toLatin1(), QUrl());
293 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
295 QVERIFY(textEditObject != 0);
296 QCOMPARE(textEditObject->width(), qreal(documentWidth));
300 void tst_qdeclarativetextedit::wrap()
302 // for specified width and wrap set true
304 QDeclarativeComponent texteditComponent(&engine);
305 texteditComponent.setData("import QtQuick 1.0\nTextEdit { text: \"\"; wrapMode: TextEdit.WordWrap; width: 300 }", QUrl());
306 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
308 QVERIFY(textEditObject != 0);
309 QCOMPARE(textEditObject->width(), 300.);
312 for (int i = 0; i < standard.size(); i++)
314 QString componentStr = "import QtQuick 1.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + standard.at(i) + "\" }";
315 QDeclarativeComponent texteditComponent(&engine);
316 texteditComponent.setData(componentStr.toLatin1(), QUrl());
317 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
319 QVERIFY(textEditObject != 0);
320 QCOMPARE(textEditObject->width(), 300.);
323 for (int i = 0; i < richText.size(); i++)
325 QString componentStr = "import QtQuick 1.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + richText.at(i) + "\" }";
326 QDeclarativeComponent texteditComponent(&engine);
327 texteditComponent.setData(componentStr.toLatin1(), QUrl());
328 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
330 QVERIFY(textEditObject != 0);
331 QCOMPARE(textEditObject->width(), 300.);
336 void tst_qdeclarativetextedit::textFormat()
339 QDeclarativeComponent textComponent(&engine);
340 textComponent.setData("import QtQuick 1.0\nTextEdit { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
341 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
343 QVERIFY(textObject != 0);
344 QVERIFY(textObject->textFormat() == QDeclarative1TextEdit::RichText);
347 QDeclarativeComponent textComponent(&engine);
348 textComponent.setData("import QtQuick 1.0\nTextEdit { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
349 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
351 QVERIFY(textObject != 0);
352 QVERIFY(textObject->textFormat() == QDeclarative1TextEdit::PlainText);
356 void tst_qdeclarativetextedit::alignments_data()
358 QTest::addColumn<int>("hAlign");
359 QTest::addColumn<int>("vAlign");
360 QTest::addColumn<QString>("expectfile");
362 QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << "alignments_lt";
363 QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << "alignments_rt";
364 QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << "alignments_ct";
366 QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << "alignments_lb";
367 QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << "alignments_rb";
368 QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << "alignments_cb";
370 QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << "alignments_lc";
371 QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << "alignments_rc";
372 QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << "alignments_cc";
376 void tst_qdeclarativetextedit::alignments()
380 QFETCH(QString, expectfile);
382 QDeclarativeView *canvas = createView(SRCDIR "/data/alignments.qml");
385 QApplication::setActiveWindow(canvas);
386 QTest::qWaitForWindowShown(canvas);
387 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
389 QObject *ob = canvas->rootObject();
391 ob->setProperty("horizontalAlignment",hAlign);
392 ob->setProperty("verticalAlignment",vAlign);
393 QTRY_COMPARE(ob->property("running").toBool(),false);
394 QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32);
395 actual.fill(qRgb(255,255,255));
399 expectfile = createExpectedFileIfNotFound(expectfile, actual);
401 QImage expect(expectfile);
403 QCOMPARE(actual,expect);
409 //the alignment tests may be trivial o.oa
410 void tst_qdeclarativetextedit::hAlign()
412 //test one align each, and then test if two align fails.
414 for (int i = 0; i < standard.size(); i++)
416 for (int j=0; j < hAlignmentStrings.size(); j++)
418 QString componentStr = "import QtQuick 1.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
419 QDeclarativeComponent texteditComponent(&engine);
420 texteditComponent.setData(componentStr.toLatin1(), QUrl());
421 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
423 QVERIFY(textEditObject != 0);
424 QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
428 for (int i = 0; i < richText.size(); i++)
430 for (int j=0; j < hAlignmentStrings.size(); j++)
432 QString componentStr = "import QtQuick 1.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
433 QDeclarativeComponent texteditComponent(&engine);
434 texteditComponent.setData(componentStr.toLatin1(), QUrl());
435 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
437 QVERIFY(textEditObject != 0);
438 QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
444 void tst_qdeclarativetextedit::hAlign_RightToLeft()
446 QDeclarativeView *canvas = createView(SRCDIR "/data/horizontalAlignment_RightToLeft.qml");
447 QDeclarative1TextEdit *textEdit = canvas->rootObject()->findChild<QDeclarative1TextEdit*>("text");
448 QVERIFY(textEdit != 0);
451 const QString rtlText = textEdit->text();
453 // implicit alignment should follow the reading direction of text
454 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
455 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
457 // explicitly left aligned
458 textEdit->setHAlign(QDeclarative1TextEdit::AlignLeft);
459 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
460 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
462 // explicitly right aligned
463 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
464 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
465 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
467 QString textString = textEdit->text();
468 textEdit->setText(QString("<i>") + textString + QString("</i>"));
469 textEdit->resetHAlign();
471 // implicitly aligned rich text should follow the reading direction of RTL text
472 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
473 QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
474 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
476 // explicitly left aligned rich text
477 textEdit->setHAlign(QDeclarative1TextEdit::AlignLeft);
478 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
479 QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
480 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
482 // explicitly right aligned rich text
483 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
484 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
485 QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
486 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
488 textEdit->setText(textString);
490 // explicitly center aligned
491 textEdit->setHAlign(QDeclarative1TextEdit::AlignHCenter);
492 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignHCenter);
493 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
495 // reseted alignment should go back to following the text reading direction
496 textEdit->resetHAlign();
497 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
498 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
500 // mirror the text item
501 QDeclarativeItemPrivate::get(textEdit)->setLayoutMirror(true);
503 // mirrored implicit alignment should continue to follow the reading direction of the text
504 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
505 QCOMPARE(textEdit->effectiveHAlign(), QDeclarative1TextEdit::AlignRight);
506 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
508 // mirrored explicitly right aligned behaves as left aligned
509 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
510 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
511 QCOMPARE(textEdit->effectiveHAlign(), QDeclarative1TextEdit::AlignLeft);
512 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
514 // mirrored explicitly left aligned behaves as right aligned
515 textEdit->setHAlign(QDeclarative1TextEdit::AlignLeft);
516 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
517 QCOMPARE(textEdit->effectiveHAlign(), QDeclarative1TextEdit::AlignRight);
518 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
521 QDeclarativeItemPrivate::get(textEdit)->setLayoutMirror(false);
522 textEdit->resetHAlign();
524 // English text should be implicitly left aligned
525 textEdit->setText("Hello world!");
526 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
527 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
529 QApplication::setActiveWindow(canvas);
530 QTest::qWaitForWindowShown(canvas);
531 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
533 textEdit->setText(QString());
534 { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
535 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
536 { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
537 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
539 #ifndef Q_OS_MAC // QTBUG-18040
540 // empty text with implicit alignment follows the system locale-based
541 // keyboard input direction from QApplication::keyboardInputDirection
542 textEdit->setText("");
543 QCOMPARE(textEdit->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
544 QDeclarative1TextEdit::AlignLeft : QDeclarative1TextEdit::AlignRight);
545 if (QApplication::keyboardInputDirection() == Qt::LeftToRight)
546 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
548 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
549 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
550 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
551 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
556 #ifndef Q_OS_MAC // QTBUG-18040
557 // alignment of TextEdit with no text set to it
558 QString componentStr = "import QtQuick 1.0\nTextEdit {}";
559 QDeclarativeComponent textComponent(&engine);
560 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
561 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
562 QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
563 QDeclarative1TextEdit::AlignLeft : QDeclarative1TextEdit::AlignRight);
568 void tst_qdeclarativetextedit::vAlign()
570 //test one align each, and then test if two align fails.
572 for (int i = 0; i < standard.size(); i++)
574 for (int j=0; j < vAlignmentStrings.size(); j++)
576 QString componentStr = "import QtQuick 1.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
577 QDeclarativeComponent texteditComponent(&engine);
578 texteditComponent.setData(componentStr.toLatin1(), QUrl());
579 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
581 QVERIFY(textEditObject != 0);
582 QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
586 for (int i = 0; i < richText.size(); i++)
588 for (int j=0; j < vAlignmentStrings.size(); j++)
590 QString componentStr = "import QtQuick 1.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
591 QDeclarativeComponent texteditComponent(&engine);
592 texteditComponent.setData(componentStr.toLatin1(), QUrl());
593 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
595 QVERIFY(textEditObject != 0);
596 QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
602 void tst_qdeclarativetextedit::font()
604 //test size, then bold, then italic, then family
606 QString componentStr = "import QtQuick 1.0\nTextEdit { font.pointSize: 40; text: \"Hello World\" }";
607 QDeclarativeComponent texteditComponent(&engine);
608 texteditComponent.setData(componentStr.toLatin1(), QUrl());
609 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
611 QVERIFY(textEditObject != 0);
612 QCOMPARE(textEditObject->font().pointSize(), 40);
613 QCOMPARE(textEditObject->font().bold(), false);
614 QCOMPARE(textEditObject->font().italic(), false);
618 QString componentStr = "import QtQuick 1.0\nTextEdit { font.bold: true; text: \"Hello World\" }";
619 QDeclarativeComponent texteditComponent(&engine);
620 texteditComponent.setData(componentStr.toLatin1(), QUrl());
621 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
623 QVERIFY(textEditObject != 0);
624 QCOMPARE(textEditObject->font().bold(), true);
625 QCOMPARE(textEditObject->font().italic(), false);
629 QString componentStr = "import QtQuick 1.0\nTextEdit { font.italic: true; text: \"Hello World\" }";
630 QDeclarativeComponent texteditComponent(&engine);
631 texteditComponent.setData(componentStr.toLatin1(), QUrl());
632 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
634 QVERIFY(textEditObject != 0);
635 QCOMPARE(textEditObject->font().italic(), true);
636 QCOMPARE(textEditObject->font().bold(), false);
640 QString componentStr = "import QtQuick 1.0\nTextEdit { font.family: \"Helvetica\"; text: \"Hello World\" }";
641 QDeclarativeComponent texteditComponent(&engine);
642 texteditComponent.setData(componentStr.toLatin1(), QUrl());
643 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
645 QVERIFY(textEditObject != 0);
646 QCOMPARE(textEditObject->font().family(), QString("Helvetica"));
647 QCOMPARE(textEditObject->font().bold(), false);
648 QCOMPARE(textEditObject->font().italic(), false);
652 QString componentStr = "import QtQuick 1.0\nTextEdit { font.family: \"\"; text: \"Hello World\" }";
653 QDeclarativeComponent texteditComponent(&engine);
654 texteditComponent.setData(componentStr.toLatin1(), QUrl());
655 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
657 QVERIFY(textEditObject != 0);
658 QCOMPARE(textEditObject->font().family(), QString(""));
662 void tst_qdeclarativetextedit::color()
666 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello World\" }";
667 QDeclarativeComponent texteditComponent(&engine);
668 texteditComponent.setData(componentStr.toLatin1(), QUrl());
669 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
671 QDeclarative1TextEditPrivate *textEditPrivate = static_cast<QDeclarative1TextEditPrivate*>(QDeclarativeItemPrivate::get(textEditObject));
673 QVERIFY(textEditObject);
674 QVERIFY(textEditPrivate);
675 QVERIFY(textEditPrivate->control);
677 QPalette pal = textEditPrivate->control->palette();
678 QCOMPARE(textEditPrivate->color, QColor("black"));
679 QCOMPARE(textEditPrivate->color, pal.color(QPalette::Text));
682 for (int i = 0; i < colorStrings.size(); i++)
684 QString componentStr = "import QtQuick 1.0\nTextEdit { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
685 QDeclarativeComponent texteditComponent(&engine);
686 texteditComponent.setData(componentStr.toLatin1(), QUrl());
687 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
688 //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i));
689 QVERIFY(textEditObject != 0);
690 QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i)));
694 for (int i = 0; i < colorStrings.size(); i++)
696 QString componentStr = "import QtQuick 1.0\nTextEdit { selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
697 QDeclarativeComponent texteditComponent(&engine);
698 texteditComponent.setData(componentStr.toLatin1(), QUrl());
699 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
700 QVERIFY(textEditObject != 0);
701 QCOMPARE(textEditObject->selectionColor(), QColor(colorStrings.at(i)));
705 for (int i = 0; i < colorStrings.size(); i++)
707 QString componentStr = "import QtQuick 1.0\nTextEdit { selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
708 QDeclarativeComponent texteditComponent(&engine);
709 texteditComponent.setData(componentStr.toLatin1(), QUrl());
710 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
711 QVERIFY(textEditObject != 0);
712 QCOMPARE(textEditObject->selectedTextColor(), QColor(colorStrings.at(i)));
716 QString colorStr = "#AA001234";
717 QColor testColor("#001234");
718 testColor.setAlpha(170);
720 QString componentStr = "import QtQuick 1.0\nTextEdit { color: \"" + colorStr + "\"; text: \"Hello World\" }";
721 QDeclarativeComponent texteditComponent(&engine);
722 texteditComponent.setData(componentStr.toLatin1(), QUrl());
723 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
725 QVERIFY(textEditObject != 0);
726 QCOMPARE(textEditObject->color(), testColor);
730 void tst_qdeclarativetextedit::textMargin()
732 for(qreal i=0; i<=10; i+=0.3){
733 QString componentStr = "import QtQuick 1.0\nTextEdit { textMargin: " + QString::number(i) + "; text: \"Hello World\" }";
734 QDeclarativeComponent texteditComponent(&engine);
735 texteditComponent.setData(componentStr.toLatin1(), QUrl());
736 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
737 QVERIFY(textEditObject != 0);
738 QCOMPARE(textEditObject->textMargin(), i);
742 void tst_qdeclarativetextedit::persistentSelection()
745 QString componentStr = "import QtQuick 1.0\nTextEdit { persistentSelection: true; text: \"Hello World\" }";
746 QDeclarativeComponent texteditComponent(&engine);
747 texteditComponent.setData(componentStr.toLatin1(), QUrl());
748 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
749 QVERIFY(textEditObject != 0);
750 QCOMPARE(textEditObject->persistentSelection(), true);
754 QString componentStr = "import QtQuick 1.0\nTextEdit { persistentSelection: false; text: \"Hello World\" }";
755 QDeclarativeComponent texteditComponent(&engine);
756 texteditComponent.setData(componentStr.toLatin1(), QUrl());
757 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
758 QVERIFY(textEditObject != 0);
759 QCOMPARE(textEditObject->persistentSelection(), false);
763 void tst_qdeclarativetextedit::focusOnPress()
766 QString componentStr = "import QtQuick 1.0\nTextEdit { activeFocusOnPress: true; text: \"Hello World\" }";
767 QDeclarativeComponent texteditComponent(&engine);
768 texteditComponent.setData(componentStr.toLatin1(), QUrl());
769 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
770 QVERIFY(textEditObject != 0);
771 QCOMPARE(textEditObject->focusOnPress(), true);
775 QString componentStr = "import QtQuick 1.0\nTextEdit { activeFocusOnPress: false; text: \"Hello World\" }";
776 QDeclarativeComponent texteditComponent(&engine);
777 texteditComponent.setData(componentStr.toLatin1(), QUrl());
778 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
779 QVERIFY(textEditObject != 0);
780 QCOMPARE(textEditObject->focusOnPress(), false);
784 void tst_qdeclarativetextedit::selection()
786 QString testStr = standard[0];//TODO: What should happen for multiline/rich text?
787 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \""+ testStr +"\"; }";
788 QDeclarativeComponent texteditComponent(&engine);
789 texteditComponent.setData(componentStr.toLatin1(), QUrl());
790 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
791 QVERIFY(textEditObject != 0);
794 //Test selection follows cursor
795 for(int i=0; i<= testStr.size(); i++) {
796 textEditObject->setCursorPosition(i);
797 QCOMPARE(textEditObject->cursorPosition(), i);
798 QCOMPARE(textEditObject->selectionStart(), i);
799 QCOMPARE(textEditObject->selectionEnd(), i);
800 QVERIFY(textEditObject->selectedText().isNull());
802 //Test cursor follows selection
803 for(int i=0; i<= testStr.size(); i++) {
804 textEditObject->select(i,i);
805 QCOMPARE(textEditObject->cursorPosition(), i);
806 QCOMPARE(textEditObject->selectionStart(), i);
807 QCOMPARE(textEditObject->selectionEnd(), i);
811 textEditObject->setCursorPosition(0);
812 QVERIFY(textEditObject->cursorPosition() == 0);
813 QVERIFY(textEditObject->selectionStart() == 0);
814 QVERIFY(textEditObject->selectionEnd() == 0);
815 QVERIFY(textEditObject->selectedText().isNull());
817 // Verify invalid positions are ignored.
818 textEditObject->setCursorPosition(-1);
819 QVERIFY(textEditObject->cursorPosition() == 0);
820 QVERIFY(textEditObject->selectionStart() == 0);
821 QVERIFY(textEditObject->selectionEnd() == 0);
822 QVERIFY(textEditObject->selectedText().isNull());
824 textEditObject->setCursorPosition(textEditObject->text().count()+1);
825 QVERIFY(textEditObject->cursorPosition() == 0);
826 QVERIFY(textEditObject->selectionStart() == 0);
827 QVERIFY(textEditObject->selectionEnd() == 0);
828 QVERIFY(textEditObject->selectedText().isNull());
831 for(int i=0; i<= testStr.size(); i++) {
832 textEditObject->select(0,i);
833 QCOMPARE(testStr.mid(0,i), textEditObject->selectedText());
834 QCOMPARE(textEditObject->cursorPosition(), i);
836 for(int i=0; i<= testStr.size(); i++) {
837 textEditObject->select(i,testStr.size());
838 QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText());
839 QCOMPARE(textEditObject->cursorPosition(), testStr.size());
842 textEditObject->setCursorPosition(0);
843 QVERIFY(textEditObject->cursorPosition() == 0);
844 QVERIFY(textEditObject->selectionStart() == 0);
845 QVERIFY(textEditObject->selectionEnd() == 0);
846 QVERIFY(textEditObject->selectedText().isNull());
848 //Test Error Ignoring behaviour
849 textEditObject->setCursorPosition(0);
850 QVERIFY(textEditObject->selectedText().isNull());
851 textEditObject->select(-10,0);
852 QVERIFY(textEditObject->selectedText().isNull());
853 textEditObject->select(100,101);
854 QVERIFY(textEditObject->selectedText().isNull());
855 textEditObject->select(0,-10);
856 QVERIFY(textEditObject->selectedText().isNull());
857 textEditObject->select(0,100);
858 QVERIFY(textEditObject->selectedText().isNull());
859 textEditObject->select(0,10);
860 QVERIFY(textEditObject->selectedText().size() == 10);
861 textEditObject->select(-10,0);
862 QVERIFY(textEditObject->selectedText().size() == 10);
863 textEditObject->select(100,101);
864 QVERIFY(textEditObject->selectedText().size() == 10);
865 textEditObject->select(0,-10);
866 QVERIFY(textEditObject->selectedText().size() == 10);
867 textEditObject->select(0,100);
868 QVERIFY(textEditObject->selectedText().size() == 10);
870 textEditObject->deselect();
871 QVERIFY(textEditObject->selectedText().isNull());
872 textEditObject->select(0,10);
873 QVERIFY(textEditObject->selectedText().size() == 10);
874 textEditObject->deselect();
875 QVERIFY(textEditObject->selectedText().isNull());
878 void tst_qdeclarativetextedit::isRightToLeft_data()
880 QTest::addColumn<QString>("text");
881 QTest::addColumn<bool>("emptyString");
882 QTest::addColumn<bool>("firstCharacter");
883 QTest::addColumn<bool>("lastCharacter");
884 QTest::addColumn<bool>("middleCharacter");
885 QTest::addColumn<bool>("startString");
886 QTest::addColumn<bool>("midString");
887 QTest::addColumn<bool>("endString");
889 const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
890 QTest::newRow("Empty") << "" << false << false << false << false << false << false << false;
891 QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false;
892 QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false;
893 QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true;
894 QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true;
895 QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false;
898 void tst_qdeclarativetextedit::isRightToLeft()
900 QFETCH(QString, text);
901 QFETCH(bool, emptyString);
902 QFETCH(bool, firstCharacter);
903 QFETCH(bool, lastCharacter);
904 QFETCH(bool, middleCharacter);
905 QFETCH(bool, startString);
906 QFETCH(bool, midString);
907 QFETCH(bool, endString);
909 QDeclarative1TextEdit textEdit;
910 textEdit.setText(text);
912 // first test that the right string is delivered to the QString::isRightToLeft()
913 QCOMPARE(textEdit.isRightToLeft(0,0), text.mid(0,0).isRightToLeft());
914 QCOMPARE(textEdit.isRightToLeft(0,1), text.mid(0,1).isRightToLeft());
915 QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft());
916 QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft());
917 QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft());
918 QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft());
920 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
921 QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft());
923 // then test that the feature actually works
924 QCOMPARE(textEdit.isRightToLeft(0,0), emptyString);
925 QCOMPARE(textEdit.isRightToLeft(0,1), firstCharacter);
926 QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), lastCharacter);
927 QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter);
928 QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), startString);
929 QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), midString);
931 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
932 QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), endString);
935 void tst_qdeclarativetextedit::keySelection()
937 QDeclarativeView *canvas = createView(SRCDIR "/data/navigation.qml");
939 QApplication::setActiveWindow(canvas);
940 QTest::qWaitForWindowShown(canvas);
941 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
944 QVERIFY(canvas->rootObject() != 0);
946 QDeclarative1TextEdit *input = qobject_cast<QDeclarative1TextEdit *>(qvariant_cast<QObject *>(canvas->rootObject()->property("myInput")));
949 QTRY_VERIFY(input->hasActiveFocus() == true);
951 QSignalSpy spy(input, SIGNAL(selectionChanged()));
953 simulateKey(canvas, Qt::Key_Right, Qt::ShiftModifier);
954 QVERIFY(input->hasActiveFocus() == true);
955 QCOMPARE(input->selectedText(), QString("a"));
956 QCOMPARE(spy.count(), 1);
957 simulateKey(canvas, Qt::Key_Right);
958 QVERIFY(input->hasActiveFocus() == true);
959 QCOMPARE(input->selectedText(), QString());
960 QCOMPARE(spy.count(), 2);
961 simulateKey(canvas, Qt::Key_Right);
962 QVERIFY(input->hasActiveFocus() == false);
963 QCOMPARE(input->selectedText(), QString());
964 QCOMPARE(spy.count(), 2);
966 simulateKey(canvas, Qt::Key_Left);
967 QVERIFY(input->hasActiveFocus() == true);
968 QCOMPARE(spy.count(), 2);
969 simulateKey(canvas, Qt::Key_Left, Qt::ShiftModifier);
970 QVERIFY(input->hasActiveFocus() == true);
971 QCOMPARE(input->selectedText(), QString("a"));
972 QCOMPARE(spy.count(), 3);
973 simulateKey(canvas, Qt::Key_Left);
974 QVERIFY(input->hasActiveFocus() == true);
975 QCOMPARE(input->selectedText(), QString());
976 QCOMPARE(spy.count(), 4);
977 simulateKey(canvas, Qt::Key_Left);
978 QVERIFY(input->hasActiveFocus() == false);
979 QCOMPARE(input->selectedText(), QString());
980 QCOMPARE(spy.count(), 4);
985 void tst_qdeclarativetextedit::moveCursorSelection_data()
987 QTest::addColumn<QString>("testStr");
988 QTest::addColumn<int>("cursorPosition");
989 QTest::addColumn<int>("movePosition");
990 QTest::addColumn<QDeclarative1TextEdit::SelectionMode>("mode");
991 QTest::addColumn<int>("selectionStart");
992 QTest::addColumn<int>("selectionEnd");
993 QTest::addColumn<bool>("reversible");
995 QTest::newRow("(t)he|characters")
996 << standard[0] << 0 << 1 << QDeclarative1TextEdit::SelectCharacters << 0 << 1 << true;
997 QTest::newRow("do(g)|characters")
998 << standard[0] << 43 << 44 << QDeclarative1TextEdit::SelectCharacters << 43 << 44 << true;
999 QTest::newRow("jum(p)ed|characters")
1000 << standard[0] << 23 << 24 << QDeclarative1TextEdit::SelectCharacters << 23 << 24 << true;
1001 QTest::newRow("jumped( )over|characters")
1002 << standard[0] << 26 << 27 << QDeclarative1TextEdit::SelectCharacters << 26 << 27 << true;
1003 QTest::newRow("(the )|characters")
1004 << standard[0] << 0 << 4 << QDeclarative1TextEdit::SelectCharacters << 0 << 4 << true;
1005 QTest::newRow("( dog)|characters")
1006 << standard[0] << 40 << 44 << QDeclarative1TextEdit::SelectCharacters << 40 << 44 << true;
1007 QTest::newRow("( jumped )|characters")
1008 << standard[0] << 19 << 27 << QDeclarative1TextEdit::SelectCharacters << 19 << 27 << true;
1009 QTest::newRow("th(e qu)ick|characters")
1010 << standard[0] << 2 << 6 << QDeclarative1TextEdit::SelectCharacters << 2 << 6 << true;
1011 QTest::newRow("la(zy d)og|characters")
1012 << standard[0] << 38 << 42 << QDeclarative1TextEdit::SelectCharacters << 38 << 42 << true;
1013 QTest::newRow("jum(ped ov)er|characters")
1014 << standard[0] << 23 << 29 << QDeclarative1TextEdit::SelectCharacters << 23 << 29 << true;
1015 QTest::newRow("()the|characters")
1016 << standard[0] << 0 << 0 << QDeclarative1TextEdit::SelectCharacters << 0 << 0 << true;
1017 QTest::newRow("dog()|characters")
1018 << standard[0] << 44 << 44 << QDeclarative1TextEdit::SelectCharacters << 44 << 44 << true;
1019 QTest::newRow("jum()ped|characters")
1020 << standard[0] << 23 << 23 << QDeclarative1TextEdit::SelectCharacters << 23 << 23 << true;
1022 QTest::newRow("<(t)he>|words")
1023 << standard[0] << 0 << 1 << QDeclarative1TextEdit::SelectWords << 0 << 3 << true;
1024 QTest::newRow("<do(g)>|words")
1025 << standard[0] << 43 << 44 << QDeclarative1TextEdit::SelectWords << 41 << 44 << true;
1026 QTest::newRow("<jum(p)ed>|words")
1027 << standard[0] << 23 << 24 << QDeclarative1TextEdit::SelectWords << 20 << 26 << true;
1028 QTest::newRow("<jumped( )>over|words")
1029 << standard[0] << 26 << 27 << QDeclarative1TextEdit::SelectWords << 20 << 27 << false;
1030 QTest::newRow("jumped<( )over>|words,reversed")
1031 << standard[0] << 27 << 26 << QDeclarative1TextEdit::SelectWords << 26 << 31 << false;
1032 QTest::newRow("<(the )>quick|words")
1033 << standard[0] << 0 << 4 << QDeclarative1TextEdit::SelectWords << 0 << 4 << false;
1034 QTest::newRow("<(the )quick>|words,reversed")
1035 << standard[0] << 4 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 9 << false;
1036 QTest::newRow("<lazy( dog)>|words")
1037 << standard[0] << 40 << 44 << QDeclarative1TextEdit::SelectWords << 36 << 44 << false;
1038 QTest::newRow("lazy<( dog)>|words,reversed")
1039 << standard[0] << 44 << 40 << QDeclarative1TextEdit::SelectWords << 40 << 44 << false;
1040 QTest::newRow("<fox( jumped )>over|words")
1041 << standard[0] << 19 << 27 << QDeclarative1TextEdit::SelectWords << 16 << 27 << false;
1042 QTest::newRow("fox<( jumped )over>|words,reversed")
1043 << standard[0] << 27 << 19 << QDeclarative1TextEdit::SelectWords << 19 << 31 << false;
1044 QTest::newRow("<th(e qu)ick>|words")
1045 << standard[0] << 2 << 6 << QDeclarative1TextEdit::SelectWords << 0 << 9 << true;
1046 QTest::newRow("<la(zy d)og|words>")
1047 << standard[0] << 38 << 42 << QDeclarative1TextEdit::SelectWords << 36 << 44 << true;
1048 QTest::newRow("<jum(ped ov)er>|words")
1049 << standard[0] << 23 << 29 << QDeclarative1TextEdit::SelectWords << 20 << 31 << true;
1050 QTest::newRow("<()>the|words")
1051 << standard[0] << 0 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 0 << true;
1052 QTest::newRow("dog<()>|words")
1053 << standard[0] << 44 << 44 << QDeclarative1TextEdit::SelectWords << 44 << 44 << true;
1054 QTest::newRow("jum<()>ped|words")
1055 << standard[0] << 23 << 23 << QDeclarative1TextEdit::SelectWords << 23 << 23 << true;
1057 QTest::newRow("Hello<(,)> |words")
1058 << standard[2] << 5 << 6 << QDeclarative1TextEdit::SelectWords << 5 << 6 << true;
1059 QTest::newRow("Hello<(, )>world|words")
1060 << standard[2] << 5 << 7 << QDeclarative1TextEdit::SelectWords << 5 << 7 << false;
1061 QTest::newRow("Hello<(, )world>|words,reversed")
1062 << standard[2] << 7 << 5 << QDeclarative1TextEdit::SelectWords << 5 << 12 << false;
1063 QTest::newRow("<Hel(lo, )>world|words")
1064 << standard[2] << 3 << 7 << QDeclarative1TextEdit::SelectWords << 0 << 7 << false;
1065 QTest::newRow("<Hel(lo, )world>|words,reversed")
1066 << standard[2] << 7 << 3 << QDeclarative1TextEdit::SelectWords << 0 << 12 << false;
1067 QTest::newRow("<Hel(lo)>,|words")
1068 << standard[2] << 3 << 5 << QDeclarative1TextEdit::SelectWords << 0 << 5 << true;
1069 QTest::newRow("Hello<()>,|words")
1070 << standard[2] << 5 << 5 << QDeclarative1TextEdit::SelectWords << 5 << 5 << true;
1071 QTest::newRow("Hello,<()>|words")
1072 << standard[2] << 6 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 6 << true;
1073 QTest::newRow("Hello<,( )>world|words")
1074 << standard[2] << 6 << 7 << QDeclarative1TextEdit::SelectWords << 5 << 7 << false;
1075 QTest::newRow("Hello,<( )world>|words,reversed")
1076 << standard[2] << 7 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 12 << false;
1077 QTest::newRow("Hello<,( world)>|words")
1078 << standard[2] << 6 << 12 << QDeclarative1TextEdit::SelectWords << 5 << 12 << false;
1079 QTest::newRow("Hello,<( world)>|words,reversed")
1080 << standard[2] << 12 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 12 << false;
1081 QTest::newRow("Hello<,( world!)>|words")
1082 << standard[2] << 6 << 13 << QDeclarative1TextEdit::SelectWords << 5 << 13 << false;
1083 QTest::newRow("Hello,<( world!)>|words,reversed")
1084 << standard[2] << 13 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 13 << false;
1085 QTest::newRow("Hello<(, world!)>|words")
1086 << standard[2] << 5 << 13 << QDeclarative1TextEdit::SelectWords << 5 << 13 << true;
1087 QTest::newRow("world<(!)>|words")
1088 << standard[2] << 12 << 13 << QDeclarative1TextEdit::SelectWords << 12 << 13 << true;
1089 QTest::newRow("world!<()>)|words")
1090 << standard[2] << 13 << 13 << QDeclarative1TextEdit::SelectWords << 13 << 13 << true;
1091 QTest::newRow("world<()>!)|words")
1092 << standard[2] << 12 << 12 << QDeclarative1TextEdit::SelectWords << 12 << 12 << true;
1094 QTest::newRow("<(,)>olleH |words")
1095 << standard[3] << 7 << 8 << QDeclarative1TextEdit::SelectWords << 7 << 8 << true;
1096 QTest::newRow("<dlrow( ,)>olleH|words")
1097 << standard[3] << 6 << 8 << QDeclarative1TextEdit::SelectWords << 1 << 8 << false;
1098 QTest::newRow("dlrow<( ,)>olleH|words,reversed")
1099 << standard[3] << 8 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 8 << false;
1100 QTest::newRow("<dlrow( ,ol)leH>|words")
1101 << standard[3] << 6 << 10 << QDeclarative1TextEdit::SelectWords << 1 << 13 << false;
1102 QTest::newRow("dlrow<( ,ol)leH>|words,reversed")
1103 << standard[3] << 10 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 13 << false;
1104 QTest::newRow(",<(ol)leH>,|words")
1105 << standard[3] << 8 << 10 << QDeclarative1TextEdit::SelectWords << 8 << 13 << true;
1106 QTest::newRow(",<()>olleH|words")
1107 << standard[3] << 8 << 8 << QDeclarative1TextEdit::SelectWords << 8 << 8 << true;
1108 QTest::newRow("<()>,olleH|words")
1109 << standard[3] << 7 << 7 << QDeclarative1TextEdit::SelectWords << 7 << 7 << true;
1110 QTest::newRow("<dlrow( )>,olleH|words")
1111 << standard[3] << 6 << 7 << QDeclarative1TextEdit::SelectWords << 1 << 7 << false;
1112 QTest::newRow("dlrow<( ),>olleH|words,reversed")
1113 << standard[3] << 7 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 8 << false;
1114 QTest::newRow("<(dlrow )>,olleH|words")
1115 << standard[3] << 1 << 7 << QDeclarative1TextEdit::SelectWords << 1 << 7 << false;
1116 QTest::newRow("<(dlrow ),>olleH|words,reversed")
1117 << standard[3] << 7 << 1 << QDeclarative1TextEdit::SelectWords << 1 << 8 << false;
1118 QTest::newRow("<(!dlrow )>,olleH|words")
1119 << standard[3] << 0 << 7 << QDeclarative1TextEdit::SelectWords << 0 << 7 << false;
1120 QTest::newRow("<(!dlrow ),>olleH|words,reversed")
1121 << standard[3] << 7 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 8 << false;
1122 QTest::newRow("(!dlrow ,)olleH|words")
1123 << standard[3] << 0 << 8 << QDeclarative1TextEdit::SelectWords << 0 << 8 << true;
1124 QTest::newRow("<(!)>dlrow|words")
1125 << standard[3] << 0 << 1 << QDeclarative1TextEdit::SelectWords << 0 << 1 << true;
1126 QTest::newRow("<()>!dlrow|words")
1127 << standard[3] << 0 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 0 << true;
1128 QTest::newRow("!<()>dlrow|words")
1129 << standard[3] << 1 << 1 << QDeclarative1TextEdit::SelectWords << 1 << 1 << true;
1132 void tst_qdeclarativetextedit::moveCursorSelection()
1134 QFETCH(QString, testStr);
1135 QFETCH(int, cursorPosition);
1136 QFETCH(int, movePosition);
1137 QFETCH(QDeclarative1TextEdit::SelectionMode, mode);
1138 QFETCH(int, selectionStart);
1139 QFETCH(int, selectionEnd);
1140 QFETCH(bool, reversible);
1142 QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }";
1143 QDeclarativeComponent textinputComponent(&engine);
1144 textinputComponent.setData(componentStr.toLatin1(), QUrl());
1145 QDeclarative1TextEdit *texteditObject = qobject_cast<QDeclarative1TextEdit*>(textinputComponent.create());
1146 QVERIFY(texteditObject != 0);
1148 texteditObject->setCursorPosition(cursorPosition);
1149 texteditObject->moveCursorSelection(movePosition, mode);
1151 QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
1152 QCOMPARE(texteditObject->selectionStart(), selectionStart);
1153 QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
1156 texteditObject->setCursorPosition(movePosition);
1157 texteditObject->moveCursorSelection(cursorPosition, mode);
1159 QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
1160 QCOMPARE(texteditObject->selectionStart(), selectionStart);
1161 QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
1165 void tst_qdeclarativetextedit::moveCursorSelectionSequence_data()
1167 QTest::addColumn<QString>("testStr");
1168 QTest::addColumn<int>("cursorPosition");
1169 QTest::addColumn<int>("movePosition1");
1170 QTest::addColumn<int>("movePosition2");
1171 QTest::addColumn<int>("selection1Start");
1172 QTest::addColumn<int>("selection1End");
1173 QTest::addColumn<int>("selection2Start");
1174 QTest::addColumn<int>("selection2End");
1176 QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr")
1181 QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl")
1186 QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr")
1191 QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl")
1196 QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr")
1201 QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl")
1206 QTest::newRow("the {<quick() ^}bro)wn> fox|ltr")
1211 QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl")
1216 QTest::newRow("the {<quick^}( bro)wn> fox|ltr")
1221 QTest::newRow("the quick{<(^ bro)wn>} fox|rtl")
1226 QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr")
1231 QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl")
1236 QTest::newRow("the {<^quick}( bro)wn> fox|ltr")
1241 QTest::newRow("the {<^quick}( bro)wn> fox|rtl")
1246 QTest::newRow("the{^ <quick}( bro)wn> fox|ltr")
1251 QTest::newRow("the{^ <quick}( bro)wn> fox|rtl")
1256 QTest::newRow("{t^he <quick}( bro)wn> fox|ltr")
1261 QTest::newRow("{t^he <quick}( bro)wn> fox|rtl")
1267 QTest::newRow("{<He(ll)o>, w^orld}!|ltr")
1272 QTest::newRow("{<He(ll)o>, w^orld}!|rtl")
1278 QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr")
1283 QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl")
1290 void tst_qdeclarativetextedit::moveCursorSelectionSequence()
1292 QFETCH(QString, testStr);
1293 QFETCH(int, cursorPosition);
1294 QFETCH(int, movePosition1);
1295 QFETCH(int, movePosition2);
1296 QFETCH(int, selection1Start);
1297 QFETCH(int, selection1End);
1298 QFETCH(int, selection2Start);
1299 QFETCH(int, selection2End);
1301 QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }";
1302 QDeclarativeComponent texteditComponent(&engine);
1303 texteditComponent.setData(componentStr.toLatin1(), QUrl());
1304 QDeclarative1TextEdit *texteditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
1305 QVERIFY(texteditObject != 0);
1307 texteditObject->setCursorPosition(cursorPosition);
1309 texteditObject->moveCursorSelection(movePosition1, QDeclarative1TextEdit::SelectWords);
1310 QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start));
1311 QCOMPARE(texteditObject->selectionStart(), selection1Start);
1312 QCOMPARE(texteditObject->selectionEnd(), selection1End);
1314 texteditObject->moveCursorSelection(movePosition2, QDeclarative1TextEdit::SelectWords);
1315 QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start));
1316 QCOMPARE(texteditObject->selectionStart(), selection2Start);
1317 QCOMPARE(texteditObject->selectionEnd(), selection2End);
1321 void tst_qdeclarativetextedit::mouseSelection_data()
1323 QTest::addColumn<QString>("qmlfile");
1324 QTest::addColumn<int>("from");
1325 QTest::addColumn<int>("to");
1326 QTest::addColumn<QString>("selectedText");
1329 QTest::newRow("on") << SRCDIR "/data/mouseselection_true.qml" << 4 << 9 << "45678";
1330 QTest::newRow("off") << SRCDIR "/data/mouseselection_false.qml" << 4 << 9 << QString();
1331 QTest::newRow("default") << SRCDIR "/data/mouseselection_default.qml" << 4 << 9 << QString();
1332 QTest::newRow("off word selection") << SRCDIR "/data/mouseselection_false_words.qml" << 4 << 9 << QString();
1333 QTest::newRow("on word selection (4,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 4 << 9 << "0123456789";
1334 QTest::newRow("on word selection (2,13)") << SRCDIR "/data/mouseselection_true_words.qml" << 2 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1335 QTest::newRow("on word selection (2,30)") << SRCDIR "/data/mouseselection_true_words.qml" << 2 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1336 QTest::newRow("on word selection (9,13)") << SRCDIR "/data/mouseselection_true_words.qml" << 9 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1337 QTest::newRow("on word selection (9,30)") << SRCDIR "/data/mouseselection_true_words.qml" << 9 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1338 QTest::newRow("on word selection (13,2)") << SRCDIR "/data/mouseselection_true_words.qml" << 13 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1339 QTest::newRow("on word selection (20,2)") << SRCDIR "/data/mouseselection_true_words.qml" << 20 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1340 QTest::newRow("on word selection (12,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 12 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1341 QTest::newRow("on word selection (30,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 30 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1344 void tst_qdeclarativetextedit::mouseSelection()
1346 QFETCH(QString, qmlfile);
1349 QFETCH(QString, selectedText);
1351 QDeclarativeView *canvas = createView(qmlfile);
1354 QApplication::setActiveWindow(canvas);
1355 QTest::qWaitForWindowShown(canvas);
1356 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1358 QVERIFY(canvas->rootObject() != 0);
1359 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1360 QVERIFY(textEditObject != 0);
1362 // press-and-drag-and-release from x1 to x2
1363 QPoint p1 = canvas->mapFromScene(textEditObject->positionToRectangle(from).center());
1364 QPoint p2 = canvas->mapFromScene(textEditObject->positionToRectangle(to).center());
1365 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, p1);
1366 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1367 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(p2), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1368 QApplication::sendEvent(canvas->viewport(), &mv);
1369 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, p2);
1370 QCOMPARE(textEditObject->selectedText(), selectedText);
1372 // Clicking and shift to clicking between the same points should select the same text.
1373 textEditObject->setCursorPosition(0);
1374 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::NoModifier, p1);
1375 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::ShiftModifier, p2);
1376 QCOMPARE(textEditObject->selectedText(), selectedText);
1381 void tst_qdeclarativetextedit::multilineMouseSelection()
1383 QDeclarativeView *canvas = createView(SRCDIR "/data/mouseselection_multiline.qml");
1386 QApplication::setActiveWindow(canvas);
1387 QTest::qWaitForWindowShown(canvas);
1388 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1390 QVERIFY(canvas->rootObject() != 0);
1391 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1392 QVERIFY(textEditObject != 0);
1394 // press-and-drag from x1,y1 to x2,y1
1396 int x2 = textEditObject->width() - 10;
1397 int y1 = textEditObject->height() / 4;
1398 int y2 = textEditObject->height() * 3 / 4;
1399 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y1)));
1400 QMouseEvent mv1(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y1)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1401 QApplication::sendEvent(canvas->viewport(), &mv1);
1402 QString str1 = textEditObject->selectedText();
1403 QVERIFY(str1.length() > 3); // don't reallly care *what* was selected (and it's too sensitive to platform)
1405 // drag-and-release from x2,y1 to x2,y2
1406 QMouseEvent mv2(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y2)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1407 QApplication::sendEvent(canvas->viewport(), &mv2);
1408 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y2)));
1409 QString str2 = textEditObject->selectedText();
1410 QVERIFY(str1 != str2);
1411 QVERIFY(str2.length() > 3);
1416 void tst_qdeclarativetextedit::deferEnableSelectByMouse_data()
1418 QTest::addColumn<QString>("qmlfile");
1420 QTest::newRow("writable") << SRCDIR "/data/mouseselection_false.qml";
1421 QTest::newRow("read only") << SRCDIR "/data/mouseselection_false_readonly.qml";
1424 void tst_qdeclarativetextedit::deferEnableSelectByMouse()
1426 // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed.
1427 QFETCH(QString, qmlfile);
1429 QDeclarativeView *canvas = createView(qmlfile);
1432 QApplication::setActiveWindow(canvas);
1433 QTest::qWaitForWindowShown(canvas);
1434 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1436 QVERIFY(canvas->rootObject() != 0);
1437 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1438 QVERIFY(textEditObject != 0);
1440 // press-and-drag-and-release from x1 to x2
1443 int y = textEditObject->height()/2;
1445 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1446 textEditObject->setSelectByMouse(true);
1447 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1448 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1449 QApplication::sendEvent(canvas->viewport(), &mv);
1450 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1451 QVERIFY(textEditObject->selectedText().isEmpty());
1456 void tst_qdeclarativetextedit::deferDisableSelectByMouse_data()
1458 QTest::addColumn<QString>("qmlfile");
1460 QTest::newRow("writable") << SRCDIR "/data/mouseselection_true.qml";
1461 QTest::newRow("read only") << SRCDIR "/data/mouseselection_true_readonly.qml";
1464 void tst_qdeclarativetextedit::deferDisableSelectByMouse()
1466 // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed.
1467 QFETCH(QString, qmlfile);
1469 QDeclarativeView *canvas = createView(qmlfile);
1472 QApplication::setActiveWindow(canvas);
1473 QTest::qWaitForWindowShown(canvas);
1474 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1476 QVERIFY(canvas->rootObject() != 0);
1477 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1478 QVERIFY(textEditObject != 0);
1480 // press-and-drag-and-release from x1 to x2
1483 int y = textEditObject->height()/2;
1485 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1486 textEditObject->setSelectByMouse(false);
1487 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1488 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1489 QApplication::sendEvent(canvas->viewport(), &mv);
1490 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1491 QVERIFY(textEditObject->selectedText().length() > 3);
1496 void tst_qdeclarativetextedit::dragMouseSelection()
1498 QString qmlfile = SRCDIR "/data/mouseselection_true.qml";
1500 QDeclarativeView *canvas = createView(qmlfile);
1503 QApplication::setActiveWindow(canvas);
1504 QTest::qWaitForWindowShown(canvas);
1505 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1507 QVERIFY(canvas->rootObject() != 0);
1508 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1509 QVERIFY(textEditObject != 0);
1511 textEditObject->setAcceptDrops(true);
1513 // press-and-drag-and-release from x1 to x2
1516 int y = textEditObject->height()/2;
1517 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1519 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1520 QApplication::sendEvent(canvas->viewport(), &mv);
1522 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1523 QString str1 = textEditObject->selectedText();
1524 QVERIFY(str1.length() > 3);
1526 // press and drag the current selection.
1529 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1531 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1532 QApplication::sendEvent(canvas->viewport(), &mv);
1534 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1535 QString str2 = textEditObject->selectedText();
1536 QVERIFY(str2.length() > 3);
1538 QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved.
1543 void tst_qdeclarativetextedit::mouseSelectionMode_data()
1545 QTest::addColumn<QString>("qmlfile");
1546 QTest::addColumn<bool>("selectWords");
1549 QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true;
1550 QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false;
1551 QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false;
1554 void tst_qdeclarativetextedit::mouseSelectionMode()
1556 QFETCH(QString, qmlfile);
1557 QFETCH(bool, selectWords);
1559 QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1561 QDeclarativeView *canvas = createView(qmlfile);
1564 QApplication::setActiveWindow(canvas);
1565 QTest::qWaitForWindowShown(canvas);
1566 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1568 QVERIFY(canvas->rootObject() != 0);
1569 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1570 QVERIFY(textEditObject != 0);
1572 // press-and-drag-and-release from x1 to x2
1575 int y = textEditObject->height()/2;
1576 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1577 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1578 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1579 QApplication::sendEvent(canvas->viewport(), &mv);
1580 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1581 QString str = textEditObject->selectedText();
1583 QCOMPARE(str, text);
1585 QVERIFY(str.length() > 3);
1586 QVERIFY(str != text);
1589 // Clicking and shift to clicking between the same points should select the same text.
1590 textEditObject->setCursorPosition(0);
1591 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::NoModifier, canvas->mapFromScene(QPoint(x1,y)));
1592 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::ShiftModifier, canvas->mapFromScene(QPoint(x2,y)));
1593 QCOMPARE(textEditObject->selectedText(), str);
1598 void tst_qdeclarativetextedit::inputMethodHints()
1600 QDeclarativeView *canvas = createView(SRCDIR "/data/inputmethodhints.qml");
1604 QVERIFY(canvas->rootObject() != 0);
1605 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1606 QVERIFY(textEditObject != 0);
1607 QVERIFY(textEditObject->inputMethodHints() & Qt::ImhNoPredictiveText);
1608 textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly);
1609 QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly);
1614 void tst_qdeclarativetextedit::positionAt()
1616 QDeclarativeView *canvas = createView(SRCDIR "/data/positionAt.qml");
1617 QVERIFY(canvas->rootObject() != 0);
1620 QApplication::setActiveWindow(canvas);
1621 QTest::qWaitForWindowShown(canvas);
1623 QDeclarative1TextEdit *texteditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1624 QVERIFY(texteditObject != 0);
1626 QFontMetrics fm(texteditObject->font());
1627 const int y0 = fm.height() / 2;
1628 const int y1 = fm.height() * 3 / 2;
1630 int pos = texteditObject->positionAt(texteditObject->width()/2, y0);
1631 int diff = abs(int(fm.width(texteditObject->text().left(pos))-texteditObject->width()/2));
1634 QEXPECT_FAIL("", "QTBUG-21016 fails", Continue);
1636 // some tollerance for different fonts.
1643 const qreal x0 = texteditObject->positionToRectangle(pos).x();
1644 const qreal x1 = texteditObject->positionToRectangle(pos + 1).x();
1646 QString preeditText = texteditObject->text().mid(0, pos);
1647 texteditObject->setText(texteditObject->text().mid(pos));
1648 texteditObject->setCursorPosition(0);
1650 QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
1651 QApplication::sendEvent(canvas, &inputEvent);
1653 // Check all points within the preedit text return the same position.
1654 QCOMPARE(texteditObject->positionAt(0, y0), 0);
1655 QCOMPARE(texteditObject->positionAt(x0 / 2, y0), 0);
1656 QCOMPARE(texteditObject->positionAt(x0, y0), 0);
1658 // Verify positioning returns to normal after the preedit text.
1659 QCOMPARE(texteditObject->positionAt(x1, y0), 1);
1660 QCOMPARE(texteditObject->positionToRectangle(1).x(), x1);
1662 QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0);
1667 void tst_qdeclarativetextedit::cursorDelegate()
1669 QDeclarativeView* view = createView(SRCDIR "/data/cursorTest.qml");
1672 QDeclarative1TextEdit *textEditObject = view->rootObject()->findChild<QDeclarative1TextEdit*>("textEditObject");
1673 QVERIFY(textEditObject != 0);
1674 QVERIFY(textEditObject->findChild<QDeclarativeItem*>("cursorInstance"));
1675 //Test Delegate gets created
1676 textEditObject->setFocus(true);
1677 QDeclarativeItem* delegateObject = textEditObject->findChild<QDeclarativeItem*>("cursorInstance");
1678 QVERIFY(delegateObject);
1679 //Test Delegate gets moved
1680 for(int i=0; i<= textEditObject->text().length(); i++){
1681 textEditObject->setCursorPosition(i);
1682 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1683 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1685 const QString preedit = "preedit";
1686 for (int i = 0; i <= preedit.length(); i++) {
1687 QInputMethodEvent event(preedit, QList<QInputMethodEvent::Attribute>()
1688 << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, 1, QVariant()));
1689 QApplication::sendEvent(view, &event);
1691 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1692 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1694 // Clear preedit text;
1695 QInputMethodEvent event;
1696 QApplication::sendEvent(view, &event);
1699 // Test delegate gets moved on mouse press.
1700 textEditObject->setSelectByMouse(true);
1701 textEditObject->setCursorPosition(0);
1702 const QPoint point1 = view->mapFromScene(textEditObject->positionToRectangle(5).center());
1703 QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, point1);
1704 QVERIFY(textEditObject->cursorPosition() != 0);
1705 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1706 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1708 // Test delegate gets moved on mouse drag
1709 textEditObject->setCursorPosition(0);
1710 const QPoint point2 = view->mapFromScene(textEditObject->positionToRectangle(10).center());
1711 QTest::mousePress(view->viewport(), Qt::LeftButton, 0, point1);
1712 QMouseEvent mv(QEvent::MouseMove, point2, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1713 QApplication::sendEvent(view->viewport(), &mv);
1714 QTest::mouseRelease(view->viewport(), Qt::LeftButton, 0, point2);
1715 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1716 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1718 textEditObject->setReadOnly(true);
1719 textEditObject->setCursorPosition(0);
1720 QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(textEditObject->positionToRectangle(5).center()));
1721 QVERIFY(textEditObject->cursorPosition() != 0);
1722 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1723 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1725 textEditObject->setCursorPosition(0);
1726 QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(textEditObject->positionToRectangle(5).center()));
1727 QVERIFY(textEditObject->cursorPosition() != 0);
1728 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1729 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1731 textEditObject->setCursorPosition(0);
1732 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1733 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1734 QVERIFY(textEditObject->cursorRectangle().y() >= 0);
1735 QVERIFY(textEditObject->cursorRectangle().y() < textEditObject->cursorRectangle().height());
1736 textEditObject->setVAlign(QDeclarative1TextEdit::AlignVCenter);
1737 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1738 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1739 QVERIFY(textEditObject->cursorRectangle().y() > (textEditObject->height() / 2) - textEditObject->cursorRectangle().height());
1740 QVERIFY(textEditObject->cursorRectangle().y() < (textEditObject->height() / 2) + textEditObject->cursorRectangle().height());
1741 textEditObject->setVAlign(QDeclarative1TextEdit::AlignBottom);
1742 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1743 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1744 QVERIFY(textEditObject->cursorRectangle().y() > textEditObject->height() - (textEditObject->cursorRectangle().height() * 2));
1745 QVERIFY(textEditObject->cursorRectangle().y() < textEditObject->height());
1747 //Test Delegate gets deleted
1748 textEditObject->setCursorDelegate(0);
1749 QVERIFY(!textEditObject->findChild<QDeclarativeItem*>("cursorInstance"));
1754 void tst_qdeclarativetextedit::cursorVisible()
1756 QGraphicsScene scene;
1757 QGraphicsView view(&scene);
1759 QApplication::setActiveWindow(&view);
1760 QTest::qWaitForWindowShown(&view);
1761 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
1764 QDeclarative1TextEdit edit;
1765 QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool)));
1767 QCOMPARE(edit.isCursorVisible(), false);
1769 edit.setCursorVisible(true);
1770 QCOMPARE(edit.isCursorVisible(), true);
1771 QCOMPARE(spy.count(), 1);
1773 edit.setCursorVisible(false);
1774 QCOMPARE(edit.isCursorVisible(), false);
1775 QCOMPARE(spy.count(), 2);
1777 edit.setFocus(true);
1778 QCOMPARE(edit.isCursorVisible(), false);
1779 QCOMPARE(spy.count(), 2);
1781 scene.addItem(&edit);
1782 QCOMPARE(edit.isCursorVisible(), true);
1783 QCOMPARE(spy.count(), 3);
1785 edit.setFocus(false);
1786 QCOMPARE(edit.isCursorVisible(), false);
1787 QCOMPARE(spy.count(), 4);
1789 edit.setFocus(true);
1790 QCOMPARE(edit.isCursorVisible(), true);
1791 QCOMPARE(spy.count(), 5);
1794 QCOMPARE(edit.isCursorVisible(), false);
1795 QCOMPARE(spy.count(), 6);
1798 QCOMPARE(edit.isCursorVisible(), true);
1799 QCOMPARE(spy.count(), 7);
1802 QCOMPARE(edit.isCursorVisible(), false);
1803 QCOMPARE(spy.count(), 8);
1806 QCOMPARE(edit.isCursorVisible(), true);
1807 QCOMPARE(spy.count(), 9);
1809 // on mac, setActiveWindow(0) on mac does not deactivate the current application
1810 // (you have to switch to a different app or hide the current app to trigger this)
1811 #if !defined(Q_WS_MAC)
1812 QApplication::setActiveWindow(0);
1813 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(0));
1814 QCOMPARE(edit.isCursorVisible(), false);
1815 QCOMPARE(spy.count(), 10);
1817 QApplication::setActiveWindow(&view);
1818 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
1819 QCOMPARE(edit.isCursorVisible(), true);
1820 QCOMPARE(spy.count(), 11);
1824 void tst_qdeclarativetextedit::delegateLoading_data()
1826 QTest::addColumn<QString>("qmlfile");
1827 QTest::addColumn<QString>("error");
1830 QTest::newRow("pass") << "cursorHttpTestPass.qml" << "";
1831 QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "http://localhost:42332/FailItem.qml: Remote host closed the connection ";
1832 QTest::newRow("fail2") << "cursorHttpTestFail2.qml" << "http://localhost:42332/ErrItem.qml:4:5: Fungus is not a type ";
1835 void tst_qdeclarativetextedit::delegateLoading()
1837 QFETCH(QString, qmlfile);
1838 QFETCH(QString, error);
1840 TestHTTPServer server(42332);
1841 server.serveDirectory(SRCDIR "/data/httpfail", TestHTTPServer::Disconnect);
1842 server.serveDirectory(SRCDIR "/data/httpslow", TestHTTPServer::Delay);
1843 server.serveDirectory(SRCDIR "/data/http");
1845 QDeclarativeView* view = new QDeclarativeView(0);
1847 view->setSource(QUrl(QLatin1String("http://localhost:42332/") + qmlfile));
1851 if (!error.isEmpty()) {
1852 QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
1853 QTRY_VERIFY(view->status()==QDeclarativeView::Error);
1854 QTRY_VERIFY(!view->rootObject()); // there is fail item inside this test
1856 QTRY_VERIFY(view->rootObject());//Wait for loading to finish.
1857 QDeclarative1TextEdit *textEditObject = view->rootObject()->findChild<QDeclarative1TextEdit*>("textEditObject");
1858 // view->rootObject()->dumpObjectTree();
1859 QVERIFY(textEditObject != 0);
1860 textEditObject->setFocus(true);
1861 QDeclarativeItem *delegate;
1862 delegate = view->rootObject()->findChild<QDeclarativeItem*>("delegateOkay");
1864 delegate = view->rootObject()->findChild<QDeclarativeItem*>("delegateSlow");
1871 //A test should be added here with a component which is ready but component.create() returns null
1872 //Not sure how to accomplish this with QDeclarative1TextEdits cursor delegate
1873 //###This was only needed for code coverage, and could be a case of overzealous defensive programming
1874 //delegate = view->rootObject()->findChild<QDeclarativeItem*>("delegateErrorB");
1875 //QVERIFY(!delegate);
1881 TextEdit element should only handle left/right keys until the cursor reaches
1882 the extent of the text, then they should ignore the keys.
1884 void tst_qdeclarativetextedit::navigation()
1886 QDeclarativeView *canvas = createView(SRCDIR "/data/navigation.qml");
1890 QVERIFY(canvas->rootObject() != 0);
1892 QDeclarativeItem *input = qobject_cast<QDeclarativeItem *>(qvariant_cast<QObject *>(canvas->rootObject()->property("myInput")));
1894 QVERIFY(input != 0);
1895 QTRY_VERIFY(input->hasActiveFocus() == true);
1896 simulateKey(canvas, Qt::Key_Left);
1897 QVERIFY(input->hasActiveFocus() == false);
1898 simulateKey(canvas, Qt::Key_Right);
1899 QVERIFY(input->hasActiveFocus() == true);
1900 simulateKey(canvas, Qt::Key_Right);
1901 QVERIFY(input->hasActiveFocus() == true);
1902 simulateKey(canvas, Qt::Key_Right);
1903 QVERIFY(input->hasActiveFocus() == false);
1904 simulateKey(canvas, Qt::Key_Left);
1905 QVERIFY(input->hasActiveFocus() == true);
1910 void tst_qdeclarativetextedit::copyAndPaste() {
1911 #ifndef QT_NO_CLIPBOARD
1915 PasteboardRef pasteboard;
1916 OSStatus status = PasteboardCreate(0, &pasteboard);
1917 if (status == noErr)
1918 CFRelease(pasteboard);
1920 QSKIP("This machine doesn't support the clipboard", SkipAll);
1924 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
1925 QDeclarativeComponent textEditComponent(&engine);
1926 textEditComponent.setData(componentStr.toLatin1(), QUrl());
1927 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit*>(textEditComponent.create());
1928 QVERIFY(textEdit != 0);
1931 QCOMPARE(textEdit->text().length(), 12);
1932 textEdit->select(0, textEdit->text().length());;
1934 QCOMPARE(textEdit->selectedText(), QString("Hello world!"));
1935 QCOMPARE(textEdit->selectedText().length(), 12);
1936 textEdit->setCursorPosition(0);
1937 QVERIFY(textEdit->canPaste());
1939 QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
1940 QCOMPARE(textEdit->text().length(), 24);
1943 QVERIFY(textEdit->canPaste());
1944 textEdit->setReadOnly(true);
1945 QVERIFY(!textEdit->canPaste());
1946 textEdit->setReadOnly(false);
1947 QVERIFY(textEdit->canPaste());
1950 // test that document and internal text attribute are in sync
1951 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(textEdit);
1952 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
1953 QCOMPARE(textEdit->text(), editPrivate->text);
1956 textEdit->setCursorPosition(0);
1957 textEdit->selectWord();
1958 QCOMPARE(textEdit->selectedText(), QString("Hello"));
1960 // select all and cut
1961 textEdit->selectAll();
1963 QCOMPARE(textEdit->text().length(), 0);
1965 QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
1966 QCOMPARE(textEdit->text().length(), 24);
1970 void tst_qdeclarativetextedit::canPaste() {
1971 #ifndef QT_NO_CLIPBOARD
1973 QApplication::clipboard()->setText("Some text");
1975 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
1976 QDeclarativeComponent textEditComponent(&engine);
1977 textEditComponent.setData(componentStr.toLatin1(), QUrl());
1978 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit*>(textEditComponent.create());
1979 QVERIFY(textEdit != 0);
1981 // check initial value - QTBUG-17765
1983 QCOMPARE(textEdit->canPaste(), tc.canPaste());
1988 void tst_qdeclarativetextedit::canPasteEmpty() {
1989 #ifndef QT_NO_CLIPBOARD
1991 QApplication::clipboard()->clear();
1993 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
1994 QDeclarativeComponent textEditComponent(&engine);
1995 textEditComponent.setData(componentStr.toLatin1(), QUrl());
1996 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit*>(textEditComponent.create());
1997 QVERIFY(textEdit != 0);
1999 // check initial value - QTBUG-17765
2001 QCOMPARE(textEdit->canPaste(), tc.canPaste());
2006 void tst_qdeclarativetextedit::readOnly()
2008 QDeclarativeView *canvas = createView(SRCDIR "/data/readOnly.qml");
2012 QVERIFY(canvas->rootObject() != 0);
2014 QDeclarative1TextEdit *edit = qobject_cast<QDeclarative1TextEdit *>(qvariant_cast<QObject *>(canvas->rootObject()->property("myInput")));
2017 QTRY_VERIFY(edit->hasActiveFocus() == true);
2018 QVERIFY(edit->isReadOnly() == true);
2019 QString initial = edit->text();
2020 for(int k=Qt::Key_0; k<=Qt::Key_Z; k++)
2021 simulateKey(canvas, k);
2022 simulateKey(canvas, Qt::Key_Return);
2023 simulateKey(canvas, Qt::Key_Space);
2024 simulateKey(canvas, Qt::Key_Escape);
2025 QCOMPARE(edit->text(), initial);
2030 void tst_qdeclarativetextedit::simulateKey(QDeclarativeView *view, int key, Qt::KeyboardModifiers modifiers)
2032 QKeyEvent press(QKeyEvent::KeyPress, key, modifiers);
2033 QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers);
2035 QApplication::sendEvent(view, &press);
2036 QApplication::sendEvent(view, &release);
2039 QDeclarativeView *tst_qdeclarativetextedit::createView(const QString &filename)
2041 QDeclarativeView *canvas = new QDeclarativeView(0);
2043 canvas->setSource(QUrl::fromLocalFile(filename));
2047 class MyInputContext : public QInputContext
2050 MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {}
2051 ~MyInputContext() {}
2053 QString identifierName() { return QString(); }
2054 QString language() { return QString(); }
2058 bool isComposing() const { return false; }
2060 bool filterEvent( const QEvent *event )
2062 if (event->type() == QEvent::RequestSoftwareInputPanel)
2063 openInputPanelReceived = true;
2064 if (event->type() == QEvent::CloseSoftwareInputPanel)
2065 closeInputPanelReceived = true;
2066 return false; //QInputContext::filterEvent(event);
2069 void update() { updateReceived = true; }
2071 void sendPreeditText(const QString &text, int cursor)
2073 QList<QInputMethodEvent::Attribute> attributes;
2074 attributes.append(QInputMethodEvent::Attribute(
2075 QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
2077 QInputMethodEvent event(text, attributes);
2081 void mouseHandler(int x, QMouseEvent *event)
2084 eventType = event->type();
2085 eventPosition = event->pos();
2086 eventGlobalPosition = event->globalPos();
2087 eventButton = event->button();
2088 eventButtons = event->buttons();
2089 eventModifiers = event->modifiers();
2092 bool openInputPanelReceived;
2093 bool closeInputPanelReceived;
2094 bool updateReceived;
2096 QEvent::Type eventType;
2097 QPoint eventPosition;
2098 QPoint eventGlobalPosition;
2099 Qt::MouseButton eventButton;
2100 Qt::MouseButtons eventButtons;
2101 Qt::KeyboardModifiers eventModifiers;
2104 void tst_qdeclarativetextedit::textInput()
2106 QGraphicsScene scene;
2107 QGraphicsView view(&scene);
2108 QDeclarative1TextEdit edit;
2109 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit);
2110 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
2112 scene.addItem(&edit);
2114 QApplication::setActiveWindow(&view);
2115 QTest::qWaitForWindowShown(&view);
2116 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2117 edit.setFocus(true);
2118 QVERIFY(edit.hasActiveFocus() == true);
2120 // test that input method event is committed
2121 QInputMethodEvent event;
2122 event.setCommitString( "Hello world!", 0, 0);
2123 QApplication::sendEvent(&view, &event);
2124 QCOMPARE(edit.text(), QString("Hello world!"));
2127 // test that document and internal text attribute are in sync
2128 QCOMPARE(editPrivate->text, QString("Hello world!"));
2131 void tst_qdeclarativetextedit::openInputPanelOnClick()
2133 QGraphicsScene scene;
2134 QGraphicsView view(&scene);
2136 view.setInputContext(&ic);
2137 QDeclarative1TextEdit edit;
2138 QSignalSpy focusOnPressSpy(&edit, SIGNAL(activeFocusOnPressChanged(bool)));
2139 edit.setText("Hello world");
2141 scene.addItem(&edit);
2143 qApp->setAutoSipEnabled(true);
2144 QApplication::setActiveWindow(&view);
2145 QTest::qWaitForWindowShown(&view);
2146 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2148 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit);
2149 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
2151 // input panel on click
2152 editPrivate->showInputPanelOnFocus = false;
2154 QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
2155 view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
2156 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2157 QApplication::processEvents();
2158 if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) {
2159 QCOMPARE(ic.openInputPanelReceived, false);
2160 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2161 QApplication::processEvents();
2162 QCOMPARE(ic.openInputPanelReceived, true);
2163 } else if (behavior == QStyle::RSIP_OnMouseClick) {
2164 QCOMPARE(ic.openInputPanelReceived, true);
2166 ic.openInputPanelReceived = false;
2168 // focus should not cause input panels to open or close
2169 edit.setFocus(false);
2170 edit.setFocus(true);
2171 edit.setFocus(false);
2172 edit.setFocus(true);
2173 edit.setFocus(false);
2174 QApplication::processEvents();
2175 QCOMPARE(ic.openInputPanelReceived, false);
2176 QCOMPARE(ic.closeInputPanelReceived, false);
2179 void tst_qdeclarativetextedit::openInputPanelOnFocus()
2181 QGraphicsScene scene;
2182 QGraphicsView view(&scene);
2184 view.setInputContext(&ic);
2185 QDeclarative1TextEdit edit;
2186 QSignalSpy focusOnPressSpy(&edit, SIGNAL(activeFocusOnPressChanged(bool)));
2187 edit.setText("Hello world");
2189 scene.addItem(&edit);
2191 qApp->setAutoSipEnabled(true);
2192 QApplication::setActiveWindow(&view);
2193 QTest::qWaitForWindowShown(&view);
2194 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2196 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit);
2197 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
2198 editPrivate->showInputPanelOnFocus = true;
2200 // test default values
2201 QVERIFY(edit.focusOnPress());
2202 QCOMPARE(ic.openInputPanelReceived, false);
2203 QCOMPARE(ic.closeInputPanelReceived, false);
2205 // focus on press, input panel on focus
2206 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2207 QApplication::processEvents();
2208 QVERIFY(edit.hasActiveFocus());
2209 QCOMPARE(ic.openInputPanelReceived, true);
2210 ic.openInputPanelReceived = false;
2212 // no events on release
2213 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2214 QCOMPARE(ic.openInputPanelReceived, false);
2215 ic.openInputPanelReceived = false;
2217 // if already focused, input panel can be opened on press
2218 QVERIFY(edit.hasActiveFocus());
2219 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2220 QApplication::processEvents();
2221 QCOMPARE(ic.openInputPanelReceived, true);
2222 ic.openInputPanelReceived = false;
2224 // input method should stay enabled if focus
2225 // is lost to an item that also accepts inputs
2226 QDeclarative1TextEdit anotherEdit;
2227 scene.addItem(&anotherEdit);
2228 anotherEdit.setFocus(true);
2229 QApplication::processEvents();
2230 QCOMPARE(ic.openInputPanelReceived, true);
2231 ic.openInputPanelReceived = false;
2232 QCOMPARE(view.inputContext(), (QInputContext*)&ic);
2233 QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled));
2235 // input method should be disabled if focus
2236 // is lost to an item that doesn't accept inputs
2237 QDeclarativeItem item;
2238 scene.addItem(&item);
2239 item.setFocus(true);
2240 QApplication::processEvents();
2241 QCOMPARE(ic.openInputPanelReceived, false);
2242 QVERIFY(view.inputContext() == 0);
2243 QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
2245 // no automatic input panel events should
2246 // be sent if activeFocusOnPress is false
2247 edit.setFocusOnPress(false);
2248 QCOMPARE(focusOnPressSpy.count(),1);
2249 edit.setFocusOnPress(false);
2250 QCOMPARE(focusOnPressSpy.count(),1);
2251 edit.setFocus(false);
2252 edit.setFocus(true);
2253 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2254 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2255 QApplication::processEvents();
2256 QCOMPARE(ic.openInputPanelReceived, false);
2257 QCOMPARE(ic.closeInputPanelReceived, false);
2259 // one show input panel event should
2260 // be set when openSoftwareInputPanel is called
2261 edit.openSoftwareInputPanel();
2262 QCOMPARE(ic.openInputPanelReceived, true);
2263 QCOMPARE(ic.closeInputPanelReceived, false);
2264 ic.openInputPanelReceived = false;
2266 // one close input panel event should
2267 // be sent when closeSoftwareInputPanel is called
2268 edit.closeSoftwareInputPanel();
2269 QCOMPARE(ic.openInputPanelReceived, false);
2270 QCOMPARE(ic.closeInputPanelReceived, true);
2271 ic.closeInputPanelReceived = false;
2273 // set activeFocusOnPress back to true
2274 edit.setFocusOnPress(true);
2275 QCOMPARE(focusOnPressSpy.count(),2);
2276 edit.setFocusOnPress(true);
2277 QCOMPARE(focusOnPressSpy.count(),2);
2278 edit.setFocus(false);
2279 QApplication::processEvents();
2280 QCOMPARE(ic.openInputPanelReceived, false);
2281 QCOMPARE(ic.closeInputPanelReceived, false);
2282 ic.closeInputPanelReceived = false;
2284 // input panel should not re-open
2285 // if focus has already been set
2286 edit.setFocus(true);
2287 QCOMPARE(ic.openInputPanelReceived, true);
2288 ic.openInputPanelReceived = false;
2289 edit.setFocus(true);
2290 QCOMPARE(ic.openInputPanelReceived, false);
2292 // input method should be disabled
2293 // if TextEdit loses focus
2294 edit.setFocus(false);
2295 QApplication::processEvents();
2296 QVERIFY(view.inputContext() == 0);
2297 QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
2299 // input method should not be enabled
2300 // if TextEdit is read only.
2301 edit.setReadOnly(true);
2302 ic.openInputPanelReceived = false;
2303 edit.setFocus(true);
2304 QApplication::processEvents();
2305 QCOMPARE(ic.openInputPanelReceived, false);
2306 QVERIFY(view.inputContext() == 0);
2307 QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
2310 void tst_qdeclarativetextedit::geometrySignals()
2312 QDeclarativeComponent component(&engine, SRCDIR "/data/geometrySignals.qml");
2313 QObject *o = component.create();
2315 QCOMPARE(o->property("bindingWidth").toInt(), 400);
2316 QCOMPARE(o->property("bindingHeight").toInt(), 500);
2320 void tst_qdeclarativetextedit::pastingRichText_QTBUG_14003()
2322 #ifndef QT_NO_CLIPBOARD
2323 QString componentStr = "import QtQuick 1.0\nTextEdit { textFormat: TextEdit.PlainText }";
2324 QDeclarativeComponent component(&engine);
2325 component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
2326 QDeclarative1TextEdit *obj = qobject_cast<QDeclarative1TextEdit*>(component.create());
2328 QTRY_VERIFY(obj != 0);
2329 QTRY_VERIFY(obj->textFormat() == QDeclarative1TextEdit::PlainText);
2331 QMimeData *mData = new QMimeData;
2332 mData->setHtml("<font color=\"red\">Hello</font>");
2333 QApplication::clipboard()->setMimeData(mData);
2336 QTRY_VERIFY(obj->text() == "");
2337 QTRY_VERIFY(obj->textFormat() == QDeclarative1TextEdit::PlainText);
2341 void tst_qdeclarativetextedit::implicitSize_data()
2343 QTest::addColumn<QString>("text");
2344 QTest::addColumn<QString>("wrap");
2345 QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap";
2346 QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap";
2347 QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap";
2348 QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap";
2351 void tst_qdeclarativetextedit::implicitSize()
2353 QFETCH(QString, text);
2354 QFETCH(QString, wrap);
2355 QString componentStr = "import QtQuick 1.1\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
2356 QDeclarativeComponent textComponent(&engine);
2357 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
2358 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
2360 QVERIFY(textObject->width() < textObject->implicitWidth());
2361 QVERIFY(textObject->height() == textObject->implicitHeight());
2363 textObject->resetWidth();
2364 QVERIFY(textObject->width() == textObject->implicitWidth());
2365 QVERIFY(textObject->height() == textObject->implicitHeight());
2368 void tst_qdeclarativetextedit::testQtQuick11Attributes()
2370 QFETCH(QString, code);
2371 QFETCH(QString, warning);
2372 QFETCH(QString, error);
2374 QDeclarativeEngine engine;
2377 QDeclarativeComponent valid(&engine);
2378 valid.setData("import QtQuick 1.1; TextEdit { " + code.toUtf8() + " }", QUrl(""));
2379 obj = valid.create();
2381 QVERIFY(valid.errorString().isEmpty());
2384 QDeclarativeComponent invalid(&engine);
2385 invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl(""));
2386 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2387 obj = invalid.create();
2388 QCOMPARE(invalid.errorString(), error);
2392 void tst_qdeclarativetextedit::testQtQuick11Attributes_data()
2394 QTest::addColumn<QString>("code");
2395 QTest::addColumn<QString>("warning");
2396 QTest::addColumn<QString>("error");
2398 QTest::newRow("canPaste") << "property bool foo: canPaste"
2399 << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste"
2402 QTest::newRow("lineCount") << "property int foo: lineCount"
2403 << "<Unknown File>:1: ReferenceError: Can't find variable: lineCount"
2406 QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)"
2407 << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection"
2410 QTest::newRow("deselect") << "Component.onCompleted: deselect()"
2411 << "<Unknown File>:1: ReferenceError: Can't find variable: deselect"
2414 QTest::newRow("onLinkActivated") << "onLinkActivated: {}"
2415 << "QDeclarativeComponent: Component is not ready"
2416 << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n";
2419 void tst_qdeclarativetextedit::preeditMicroFocus()
2421 QString preeditText = "super";
2423 QGraphicsScene scene;
2424 QGraphicsView view(&scene);
2426 view.setInputContext(&ic);
2427 QDeclarative1TextEdit edit;
2428 edit.setFocus(true);
2429 scene.addItem(&edit);
2431 QApplication::setActiveWindow(&view);
2432 QTest::qWaitForWindowShown(&view);
2433 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2435 QSignalSpy cursorRectangleSpy(&edit, SIGNAL(cursorRectangleChanged()));
2438 QRect previousRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2440 // Verify that the micro focus rect is positioned the same for position 0 as
2441 // it would be if there was no preedit text.
2442 ic.updateReceived = false;
2443 ic.sendPreeditText(preeditText, 0);
2444 currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2445 QCOMPARE(currentRect, previousRect);
2446 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
2447 QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed.
2449 QCOMPARE(cursorRectangleSpy.count(), 0);
2451 // Verify that the micro focus rect moves to the left as the cursor position
2453 for (int i = 1; i <= 5; ++i) {
2454 ic.updateReceived = false;
2455 ic.sendPreeditText(preeditText, i);
2456 currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2457 QVERIFY(previousRect.left() < currentRect.left());
2458 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
2459 QCOMPARE(ic.updateReceived, true);
2461 QVERIFY(cursorRectangleSpy.count() > 0);
2462 cursorRectangleSpy.clear();
2463 previousRect = currentRect;
2466 // Verify that if there is no preedit cursor then the micro focus rect is the
2467 // same as it would be if it were positioned at the end of the preedit text.
2468 ic.sendPreeditText(preeditText, 0);
2469 ic.updateReceived = false;
2470 ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
2471 currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2472 QCOMPARE(currentRect, previousRect);
2473 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
2474 QCOMPARE(ic.updateReceived, true);
2476 QVERIFY(cursorRectangleSpy.count() > 0);
2479 void tst_qdeclarativetextedit::inputContextMouseHandler()
2481 QString text = "supercalifragisiticexpialidocious!";
2483 QGraphicsScene scene;
2484 QGraphicsView view(&scene);
2486 view.setInputContext(&ic);
2487 QDeclarative1TextEdit edit;
2490 edit.setText(text.mid(0, 12));
2492 edit.setCursorPosition(12);
2493 edit.setFocus(true);
2494 scene.addItem(&edit);
2496 QApplication::setActiveWindow(&view);
2497 QTest::qWaitForWindowShown(&view);
2498 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2501 QFontMetricsF fm(edit.font());
2502 const qreal y = fm.height() / 2;
2504 QPoint position2 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 2)), y)));
2505 QPoint position8 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 8)), y)));
2506 QPoint position20 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 20)), y)));
2507 QPoint position27 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 27)), y)));
2508 QPoint globalPosition2 = view.viewport()->mapToGlobal(position2);
2509 QPoint globalposition8 = view.viewport()->mapToGlobal(position8);
2510 QPoint globalposition20 = view.viewport()->mapToGlobal(position20);
2511 QPoint globalposition27 = view.viewport()->mapToGlobal(position27);
2513 ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
2515 QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
2516 QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
2517 QCOMPARE(ic.eventPosition, position2);
2518 QCOMPARE(ic.eventGlobalPosition, globalPosition2);
2519 QCOMPARE(ic.eventButton, Qt::LeftButton);
2520 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2521 QVERIFY(ic.cursor < 0);
2522 ic.eventType = QEvent::None;
2524 QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
2525 QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
2526 QCOMPARE(ic.eventPosition, position2);
2527 QCOMPARE(ic.eventGlobalPosition, globalPosition2);
2528 QCOMPARE(ic.eventButton, Qt::LeftButton);
2529 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2530 QVERIFY(ic.cursor < 0);
2531 ic.eventType = QEvent::None;
2533 { QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
2534 QApplication::sendEvent(view.viewport(), &mv); }
2535 QCOMPARE(ic.eventType, QEvent::None);
2537 { QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
2538 QApplication::sendEvent(view.viewport(), &mv); }
2539 QCOMPARE(ic.eventType, QEvent::MouseMove);
2540 QCOMPARE(ic.eventPosition, position27);
2541 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2542 QCOMPARE(ic.eventButton, Qt::LeftButton);
2543 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2544 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); // 15 is expected but some platforms may be off by one.
2545 ic.eventType = QEvent::None;
2547 QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position27);
2548 QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
2549 QCOMPARE(ic.eventPosition, position27);
2550 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2551 QCOMPARE(ic.eventButton, Qt::LeftButton);
2552 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2553 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
2554 ic.eventType = QEvent::None;
2556 // And in the other direction.
2557 QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position27);
2558 QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
2559 QCOMPARE(ic.eventPosition, position27);
2560 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2561 QCOMPARE(ic.eventButton, Qt::LeftButton);
2562 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2563 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
2564 ic.eventType = QEvent::None;
2566 QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position27);
2567 QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
2568 QCOMPARE(ic.eventPosition, position27);
2569 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2570 QCOMPARE(ic.eventButton, Qt::RightButton);
2571 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2572 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
2573 ic.eventType = QEvent::None;
2575 { QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
2576 QApplication::sendEvent(view.viewport(), &mv); }
2577 QCOMPARE(ic.eventType, QEvent::MouseMove);
2578 QCOMPARE(ic.eventPosition, position20);
2579 QCOMPARE(ic.eventGlobalPosition, globalposition20);
2580 QCOMPARE(ic.eventButton, Qt::RightButton);
2581 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2582 QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
2583 ic.eventType = QEvent::None;
2585 { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
2586 QApplication::sendEvent(view.viewport(), &mv); }
2587 QCOMPARE(ic.eventType, QEvent::None);
2589 QTest::mouseRelease(view.viewport(), Qt::RightButton, Qt::ControlModifier, position2);
2590 QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
2591 QCOMPARE(ic.eventPosition, position2);
2592 QCOMPARE(ic.eventGlobalPosition, globalPosition2);
2593 QCOMPARE(ic.eventButton, Qt::RightButton);
2594 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2595 QVERIFY(ic.cursor < 0);
2596 ic.eventType = QEvent::None;
2599 void tst_qdeclarativetextedit::inputMethodComposing()
2601 QString text = "supercalifragisiticexpialidocious!";
2603 QGraphicsScene scene;
2604 QGraphicsView view(&scene);
2606 view.setInputContext(&ic);
2607 QDeclarative1TextEdit edit;
2609 edit.setText(text.mid(0, 12));
2610 edit.setCursorPosition(12);
2612 edit.setFocus(true);
2613 scene.addItem(&edit);
2615 QApplication::setActiveWindow(&view);
2616 QTest::qWaitForWindowShown(&view);
2617 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2619 QSignalSpy spy(&edit, SIGNAL(inputMethodComposingChanged()));
2621 QCOMPARE(edit.isInputMethodComposing(), false);
2623 ic.sendEvent(QInputMethodEvent(text.mid(3), QList<QInputMethodEvent::Attribute>()));
2624 QCOMPARE(edit.isInputMethodComposing(), true);
2625 QCOMPARE(spy.count(), 1);
2627 ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
2628 QCOMPARE(edit.isInputMethodComposing(), true);
2629 QCOMPARE(spy.count(), 1);
2631 ic.sendEvent(QInputMethodEvent());
2632 QCOMPARE(edit.isInputMethodComposing(), false);
2633 QCOMPARE(spy.count(), 2);
2636 void tst_qdeclarativetextedit::cursorRectangleSize()
2638 QDeclarativeView *canvas = createView(SRCDIR "/data/CursorRect.qml");
2639 QVERIFY(canvas->rootObject() != 0);
2642 QApplication::setActiveWindow(canvas);
2643 QTest::qWaitForWindowShown(canvas);
2645 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
2646 QVERIFY(textEdit != 0);
2647 textEdit->setFocus(Qt::OtherFocusReason);
2648 QRectF cursorRect = textEdit->positionToRectangle(textEdit->cursorPosition());
2649 QRectF microFocusFromScene = canvas->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
2650 QRectF microFocusFromApp= QApplication::focusWidget()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
2652 QCOMPARE(microFocusFromScene.size(), cursorRect.size());
2653 QCOMPARE(microFocusFromApp.size(), cursorRect.size());
2655 QTEST_MAIN(tst_qdeclarativetextedit)
2657 #include "tst_qdeclarativetextedit.moc"