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 "../../../shared/util.h"
44 #include "../../declarative/shared/testhttpserver.h"
47 #include <QTextDocument>
48 #include <QtDeclarative/qdeclarativeengine.h>
49 #include <QtDeclarative/qdeclarativecontext.h>
50 #include <QtDeclarative/qdeclarativeexpression.h>
51 #include <QtDeclarative/qdeclarativecomponent.h>
52 #include <QtQuick1/private/qdeclarativetextedit_p.h>
53 #include <QtQuick1/private/qdeclarativetextedit_p_p.h>
54 #include <QFontMetrics>
55 #include <QtQuick1/QDeclarativeView>
58 #include <QInputContext>
61 #include <QtWidgets/5.0.0/QtWidgets/private/qapplication_p.h>
62 #include <private/qtextcontrol_p.h>
65 // In Symbian OS test data is located in applications private dir
69 Q_DECLARE_METATYPE(QDeclarative1TextEdit::SelectionMode)
71 QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual)
73 // XXX This will be replaced by some clever persistent platform image store.
74 QString persistent_dir = SRCDIR "/data";
75 QString arch = "unknown-architecture"; // QTest needs to help with this.
77 QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
79 if (!QFile::exists(expectfile)) {
80 actual.save(expectfile);
81 qWarning() << "created" << expectfile;
88 class tst_qdeclarativetextedit : public QObject
93 tst_qdeclarativetextedit();
101 void alignments_data();
103 // ### these tests may be trivial
105 void hAlign_RightToLeft();
110 void persistentSelection();
113 void isRightToLeft_data();
114 void isRightToLeft();
116 void moveCursorSelection_data();
117 void moveCursorSelection();
118 void moveCursorSelectionSequence_data();
119 void moveCursorSelectionSequence();
120 void mouseSelection_data();
121 void mouseSelection();
122 void multilineMouseSelection();
123 void deferEnableSelectByMouse_data();
124 void deferEnableSelectByMouse();
125 void deferDisableSelectByMouse_data();
126 void deferDisableSelectByMouse();
127 void mouseSelectionMode_data();
128 void mouseSelectionMode();
129 void dragMouseSelection();
130 void inputMethodHints();
134 void cursorDelegate();
135 void cursorVisible();
136 void delegateLoading_data();
137 void delegateLoading();
142 void canPasteEmpty();
144 void openInputPanelOnClick();
145 void openInputPanelOnFocus();
146 void geometrySignals();
147 void pastingRichText_QTBUG_14003();
148 void implicitSize_data();
150 void testQtQuick11Attributes();
151 void testQtQuick11Attributes_data();
153 void preeditMicroFocus();
154 void inputContextMouseHandler();
155 void inputMethodComposing();
156 void cursorRectangleSize();
159 void simulateKey(QDeclarativeView *, int key, Qt::KeyboardModifiers modifiers = 0);
160 QDeclarativeView *createView(const QString &filename);
162 QStringList standard;
163 QStringList richText;
165 QStringList hAlignmentStrings;
166 QStringList vAlignmentStrings;
168 QList<Qt::Alignment> vAlignments;
169 QList<Qt::Alignment> hAlignments;
171 QStringList colorStrings;
173 QDeclarativeEngine engine;
176 tst_qdeclarativetextedit::tst_qdeclarativetextedit()
178 standard << "the quick brown fox jumped over the lazy dog"
179 << "the quick brown fox\n jumped over the lazy dog"
183 richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
184 << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
186 hAlignmentStrings << "AlignLeft"
190 vAlignmentStrings << "AlignTop"
194 hAlignments << Qt::AlignLeft
198 vAlignments << Qt::AlignTop
202 colorStrings << "aliceblue"
215 // need a different test to do alpha channel test
221 void tst_qdeclarativetextedit::text()
224 QDeclarativeComponent texteditComponent(&engine);
225 texteditComponent.setData("import QtQuick 1.0\nTextEdit { text: \"\" }", QUrl());
226 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
228 QVERIFY(textEditObject != 0);
229 QCOMPARE(textEditObject->text(), QString(""));
232 for (int i = 0; i < standard.size(); i++)
234 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
235 QDeclarativeComponent texteditComponent(&engine);
236 texteditComponent.setData(componentStr.toLatin1(), QUrl());
237 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
239 QVERIFY(textEditObject != 0);
240 QCOMPARE(textEditObject->text(), standard.at(i));
243 for (int i = 0; i < richText.size(); i++)
245 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
246 QDeclarativeComponent texteditComponent(&engine);
247 texteditComponent.setData(componentStr.toLatin1(), QUrl());
248 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
250 QVERIFY(textEditObject != 0);
251 QString actual = textEditObject->text();
252 QString expected = richText.at(i);
253 actual.replace(QRegExp(".*<body[^>]*>"),"");
254 actual.replace(QRegExp("(<[^>]*>)+"),"<>");
255 expected.replace(QRegExp("(<[^>]*>)+"),"<>");
256 QCOMPARE(actual.simplified(),expected.simplified());
260 void tst_qdeclarativetextedit::width()
262 // uses Font metrics to find the width for standard and document to find the width for rich
264 QDeclarativeComponent texteditComponent(&engine);
265 texteditComponent.setData("import QtQuick 1.0\nTextEdit { text: \"\" }", QUrl());
266 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
268 QVERIFY(textEditObject != 0);
269 QCOMPARE(textEditObject->width(), 0.0);
272 for (int i = 0; i < standard.size(); i++)
276 qreal metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
277 metricWidth = ceil(metricWidth);
279 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
280 QDeclarativeComponent texteditComponent(&engine);
281 texteditComponent.setData(componentStr.toLatin1(), QUrl());
282 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
284 QVERIFY(textEditObject != 0);
285 QCOMPARE(textEditObject->width(), qreal(metricWidth));
288 for (int i = 0; i < richText.size(); i++)
290 QTextDocument document;
291 document.setHtml(richText.at(i));
292 document.setDocumentMargin(0);
294 int documentWidth = ceil(document.idealWidth());
296 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
297 QDeclarativeComponent texteditComponent(&engine);
298 texteditComponent.setData(componentStr.toLatin1(), QUrl());
299 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
301 QVERIFY(textEditObject != 0);
302 QCOMPARE(textEditObject->width(), qreal(documentWidth));
306 void tst_qdeclarativetextedit::wrap()
308 // for specified width and wrap set true
310 QDeclarativeComponent texteditComponent(&engine);
311 texteditComponent.setData("import QtQuick 1.0\nTextEdit { text: \"\"; wrapMode: TextEdit.WordWrap; width: 300 }", QUrl());
312 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
314 QVERIFY(textEditObject != 0);
315 QCOMPARE(textEditObject->width(), 300.);
318 for (int i = 0; i < standard.size(); i++)
320 QString componentStr = "import QtQuick 1.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + standard.at(i) + "\" }";
321 QDeclarativeComponent texteditComponent(&engine);
322 texteditComponent.setData(componentStr.toLatin1(), QUrl());
323 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
325 QVERIFY(textEditObject != 0);
326 QCOMPARE(textEditObject->width(), 300.);
329 for (int i = 0; i < richText.size(); i++)
331 QString componentStr = "import QtQuick 1.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + richText.at(i) + "\" }";
332 QDeclarativeComponent texteditComponent(&engine);
333 texteditComponent.setData(componentStr.toLatin1(), QUrl());
334 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
336 QVERIFY(textEditObject != 0);
337 QCOMPARE(textEditObject->width(), 300.);
342 void tst_qdeclarativetextedit::textFormat()
345 QDeclarativeComponent textComponent(&engine);
346 textComponent.setData("import QtQuick 1.0\nTextEdit { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
347 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
349 QVERIFY(textObject != 0);
350 QVERIFY(textObject->textFormat() == QDeclarative1TextEdit::RichText);
353 QDeclarativeComponent textComponent(&engine);
354 textComponent.setData("import QtQuick 1.0\nTextEdit { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
355 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
357 QVERIFY(textObject != 0);
358 QVERIFY(textObject->textFormat() == QDeclarative1TextEdit::PlainText);
362 void tst_qdeclarativetextedit::alignments_data()
364 QTest::addColumn<int>("hAlign");
365 QTest::addColumn<int>("vAlign");
366 QTest::addColumn<QString>("expectfile");
368 QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << "alignments_lt";
369 QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << "alignments_rt";
370 QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << "alignments_ct";
372 QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << "alignments_lb";
373 QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << "alignments_rb";
374 QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << "alignments_cb";
376 QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << "alignments_lc";
377 QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << "alignments_rc";
378 QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << "alignments_cc";
382 void tst_qdeclarativetextedit::alignments()
386 QFETCH(QString, expectfile);
388 QDeclarativeView *canvas = createView(SRCDIR "/data/alignments.qml");
391 QApplication::setActiveWindow(canvas);
392 QTest::qWaitForWindowShown(canvas);
393 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
395 QObject *ob = canvas->rootObject();
397 ob->setProperty("horizontalAlignment",hAlign);
398 ob->setProperty("verticalAlignment",vAlign);
399 QTRY_COMPARE(ob->property("running").toBool(),false);
400 QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32);
401 actual.fill(qRgb(255,255,255));
405 expectfile = createExpectedFileIfNotFound(expectfile, actual);
407 QImage expect(expectfile);
409 QCOMPARE(actual,expect);
415 //the alignment tests may be trivial o.oa
416 void tst_qdeclarativetextedit::hAlign()
418 //test one align each, and then test if two align fails.
420 for (int i = 0; i < standard.size(); i++)
422 for (int j=0; j < hAlignmentStrings.size(); j++)
424 QString componentStr = "import QtQuick 1.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
425 QDeclarativeComponent texteditComponent(&engine);
426 texteditComponent.setData(componentStr.toLatin1(), QUrl());
427 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
429 QVERIFY(textEditObject != 0);
430 QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
434 for (int i = 0; i < richText.size(); i++)
436 for (int j=0; j < hAlignmentStrings.size(); j++)
438 QString componentStr = "import QtQuick 1.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
439 QDeclarativeComponent texteditComponent(&engine);
440 texteditComponent.setData(componentStr.toLatin1(), QUrl());
441 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
443 QVERIFY(textEditObject != 0);
444 QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
450 void tst_qdeclarativetextedit::hAlign_RightToLeft()
452 QDeclarativeView *canvas = createView(SRCDIR "/data/horizontalAlignment_RightToLeft.qml");
453 QDeclarative1TextEdit *textEdit = canvas->rootObject()->findChild<QDeclarative1TextEdit*>("text");
454 QVERIFY(textEdit != 0);
457 const QString rtlText = textEdit->text();
459 // implicit alignment should follow the reading direction of text
460 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
461 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
463 // explicitly left aligned
464 textEdit->setHAlign(QDeclarative1TextEdit::AlignLeft);
465 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
466 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
468 // explicitly right aligned
469 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
470 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
471 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
473 QString textString = textEdit->text();
474 textEdit->setText(QString("<i>") + textString + QString("</i>"));
475 textEdit->resetHAlign();
477 // implicitly aligned rich text should follow the reading direction of RTL text
478 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
479 QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
480 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
482 // explicitly left aligned rich text
483 textEdit->setHAlign(QDeclarative1TextEdit::AlignLeft);
484 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
485 QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
486 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
488 // explicitly right aligned rich text
489 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
490 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
491 QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
492 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
494 textEdit->setText(textString);
496 // explicitly center aligned
497 textEdit->setHAlign(QDeclarative1TextEdit::AlignHCenter);
498 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignHCenter);
499 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
501 // reseted alignment should go back to following the text reading direction
502 textEdit->resetHAlign();
503 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
504 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
506 // mirror the text item
507 QDeclarativeItemPrivate::get(textEdit)->setLayoutMirror(true);
509 // mirrored implicit alignment should continue to follow the reading direction of the text
510 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
511 QCOMPARE(textEdit->effectiveHAlign(), QDeclarative1TextEdit::AlignRight);
512 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
514 // mirrored explicitly right aligned behaves as left aligned
515 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
516 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
517 QCOMPARE(textEdit->effectiveHAlign(), QDeclarative1TextEdit::AlignLeft);
518 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
520 // mirrored explicitly left aligned behaves as right aligned
521 textEdit->setHAlign(QDeclarative1TextEdit::AlignLeft);
522 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
523 QCOMPARE(textEdit->effectiveHAlign(), QDeclarative1TextEdit::AlignRight);
524 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
527 QDeclarativeItemPrivate::get(textEdit)->setLayoutMirror(false);
528 textEdit->resetHAlign();
530 // English text should be implicitly left aligned
531 textEdit->setText("Hello world!");
532 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
533 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
535 QApplication::setActiveWindow(canvas);
536 QTest::qWaitForWindowShown(canvas);
537 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
539 textEdit->setText(QString());
540 { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
541 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
542 { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(canvas, &ev); }
543 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignLeft);
545 #ifndef Q_OS_MAC // QTBUG-18040
546 // empty text with implicit alignment follows the system locale-based
547 // keyboard input direction from QApplication::keyboardInputDirection
548 textEdit->setText("");
549 QCOMPARE(textEdit->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
550 QDeclarative1TextEdit::AlignLeft : QDeclarative1TextEdit::AlignRight);
551 if (QApplication::keyboardInputDirection() == Qt::LeftToRight)
552 QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2);
554 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
555 textEdit->setHAlign(QDeclarative1TextEdit::AlignRight);
556 QCOMPARE(textEdit->hAlign(), QDeclarative1TextEdit::AlignRight);
557 QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2);
562 #ifndef Q_OS_MAC // QTBUG-18040
563 // alignment of TextEdit with no text set to it
564 QString componentStr = "import QtQuick 1.0\nTextEdit {}";
565 QDeclarativeComponent textComponent(&engine);
566 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
567 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
568 QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
569 QDeclarative1TextEdit::AlignLeft : QDeclarative1TextEdit::AlignRight);
574 void tst_qdeclarativetextedit::vAlign()
576 //test one align each, and then test if two align fails.
578 for (int i = 0; i < standard.size(); i++)
580 for (int j=0; j < vAlignmentStrings.size(); j++)
582 QString componentStr = "import QtQuick 1.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
583 QDeclarativeComponent texteditComponent(&engine);
584 texteditComponent.setData(componentStr.toLatin1(), QUrl());
585 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
587 QVERIFY(textEditObject != 0);
588 QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
592 for (int i = 0; i < richText.size(); i++)
594 for (int j=0; j < vAlignmentStrings.size(); j++)
596 QString componentStr = "import QtQuick 1.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
597 QDeclarativeComponent texteditComponent(&engine);
598 texteditComponent.setData(componentStr.toLatin1(), QUrl());
599 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
601 QVERIFY(textEditObject != 0);
602 QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
608 void tst_qdeclarativetextedit::font()
610 //test size, then bold, then italic, then family
612 QString componentStr = "import QtQuick 1.0\nTextEdit { font.pointSize: 40; text: \"Hello World\" }";
613 QDeclarativeComponent texteditComponent(&engine);
614 texteditComponent.setData(componentStr.toLatin1(), QUrl());
615 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
617 QVERIFY(textEditObject != 0);
618 QCOMPARE(textEditObject->font().pointSize(), 40);
619 QCOMPARE(textEditObject->font().bold(), false);
620 QCOMPARE(textEditObject->font().italic(), false);
624 QString componentStr = "import QtQuick 1.0\nTextEdit { font.bold: true; text: \"Hello World\" }";
625 QDeclarativeComponent texteditComponent(&engine);
626 texteditComponent.setData(componentStr.toLatin1(), QUrl());
627 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
629 QVERIFY(textEditObject != 0);
630 QCOMPARE(textEditObject->font().bold(), true);
631 QCOMPARE(textEditObject->font().italic(), false);
635 QString componentStr = "import QtQuick 1.0\nTextEdit { font.italic: true; text: \"Hello World\" }";
636 QDeclarativeComponent texteditComponent(&engine);
637 texteditComponent.setData(componentStr.toLatin1(), QUrl());
638 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
640 QVERIFY(textEditObject != 0);
641 QCOMPARE(textEditObject->font().italic(), true);
642 QCOMPARE(textEditObject->font().bold(), false);
646 QString componentStr = "import QtQuick 1.0\nTextEdit { font.family: \"Helvetica\"; text: \"Hello World\" }";
647 QDeclarativeComponent texteditComponent(&engine);
648 texteditComponent.setData(componentStr.toLatin1(), QUrl());
649 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
651 QVERIFY(textEditObject != 0);
652 QCOMPARE(textEditObject->font().family(), QString("Helvetica"));
653 QCOMPARE(textEditObject->font().bold(), false);
654 QCOMPARE(textEditObject->font().italic(), false);
658 QString componentStr = "import QtQuick 1.0\nTextEdit { font.family: \"\"; text: \"Hello World\" }";
659 QDeclarativeComponent texteditComponent(&engine);
660 texteditComponent.setData(componentStr.toLatin1(), QUrl());
661 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
663 QVERIFY(textEditObject != 0);
664 QCOMPARE(textEditObject->font().family(), QString(""));
668 void tst_qdeclarativetextedit::color()
672 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello World\" }";
673 QDeclarativeComponent texteditComponent(&engine);
674 texteditComponent.setData(componentStr.toLatin1(), QUrl());
675 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
677 QDeclarative1TextEditPrivate *textEditPrivate = static_cast<QDeclarative1TextEditPrivate*>(QDeclarativeItemPrivate::get(textEditObject));
679 QVERIFY(textEditObject);
680 QVERIFY(textEditPrivate);
681 QVERIFY(textEditPrivate->control);
683 QPalette pal = textEditPrivate->control->palette();
684 QCOMPARE(textEditPrivate->color, QColor("black"));
685 QCOMPARE(textEditPrivate->color, pal.color(QPalette::Text));
688 for (int i = 0; i < colorStrings.size(); i++)
690 QString componentStr = "import QtQuick 1.0\nTextEdit { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
691 QDeclarativeComponent texteditComponent(&engine);
692 texteditComponent.setData(componentStr.toLatin1(), QUrl());
693 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
694 //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i));
695 QVERIFY(textEditObject != 0);
696 QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i)));
700 for (int i = 0; i < colorStrings.size(); i++)
702 QString componentStr = "import QtQuick 1.0\nTextEdit { selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
703 QDeclarativeComponent texteditComponent(&engine);
704 texteditComponent.setData(componentStr.toLatin1(), QUrl());
705 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
706 QVERIFY(textEditObject != 0);
707 QCOMPARE(textEditObject->selectionColor(), QColor(colorStrings.at(i)));
711 for (int i = 0; i < colorStrings.size(); i++)
713 QString componentStr = "import QtQuick 1.0\nTextEdit { selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
714 QDeclarativeComponent texteditComponent(&engine);
715 texteditComponent.setData(componentStr.toLatin1(), QUrl());
716 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
717 QVERIFY(textEditObject != 0);
718 QCOMPARE(textEditObject->selectedTextColor(), QColor(colorStrings.at(i)));
722 QString colorStr = "#AA001234";
723 QColor testColor("#001234");
724 testColor.setAlpha(170);
726 QString componentStr = "import QtQuick 1.0\nTextEdit { color: \"" + colorStr + "\"; text: \"Hello World\" }";
727 QDeclarativeComponent texteditComponent(&engine);
728 texteditComponent.setData(componentStr.toLatin1(), QUrl());
729 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
731 QVERIFY(textEditObject != 0);
732 QCOMPARE(textEditObject->color(), testColor);
736 void tst_qdeclarativetextedit::textMargin()
738 for(qreal i=0; i<=10; i+=0.3){
739 QString componentStr = "import QtQuick 1.0\nTextEdit { textMargin: " + QString::number(i) + "; text: \"Hello World\" }";
740 QDeclarativeComponent texteditComponent(&engine);
741 texteditComponent.setData(componentStr.toLatin1(), QUrl());
742 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
743 QVERIFY(textEditObject != 0);
744 QCOMPARE(textEditObject->textMargin(), i);
748 void tst_qdeclarativetextedit::persistentSelection()
751 QString componentStr = "import QtQuick 1.0\nTextEdit { persistentSelection: true; text: \"Hello World\" }";
752 QDeclarativeComponent texteditComponent(&engine);
753 texteditComponent.setData(componentStr.toLatin1(), QUrl());
754 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
755 QVERIFY(textEditObject != 0);
756 QCOMPARE(textEditObject->persistentSelection(), true);
760 QString componentStr = "import QtQuick 1.0\nTextEdit { persistentSelection: false; text: \"Hello World\" }";
761 QDeclarativeComponent texteditComponent(&engine);
762 texteditComponent.setData(componentStr.toLatin1(), QUrl());
763 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
764 QVERIFY(textEditObject != 0);
765 QCOMPARE(textEditObject->persistentSelection(), false);
769 void tst_qdeclarativetextedit::focusOnPress()
772 QString componentStr = "import QtQuick 1.0\nTextEdit { activeFocusOnPress: true; text: \"Hello World\" }";
773 QDeclarativeComponent texteditComponent(&engine);
774 texteditComponent.setData(componentStr.toLatin1(), QUrl());
775 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
776 QVERIFY(textEditObject != 0);
777 QCOMPARE(textEditObject->focusOnPress(), true);
781 QString componentStr = "import QtQuick 1.0\nTextEdit { activeFocusOnPress: false; text: \"Hello World\" }";
782 QDeclarativeComponent texteditComponent(&engine);
783 texteditComponent.setData(componentStr.toLatin1(), QUrl());
784 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
785 QVERIFY(textEditObject != 0);
786 QCOMPARE(textEditObject->focusOnPress(), false);
790 void tst_qdeclarativetextedit::selection()
792 QString testStr = standard[0];//TODO: What should happen for multiline/rich text?
793 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \""+ testStr +"\"; }";
794 QDeclarativeComponent texteditComponent(&engine);
795 texteditComponent.setData(componentStr.toLatin1(), QUrl());
796 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
797 QVERIFY(textEditObject != 0);
800 //Test selection follows cursor
801 for(int i=0; i<= testStr.size(); i++) {
802 textEditObject->setCursorPosition(i);
803 QCOMPARE(textEditObject->cursorPosition(), i);
804 QCOMPARE(textEditObject->selectionStart(), i);
805 QCOMPARE(textEditObject->selectionEnd(), i);
806 QVERIFY(textEditObject->selectedText().isNull());
808 //Test cursor follows selection
809 for(int i=0; i<= testStr.size(); i++) {
810 textEditObject->select(i,i);
811 QCOMPARE(textEditObject->cursorPosition(), i);
812 QCOMPARE(textEditObject->selectionStart(), i);
813 QCOMPARE(textEditObject->selectionEnd(), i);
817 textEditObject->setCursorPosition(0);
818 QVERIFY(textEditObject->cursorPosition() == 0);
819 QVERIFY(textEditObject->selectionStart() == 0);
820 QVERIFY(textEditObject->selectionEnd() == 0);
821 QVERIFY(textEditObject->selectedText().isNull());
823 // Verify invalid positions are ignored.
824 textEditObject->setCursorPosition(-1);
825 QVERIFY(textEditObject->cursorPosition() == 0);
826 QVERIFY(textEditObject->selectionStart() == 0);
827 QVERIFY(textEditObject->selectionEnd() == 0);
828 QVERIFY(textEditObject->selectedText().isNull());
830 textEditObject->setCursorPosition(textEditObject->text().count()+1);
831 QVERIFY(textEditObject->cursorPosition() == 0);
832 QVERIFY(textEditObject->selectionStart() == 0);
833 QVERIFY(textEditObject->selectionEnd() == 0);
834 QVERIFY(textEditObject->selectedText().isNull());
837 for(int i=0; i<= testStr.size(); i++) {
838 textEditObject->select(0,i);
839 QCOMPARE(testStr.mid(0,i), textEditObject->selectedText());
840 QCOMPARE(textEditObject->cursorPosition(), i);
842 for(int i=0; i<= testStr.size(); i++) {
843 textEditObject->select(i,testStr.size());
844 QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText());
845 QCOMPARE(textEditObject->cursorPosition(), testStr.size());
848 textEditObject->setCursorPosition(0);
849 QVERIFY(textEditObject->cursorPosition() == 0);
850 QVERIFY(textEditObject->selectionStart() == 0);
851 QVERIFY(textEditObject->selectionEnd() == 0);
852 QVERIFY(textEditObject->selectedText().isNull());
854 //Test Error Ignoring behaviour
855 textEditObject->setCursorPosition(0);
856 QVERIFY(textEditObject->selectedText().isNull());
857 textEditObject->select(-10,0);
858 QVERIFY(textEditObject->selectedText().isNull());
859 textEditObject->select(100,101);
860 QVERIFY(textEditObject->selectedText().isNull());
861 textEditObject->select(0,-10);
862 QVERIFY(textEditObject->selectedText().isNull());
863 textEditObject->select(0,100);
864 QVERIFY(textEditObject->selectedText().isNull());
865 textEditObject->select(0,10);
866 QVERIFY(textEditObject->selectedText().size() == 10);
867 textEditObject->select(-10,0);
868 QVERIFY(textEditObject->selectedText().size() == 10);
869 textEditObject->select(100,101);
870 QVERIFY(textEditObject->selectedText().size() == 10);
871 textEditObject->select(0,-10);
872 QVERIFY(textEditObject->selectedText().size() == 10);
873 textEditObject->select(0,100);
874 QVERIFY(textEditObject->selectedText().size() == 10);
876 textEditObject->deselect();
877 QVERIFY(textEditObject->selectedText().isNull());
878 textEditObject->select(0,10);
879 QVERIFY(textEditObject->selectedText().size() == 10);
880 textEditObject->deselect();
881 QVERIFY(textEditObject->selectedText().isNull());
884 void tst_qdeclarativetextedit::isRightToLeft_data()
886 QTest::addColumn<QString>("text");
887 QTest::addColumn<bool>("emptyString");
888 QTest::addColumn<bool>("firstCharacter");
889 QTest::addColumn<bool>("lastCharacter");
890 QTest::addColumn<bool>("middleCharacter");
891 QTest::addColumn<bool>("startString");
892 QTest::addColumn<bool>("midString");
893 QTest::addColumn<bool>("endString");
895 const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
896 QTest::newRow("Empty") << "" << false << false << false << false << false << false << false;
897 QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false;
898 QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false;
899 QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true;
900 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;
901 QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false;
904 void tst_qdeclarativetextedit::isRightToLeft()
906 QFETCH(QString, text);
907 QFETCH(bool, emptyString);
908 QFETCH(bool, firstCharacter);
909 QFETCH(bool, lastCharacter);
910 QFETCH(bool, middleCharacter);
911 QFETCH(bool, startString);
912 QFETCH(bool, midString);
913 QFETCH(bool, endString);
915 QDeclarative1TextEdit textEdit;
916 textEdit.setText(text);
918 // first test that the right string is delivered to the QString::isRightToLeft()
919 QCOMPARE(textEdit.isRightToLeft(0,0), text.mid(0,0).isRightToLeft());
920 QCOMPARE(textEdit.isRightToLeft(0,1), text.mid(0,1).isRightToLeft());
921 QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft());
922 QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft());
923 QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft());
924 QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft());
926 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
927 QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft());
929 // then test that the feature actually works
930 QCOMPARE(textEdit.isRightToLeft(0,0), emptyString);
931 QCOMPARE(textEdit.isRightToLeft(0,1), firstCharacter);
932 QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), lastCharacter);
933 QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter);
934 QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), startString);
935 QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), midString);
937 QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
938 QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), endString);
941 void tst_qdeclarativetextedit::keySelection()
943 QDeclarativeView *canvas = createView(SRCDIR "/data/navigation.qml");
945 QApplication::setActiveWindow(canvas);
946 QTest::qWaitForWindowShown(canvas);
947 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
950 QVERIFY(canvas->rootObject() != 0);
952 QDeclarative1TextEdit *input = qobject_cast<QDeclarative1TextEdit *>(qvariant_cast<QObject *>(canvas->rootObject()->property("myInput")));
955 QTRY_VERIFY(input->hasActiveFocus() == true);
957 QSignalSpy spy(input, SIGNAL(selectionChanged()));
959 simulateKey(canvas, Qt::Key_Right, Qt::ShiftModifier);
960 QVERIFY(input->hasActiveFocus() == true);
961 QCOMPARE(input->selectedText(), QString("a"));
962 QCOMPARE(spy.count(), 1);
963 simulateKey(canvas, Qt::Key_Right);
964 QVERIFY(input->hasActiveFocus() == true);
965 QCOMPARE(input->selectedText(), QString());
966 QCOMPARE(spy.count(), 2);
967 simulateKey(canvas, Qt::Key_Right);
968 QVERIFY(input->hasActiveFocus() == false);
969 QCOMPARE(input->selectedText(), QString());
970 QCOMPARE(spy.count(), 2);
972 simulateKey(canvas, Qt::Key_Left);
973 QVERIFY(input->hasActiveFocus() == true);
974 QCOMPARE(spy.count(), 2);
975 simulateKey(canvas, Qt::Key_Left, Qt::ShiftModifier);
976 QVERIFY(input->hasActiveFocus() == true);
977 QCOMPARE(input->selectedText(), QString("a"));
978 QCOMPARE(spy.count(), 3);
979 simulateKey(canvas, Qt::Key_Left);
980 QVERIFY(input->hasActiveFocus() == true);
981 QCOMPARE(input->selectedText(), QString());
982 QCOMPARE(spy.count(), 4);
983 simulateKey(canvas, Qt::Key_Left);
984 QVERIFY(input->hasActiveFocus() == false);
985 QCOMPARE(input->selectedText(), QString());
986 QCOMPARE(spy.count(), 4);
991 void tst_qdeclarativetextedit::moveCursorSelection_data()
993 QTest::addColumn<QString>("testStr");
994 QTest::addColumn<int>("cursorPosition");
995 QTest::addColumn<int>("movePosition");
996 QTest::addColumn<QDeclarative1TextEdit::SelectionMode>("mode");
997 QTest::addColumn<int>("selectionStart");
998 QTest::addColumn<int>("selectionEnd");
999 QTest::addColumn<bool>("reversible");
1001 QTest::newRow("(t)he|characters")
1002 << standard[0] << 0 << 1 << QDeclarative1TextEdit::SelectCharacters << 0 << 1 << true;
1003 QTest::newRow("do(g)|characters")
1004 << standard[0] << 43 << 44 << QDeclarative1TextEdit::SelectCharacters << 43 << 44 << true;
1005 QTest::newRow("jum(p)ed|characters")
1006 << standard[0] << 23 << 24 << QDeclarative1TextEdit::SelectCharacters << 23 << 24 << true;
1007 QTest::newRow("jumped( )over|characters")
1008 << standard[0] << 26 << 27 << QDeclarative1TextEdit::SelectCharacters << 26 << 27 << true;
1009 QTest::newRow("(the )|characters")
1010 << standard[0] << 0 << 4 << QDeclarative1TextEdit::SelectCharacters << 0 << 4 << true;
1011 QTest::newRow("( dog)|characters")
1012 << standard[0] << 40 << 44 << QDeclarative1TextEdit::SelectCharacters << 40 << 44 << true;
1013 QTest::newRow("( jumped )|characters")
1014 << standard[0] << 19 << 27 << QDeclarative1TextEdit::SelectCharacters << 19 << 27 << true;
1015 QTest::newRow("th(e qu)ick|characters")
1016 << standard[0] << 2 << 6 << QDeclarative1TextEdit::SelectCharacters << 2 << 6 << true;
1017 QTest::newRow("la(zy d)og|characters")
1018 << standard[0] << 38 << 42 << QDeclarative1TextEdit::SelectCharacters << 38 << 42 << true;
1019 QTest::newRow("jum(ped ov)er|characters")
1020 << standard[0] << 23 << 29 << QDeclarative1TextEdit::SelectCharacters << 23 << 29 << true;
1021 QTest::newRow("()the|characters")
1022 << standard[0] << 0 << 0 << QDeclarative1TextEdit::SelectCharacters << 0 << 0 << true;
1023 QTest::newRow("dog()|characters")
1024 << standard[0] << 44 << 44 << QDeclarative1TextEdit::SelectCharacters << 44 << 44 << true;
1025 QTest::newRow("jum()ped|characters")
1026 << standard[0] << 23 << 23 << QDeclarative1TextEdit::SelectCharacters << 23 << 23 << true;
1028 QTest::newRow("<(t)he>|words")
1029 << standard[0] << 0 << 1 << QDeclarative1TextEdit::SelectWords << 0 << 3 << true;
1030 QTest::newRow("<do(g)>|words")
1031 << standard[0] << 43 << 44 << QDeclarative1TextEdit::SelectWords << 41 << 44 << true;
1032 QTest::newRow("<jum(p)ed>|words")
1033 << standard[0] << 23 << 24 << QDeclarative1TextEdit::SelectWords << 20 << 26 << true;
1034 QTest::newRow("<jumped( )>over|words")
1035 << standard[0] << 26 << 27 << QDeclarative1TextEdit::SelectWords << 20 << 27 << false;
1036 QTest::newRow("jumped<( )over>|words,reversed")
1037 << standard[0] << 27 << 26 << QDeclarative1TextEdit::SelectWords << 26 << 31 << false;
1038 QTest::newRow("<(the )>quick|words")
1039 << standard[0] << 0 << 4 << QDeclarative1TextEdit::SelectWords << 0 << 4 << false;
1040 QTest::newRow("<(the )quick>|words,reversed")
1041 << standard[0] << 4 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 9 << false;
1042 QTest::newRow("<lazy( dog)>|words")
1043 << standard[0] << 40 << 44 << QDeclarative1TextEdit::SelectWords << 36 << 44 << false;
1044 QTest::newRow("lazy<( dog)>|words,reversed")
1045 << standard[0] << 44 << 40 << QDeclarative1TextEdit::SelectWords << 40 << 44 << false;
1046 QTest::newRow("<fox( jumped )>over|words")
1047 << standard[0] << 19 << 27 << QDeclarative1TextEdit::SelectWords << 16 << 27 << false;
1048 QTest::newRow("fox<( jumped )over>|words,reversed")
1049 << standard[0] << 27 << 19 << QDeclarative1TextEdit::SelectWords << 19 << 31 << false;
1050 QTest::newRow("<th(e qu)ick>|words")
1051 << standard[0] << 2 << 6 << QDeclarative1TextEdit::SelectWords << 0 << 9 << true;
1052 QTest::newRow("<la(zy d)og|words>")
1053 << standard[0] << 38 << 42 << QDeclarative1TextEdit::SelectWords << 36 << 44 << true;
1054 QTest::newRow("<jum(ped ov)er>|words")
1055 << standard[0] << 23 << 29 << QDeclarative1TextEdit::SelectWords << 20 << 31 << true;
1056 QTest::newRow("<()>the|words")
1057 << standard[0] << 0 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 0 << true;
1058 QTest::newRow("dog<()>|words")
1059 << standard[0] << 44 << 44 << QDeclarative1TextEdit::SelectWords << 44 << 44 << true;
1060 QTest::newRow("jum<()>ped|words")
1061 << standard[0] << 23 << 23 << QDeclarative1TextEdit::SelectWords << 23 << 23 << true;
1063 QTest::newRow("Hello<(,)> |words")
1064 << standard[2] << 5 << 6 << QDeclarative1TextEdit::SelectWords << 5 << 6 << true;
1065 QTest::newRow("Hello<(, )>world|words")
1066 << standard[2] << 5 << 7 << QDeclarative1TextEdit::SelectWords << 5 << 7 << false;
1067 QTest::newRow("Hello<(, )world>|words,reversed")
1068 << standard[2] << 7 << 5 << QDeclarative1TextEdit::SelectWords << 5 << 12 << false;
1069 QTest::newRow("<Hel(lo, )>world|words")
1070 << standard[2] << 3 << 7 << QDeclarative1TextEdit::SelectWords << 0 << 7 << false;
1071 QTest::newRow("<Hel(lo, )world>|words,reversed")
1072 << standard[2] << 7 << 3 << QDeclarative1TextEdit::SelectWords << 0 << 12 << false;
1073 QTest::newRow("<Hel(lo)>,|words")
1074 << standard[2] << 3 << 5 << QDeclarative1TextEdit::SelectWords << 0 << 5 << true;
1075 QTest::newRow("Hello<()>,|words")
1076 << standard[2] << 5 << 5 << QDeclarative1TextEdit::SelectWords << 5 << 5 << true;
1077 QTest::newRow("Hello,<()>|words")
1078 << standard[2] << 6 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 6 << true;
1079 QTest::newRow("Hello<,( )>world|words")
1080 << standard[2] << 6 << 7 << QDeclarative1TextEdit::SelectWords << 5 << 7 << false;
1081 QTest::newRow("Hello,<( )world>|words,reversed")
1082 << standard[2] << 7 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 12 << false;
1083 QTest::newRow("Hello<,( world)>|words")
1084 << standard[2] << 6 << 12 << QDeclarative1TextEdit::SelectWords << 5 << 12 << false;
1085 QTest::newRow("Hello,<( world)>|words,reversed")
1086 << standard[2] << 12 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 12 << false;
1087 QTest::newRow("Hello<,( world!)>|words")
1088 << standard[2] << 6 << 13 << QDeclarative1TextEdit::SelectWords << 5 << 13 << false;
1089 QTest::newRow("Hello,<( world!)>|words,reversed")
1090 << standard[2] << 13 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 13 << false;
1091 QTest::newRow("Hello<(, world!)>|words")
1092 << standard[2] << 5 << 13 << QDeclarative1TextEdit::SelectWords << 5 << 13 << true;
1093 QTest::newRow("world<(!)>|words")
1094 << standard[2] << 12 << 13 << QDeclarative1TextEdit::SelectWords << 12 << 13 << true;
1095 QTest::newRow("world!<()>)|words")
1096 << standard[2] << 13 << 13 << QDeclarative1TextEdit::SelectWords << 13 << 13 << true;
1097 QTest::newRow("world<()>!)|words")
1098 << standard[2] << 12 << 12 << QDeclarative1TextEdit::SelectWords << 12 << 12 << true;
1100 QTest::newRow("<(,)>olleH |words")
1101 << standard[3] << 7 << 8 << QDeclarative1TextEdit::SelectWords << 7 << 8 << true;
1102 QTest::newRow("<dlrow( ,)>olleH|words")
1103 << standard[3] << 6 << 8 << QDeclarative1TextEdit::SelectWords << 1 << 8 << false;
1104 QTest::newRow("dlrow<( ,)>olleH|words,reversed")
1105 << standard[3] << 8 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 8 << false;
1106 QTest::newRow("<dlrow( ,ol)leH>|words")
1107 << standard[3] << 6 << 10 << QDeclarative1TextEdit::SelectWords << 1 << 13 << false;
1108 QTest::newRow("dlrow<( ,ol)leH>|words,reversed")
1109 << standard[3] << 10 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 13 << false;
1110 QTest::newRow(",<(ol)leH>,|words")
1111 << standard[3] << 8 << 10 << QDeclarative1TextEdit::SelectWords << 8 << 13 << true;
1112 QTest::newRow(",<()>olleH|words")
1113 << standard[3] << 8 << 8 << QDeclarative1TextEdit::SelectWords << 8 << 8 << true;
1114 QTest::newRow("<()>,olleH|words")
1115 << standard[3] << 7 << 7 << QDeclarative1TextEdit::SelectWords << 7 << 7 << true;
1116 QTest::newRow("<dlrow( )>,olleH|words")
1117 << standard[3] << 6 << 7 << QDeclarative1TextEdit::SelectWords << 1 << 7 << false;
1118 QTest::newRow("dlrow<( ),>olleH|words,reversed")
1119 << standard[3] << 7 << 6 << QDeclarative1TextEdit::SelectWords << 6 << 8 << false;
1120 QTest::newRow("<(dlrow )>,olleH|words")
1121 << standard[3] << 1 << 7 << QDeclarative1TextEdit::SelectWords << 1 << 7 << false;
1122 QTest::newRow("<(dlrow ),>olleH|words,reversed")
1123 << standard[3] << 7 << 1 << QDeclarative1TextEdit::SelectWords << 1 << 8 << false;
1124 QTest::newRow("<(!dlrow )>,olleH|words")
1125 << standard[3] << 0 << 7 << QDeclarative1TextEdit::SelectWords << 0 << 7 << false;
1126 QTest::newRow("<(!dlrow ),>olleH|words,reversed")
1127 << standard[3] << 7 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 8 << false;
1128 QTest::newRow("(!dlrow ,)olleH|words")
1129 << standard[3] << 0 << 8 << QDeclarative1TextEdit::SelectWords << 0 << 8 << true;
1130 QTest::newRow("<(!)>dlrow|words")
1131 << standard[3] << 0 << 1 << QDeclarative1TextEdit::SelectWords << 0 << 1 << true;
1132 QTest::newRow("<()>!dlrow|words")
1133 << standard[3] << 0 << 0 << QDeclarative1TextEdit::SelectWords << 0 << 0 << true;
1134 QTest::newRow("!<()>dlrow|words")
1135 << standard[3] << 1 << 1 << QDeclarative1TextEdit::SelectWords << 1 << 1 << true;
1138 void tst_qdeclarativetextedit::moveCursorSelection()
1140 QFETCH(QString, testStr);
1141 QFETCH(int, cursorPosition);
1142 QFETCH(int, movePosition);
1143 QFETCH(QDeclarative1TextEdit::SelectionMode, mode);
1144 QFETCH(int, selectionStart);
1145 QFETCH(int, selectionEnd);
1146 QFETCH(bool, reversible);
1148 QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }";
1149 QDeclarativeComponent textinputComponent(&engine);
1150 textinputComponent.setData(componentStr.toLatin1(), QUrl());
1151 QDeclarative1TextEdit *texteditObject = qobject_cast<QDeclarative1TextEdit*>(textinputComponent.create());
1152 QVERIFY(texteditObject != 0);
1154 texteditObject->setCursorPosition(cursorPosition);
1155 texteditObject->moveCursorSelection(movePosition, mode);
1157 QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
1158 QCOMPARE(texteditObject->selectionStart(), selectionStart);
1159 QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
1162 texteditObject->setCursorPosition(movePosition);
1163 texteditObject->moveCursorSelection(cursorPosition, mode);
1165 QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
1166 QCOMPARE(texteditObject->selectionStart(), selectionStart);
1167 QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
1171 void tst_qdeclarativetextedit::moveCursorSelectionSequence_data()
1173 QTest::addColumn<QString>("testStr");
1174 QTest::addColumn<int>("cursorPosition");
1175 QTest::addColumn<int>("movePosition1");
1176 QTest::addColumn<int>("movePosition2");
1177 QTest::addColumn<int>("selection1Start");
1178 QTest::addColumn<int>("selection1End");
1179 QTest::addColumn<int>("selection2Start");
1180 QTest::addColumn<int>("selection2End");
1182 QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr")
1187 QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl")
1192 QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr")
1197 QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl")
1202 QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr")
1207 QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl")
1212 QTest::newRow("the {<quick() ^}bro)wn> fox|ltr")
1217 QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl")
1222 QTest::newRow("the {<quick^}( bro)wn> fox|ltr")
1227 QTest::newRow("the quick{<(^ bro)wn>} fox|rtl")
1232 QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr")
1237 QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl")
1242 QTest::newRow("the {<^quick}( bro)wn> fox|ltr")
1247 QTest::newRow("the {<^quick}( bro)wn> fox|rtl")
1252 QTest::newRow("the{^ <quick}( bro)wn> fox|ltr")
1257 QTest::newRow("the{^ <quick}( bro)wn> fox|rtl")
1262 QTest::newRow("{t^he <quick}( bro)wn> fox|ltr")
1267 QTest::newRow("{t^he <quick}( bro)wn> fox|rtl")
1273 QTest::newRow("{<He(ll)o>, w^orld}!|ltr")
1278 QTest::newRow("{<He(ll)o>, w^orld}!|rtl")
1284 QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr")
1289 QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl")
1296 void tst_qdeclarativetextedit::moveCursorSelectionSequence()
1298 QFETCH(QString, testStr);
1299 QFETCH(int, cursorPosition);
1300 QFETCH(int, movePosition1);
1301 QFETCH(int, movePosition2);
1302 QFETCH(int, selection1Start);
1303 QFETCH(int, selection1End);
1304 QFETCH(int, selection2Start);
1305 QFETCH(int, selection2End);
1307 QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }";
1308 QDeclarativeComponent texteditComponent(&engine);
1309 texteditComponent.setData(componentStr.toLatin1(), QUrl());
1310 QDeclarative1TextEdit *texteditObject = qobject_cast<QDeclarative1TextEdit*>(texteditComponent.create());
1311 QVERIFY(texteditObject != 0);
1313 texteditObject->setCursorPosition(cursorPosition);
1315 texteditObject->moveCursorSelection(movePosition1, QDeclarative1TextEdit::SelectWords);
1316 QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start));
1317 QCOMPARE(texteditObject->selectionStart(), selection1Start);
1318 QCOMPARE(texteditObject->selectionEnd(), selection1End);
1320 texteditObject->moveCursorSelection(movePosition2, QDeclarative1TextEdit::SelectWords);
1321 QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start));
1322 QCOMPARE(texteditObject->selectionStart(), selection2Start);
1323 QCOMPARE(texteditObject->selectionEnd(), selection2End);
1327 void tst_qdeclarativetextedit::mouseSelection_data()
1329 QTest::addColumn<QString>("qmlfile");
1330 QTest::addColumn<int>("from");
1331 QTest::addColumn<int>("to");
1332 QTest::addColumn<QString>("selectedText");
1335 QTest::newRow("on") << SRCDIR "/data/mouseselection_true.qml" << 4 << 9 << "45678";
1336 QTest::newRow("off") << SRCDIR "/data/mouseselection_false.qml" << 4 << 9 << QString();
1337 QTest::newRow("default") << SRCDIR "/data/mouseselection_default.qml" << 4 << 9 << QString();
1338 QTest::newRow("off word selection") << SRCDIR "/data/mouseselection_false_words.qml" << 4 << 9 << QString();
1339 QTest::newRow("on word selection (4,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 4 << 9 << "0123456789";
1340 QTest::newRow("on word selection (2,13)") << SRCDIR "/data/mouseselection_true_words.qml" << 2 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1341 QTest::newRow("on word selection (2,30)") << SRCDIR "/data/mouseselection_true_words.qml" << 2 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1342 QTest::newRow("on word selection (9,13)") << SRCDIR "/data/mouseselection_true_words.qml" << 9 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1343 QTest::newRow("on word selection (9,30)") << SRCDIR "/data/mouseselection_true_words.qml" << 9 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1344 QTest::newRow("on word selection (13,2)") << SRCDIR "/data/mouseselection_true_words.qml" << 13 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1345 QTest::newRow("on word selection (20,2)") << SRCDIR "/data/mouseselection_true_words.qml" << 20 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1346 QTest::newRow("on word selection (12,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 12 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1347 QTest::newRow("on word selection (30,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 30 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1350 void tst_qdeclarativetextedit::mouseSelection()
1352 QFETCH(QString, qmlfile);
1355 QFETCH(QString, selectedText);
1357 QDeclarativeView *canvas = createView(qmlfile);
1360 QApplication::setActiveWindow(canvas);
1361 QTest::qWaitForWindowShown(canvas);
1362 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1364 QVERIFY(canvas->rootObject() != 0);
1365 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1366 QVERIFY(textEditObject != 0);
1368 // press-and-drag-and-release from x1 to x2
1369 QPoint p1 = canvas->mapFromScene(textEditObject->positionToRectangle(from).center());
1370 QPoint p2 = canvas->mapFromScene(textEditObject->positionToRectangle(to).center());
1371 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, p1);
1372 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1373 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(p2), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1374 QApplication::sendEvent(canvas->viewport(), &mv);
1375 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, p2);
1376 QCOMPARE(textEditObject->selectedText(), selectedText);
1378 // Clicking and shift to clicking between the same points should select the same text.
1379 textEditObject->setCursorPosition(0);
1380 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::NoModifier, p1);
1381 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::ShiftModifier, p2);
1382 QCOMPARE(textEditObject->selectedText(), selectedText);
1387 void tst_qdeclarativetextedit::multilineMouseSelection()
1389 QDeclarativeView *canvas = createView(SRCDIR "/data/mouseselection_multiline.qml");
1392 QApplication::setActiveWindow(canvas);
1393 QTest::qWaitForWindowShown(canvas);
1394 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1396 QVERIFY(canvas->rootObject() != 0);
1397 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1398 QVERIFY(textEditObject != 0);
1400 // press-and-drag from x1,y1 to x2,y1
1402 int x2 = textEditObject->width() - 10;
1403 int y1 = textEditObject->height() / 4;
1404 int y2 = textEditObject->height() * 3 / 4;
1405 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y1)));
1406 QMouseEvent mv1(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y1)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1407 QApplication::sendEvent(canvas->viewport(), &mv1);
1408 QString str1 = textEditObject->selectedText();
1409 QVERIFY(str1.length() > 3); // don't reallly care *what* was selected (and it's too sensitive to platform)
1411 // drag-and-release from x2,y1 to x2,y2
1412 QMouseEvent mv2(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y2)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1413 QApplication::sendEvent(canvas->viewport(), &mv2);
1414 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y2)));
1415 QString str2 = textEditObject->selectedText();
1416 QVERIFY(str1 != str2);
1417 QVERIFY(str2.length() > 3);
1422 void tst_qdeclarativetextedit::deferEnableSelectByMouse_data()
1424 QTest::addColumn<QString>("qmlfile");
1426 QTest::newRow("writable") << SRCDIR "/data/mouseselection_false.qml";
1427 QTest::newRow("read only") << SRCDIR "/data/mouseselection_false_readonly.qml";
1430 void tst_qdeclarativetextedit::deferEnableSelectByMouse()
1432 // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed.
1433 QFETCH(QString, qmlfile);
1435 QDeclarativeView *canvas = createView(qmlfile);
1438 QApplication::setActiveWindow(canvas);
1439 QTest::qWaitForWindowShown(canvas);
1440 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1442 QVERIFY(canvas->rootObject() != 0);
1443 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1444 QVERIFY(textEditObject != 0);
1446 // press-and-drag-and-release from x1 to x2
1449 int y = textEditObject->height()/2;
1451 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1452 textEditObject->setSelectByMouse(true);
1453 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1454 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1455 QApplication::sendEvent(canvas->viewport(), &mv);
1456 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1457 QVERIFY(textEditObject->selectedText().isEmpty());
1462 void tst_qdeclarativetextedit::deferDisableSelectByMouse_data()
1464 QTest::addColumn<QString>("qmlfile");
1466 QTest::newRow("writable") << SRCDIR "/data/mouseselection_true.qml";
1467 QTest::newRow("read only") << SRCDIR "/data/mouseselection_true_readonly.qml";
1470 void tst_qdeclarativetextedit::deferDisableSelectByMouse()
1472 // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed.
1473 QFETCH(QString, qmlfile);
1475 QDeclarativeView *canvas = createView(qmlfile);
1478 QApplication::setActiveWindow(canvas);
1479 QTest::qWaitForWindowShown(canvas);
1480 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1482 QVERIFY(canvas->rootObject() != 0);
1483 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1484 QVERIFY(textEditObject != 0);
1486 // press-and-drag-and-release from x1 to x2
1489 int y = textEditObject->height()/2;
1491 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1492 textEditObject->setSelectByMouse(false);
1493 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1494 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1495 QApplication::sendEvent(canvas->viewport(), &mv);
1496 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1497 QVERIFY(textEditObject->selectedText().length() > 3);
1502 void tst_qdeclarativetextedit::dragMouseSelection()
1504 QString qmlfile = SRCDIR "/data/mouseselection_true.qml";
1506 QDeclarativeView *canvas = createView(qmlfile);
1509 QApplication::setActiveWindow(canvas);
1510 QTest::qWaitForWindowShown(canvas);
1511 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1513 QVERIFY(canvas->rootObject() != 0);
1514 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1515 QVERIFY(textEditObject != 0);
1517 textEditObject->setAcceptDrops(true);
1519 // press-and-drag-and-release from x1 to x2
1522 int y = textEditObject->height()/2;
1523 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1525 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1526 QApplication::sendEvent(canvas->viewport(), &mv);
1528 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1529 QString str1 = textEditObject->selectedText();
1530 QVERIFY(str1.length() > 3);
1532 // press and drag the current selection.
1535 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1537 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1538 QApplication::sendEvent(canvas->viewport(), &mv);
1540 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1541 QString str2 = textEditObject->selectedText();
1542 QVERIFY(str2.length() > 3);
1544 QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved.
1549 void tst_qdeclarativetextedit::mouseSelectionMode_data()
1551 QTest::addColumn<QString>("qmlfile");
1552 QTest::addColumn<bool>("selectWords");
1555 QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true;
1556 QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false;
1557 QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false;
1560 void tst_qdeclarativetextedit::mouseSelectionMode()
1562 QFETCH(QString, qmlfile);
1563 QFETCH(bool, selectWords);
1565 QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1567 QDeclarativeView *canvas = createView(qmlfile);
1570 QApplication::setActiveWindow(canvas);
1571 QTest::qWaitForWindowShown(canvas);
1572 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1574 QVERIFY(canvas->rootObject() != 0);
1575 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1576 QVERIFY(textEditObject != 0);
1578 // press-and-drag-and-release from x1 to x2
1581 int y = textEditObject->height()/2;
1582 QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y)));
1583 //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
1584 QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1585 QApplication::sendEvent(canvas->viewport(), &mv);
1586 QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y)));
1587 QString str = textEditObject->selectedText();
1589 QCOMPARE(str, text);
1591 QVERIFY(str.length() > 3);
1592 QVERIFY(str != text);
1595 // Clicking and shift to clicking between the same points should select the same text.
1596 textEditObject->setCursorPosition(0);
1597 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::NoModifier, canvas->mapFromScene(QPoint(x1,y)));
1598 QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::ShiftModifier, canvas->mapFromScene(QPoint(x2,y)));
1599 QCOMPARE(textEditObject->selectedText(), str);
1604 void tst_qdeclarativetextedit::inputMethodHints()
1606 QDeclarativeView *canvas = createView(SRCDIR "/data/inputmethodhints.qml");
1610 QVERIFY(canvas->rootObject() != 0);
1611 QDeclarative1TextEdit *textEditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1612 QVERIFY(textEditObject != 0);
1613 QVERIFY(textEditObject->inputMethodHints() & Qt::ImhNoPredictiveText);
1614 textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly);
1615 QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly);
1620 void tst_qdeclarativetextedit::positionAt()
1622 QDeclarativeView *canvas = createView(SRCDIR "/data/positionAt.qml");
1623 QVERIFY(canvas->rootObject() != 0);
1626 QApplication::setActiveWindow(canvas);
1627 QTest::qWaitForWindowShown(canvas);
1629 QDeclarative1TextEdit *texteditObject = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
1630 QVERIFY(texteditObject != 0);
1632 QFontMetrics fm(texteditObject->font());
1633 const int y0 = fm.height() / 2;
1634 const int y1 = fm.height() * 3 / 2;
1636 int pos = texteditObject->positionAt(texteditObject->width()/2, y0);
1637 int diff = abs(int(fm.width(texteditObject->text().left(pos))-texteditObject->width()/2));
1640 QEXPECT_FAIL("", "QTBUG-21016 fails", Continue);
1642 // some tollerance for different fonts.
1649 const qreal x0 = texteditObject->positionToRectangle(pos).x();
1650 const qreal x1 = texteditObject->positionToRectangle(pos + 1).x();
1652 QString preeditText = texteditObject->text().mid(0, pos);
1653 texteditObject->setText(texteditObject->text().mid(pos));
1654 texteditObject->setCursorPosition(0);
1656 QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
1657 QApplication::sendEvent(canvas, &inputEvent);
1659 // Check all points within the preedit text return the same position.
1660 QCOMPARE(texteditObject->positionAt(0, y0), 0);
1661 QCOMPARE(texteditObject->positionAt(x0 / 2, y0), 0);
1662 QCOMPARE(texteditObject->positionAt(x0, y0), 0);
1664 // Verify positioning returns to normal after the preedit text.
1665 QCOMPARE(texteditObject->positionAt(x1, y0), 1);
1666 QCOMPARE(texteditObject->positionToRectangle(1).x(), x1);
1668 QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0);
1673 void tst_qdeclarativetextedit::cursorDelegate()
1675 QDeclarativeView* view = createView(SRCDIR "/data/cursorTest.qml");
1678 QDeclarative1TextEdit *textEditObject = view->rootObject()->findChild<QDeclarative1TextEdit*>("textEditObject");
1679 QVERIFY(textEditObject != 0);
1680 QVERIFY(textEditObject->findChild<QDeclarativeItem*>("cursorInstance"));
1681 //Test Delegate gets created
1682 textEditObject->setFocus(true);
1683 QDeclarativeItem* delegateObject = textEditObject->findChild<QDeclarativeItem*>("cursorInstance");
1684 QVERIFY(delegateObject);
1685 //Test Delegate gets moved
1686 for(int i=0; i<= textEditObject->text().length(); i++){
1687 textEditObject->setCursorPosition(i);
1688 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1689 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1691 const QString preedit = "preedit";
1692 for (int i = 0; i <= preedit.length(); i++) {
1693 QInputMethodEvent event(preedit, QList<QInputMethodEvent::Attribute>()
1694 << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, 1, QVariant()));
1695 QApplication::sendEvent(view, &event);
1697 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1698 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1700 // Clear preedit text;
1701 QInputMethodEvent event;
1702 QApplication::sendEvent(view, &event);
1705 // Test delegate gets moved on mouse press.
1706 textEditObject->setSelectByMouse(true);
1707 textEditObject->setCursorPosition(0);
1708 const QPoint point1 = view->mapFromScene(textEditObject->positionToRectangle(5).center());
1709 QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, point1);
1710 QVERIFY(textEditObject->cursorPosition() != 0);
1711 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1712 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1714 // Test delegate gets moved on mouse drag
1715 textEditObject->setCursorPosition(0);
1716 const QPoint point2 = view->mapFromScene(textEditObject->positionToRectangle(10).center());
1717 QTest::mousePress(view->viewport(), Qt::LeftButton, 0, point1);
1718 QMouseEvent mv(QEvent::MouseMove, point2, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
1719 QApplication::sendEvent(view->viewport(), &mv);
1720 QTest::mouseRelease(view->viewport(), Qt::LeftButton, 0, point2);
1721 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1722 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1724 textEditObject->setReadOnly(true);
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 QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(textEditObject->positionToRectangle(5).center()));
1733 QVERIFY(textEditObject->cursorPosition() != 0);
1734 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1735 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1737 textEditObject->setCursorPosition(0);
1738 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1739 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1740 QVERIFY(textEditObject->cursorRectangle().y() >= 0);
1741 QVERIFY(textEditObject->cursorRectangle().y() < textEditObject->cursorRectangle().height());
1742 textEditObject->setVAlign(QDeclarative1TextEdit::AlignVCenter);
1743 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1744 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1745 QVERIFY(textEditObject->cursorRectangle().y() > (textEditObject->height() / 2) - textEditObject->cursorRectangle().height());
1746 QVERIFY(textEditObject->cursorRectangle().y() < (textEditObject->height() / 2) + textEditObject->cursorRectangle().height());
1747 textEditObject->setVAlign(QDeclarative1TextEdit::AlignBottom);
1748 QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
1749 QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
1750 QVERIFY(textEditObject->cursorRectangle().y() > textEditObject->height() - (textEditObject->cursorRectangle().height() * 2));
1751 QVERIFY(textEditObject->cursorRectangle().y() < textEditObject->height());
1753 //Test Delegate gets deleted
1754 textEditObject->setCursorDelegate(0);
1755 QVERIFY(!textEditObject->findChild<QDeclarativeItem*>("cursorInstance"));
1760 void tst_qdeclarativetextedit::cursorVisible()
1762 QGraphicsScene scene;
1763 QGraphicsView view(&scene);
1765 QApplication::setActiveWindow(&view);
1766 QTest::qWaitForWindowShown(&view);
1767 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
1770 QDeclarative1TextEdit edit;
1771 QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool)));
1773 QCOMPARE(edit.isCursorVisible(), false);
1775 edit.setCursorVisible(true);
1776 QCOMPARE(edit.isCursorVisible(), true);
1777 QCOMPARE(spy.count(), 1);
1779 edit.setCursorVisible(false);
1780 QCOMPARE(edit.isCursorVisible(), false);
1781 QCOMPARE(spy.count(), 2);
1783 edit.setFocus(true);
1784 QCOMPARE(edit.isCursorVisible(), false);
1785 QCOMPARE(spy.count(), 2);
1787 scene.addItem(&edit);
1788 QCOMPARE(edit.isCursorVisible(), true);
1789 QCOMPARE(spy.count(), 3);
1791 edit.setFocus(false);
1792 QCOMPARE(edit.isCursorVisible(), false);
1793 QCOMPARE(spy.count(), 4);
1795 edit.setFocus(true);
1796 QCOMPARE(edit.isCursorVisible(), true);
1797 QCOMPARE(spy.count(), 5);
1800 QCOMPARE(edit.isCursorVisible(), false);
1801 QCOMPARE(spy.count(), 6);
1804 QCOMPARE(edit.isCursorVisible(), true);
1805 QCOMPARE(spy.count(), 7);
1808 QCOMPARE(edit.isCursorVisible(), false);
1809 QCOMPARE(spy.count(), 8);
1812 QCOMPARE(edit.isCursorVisible(), true);
1813 QCOMPARE(spy.count(), 9);
1815 // on mac, setActiveWindow(0) on mac does not deactivate the current application
1816 // (you have to switch to a different app or hide the current app to trigger this)
1817 #if !defined(Q_WS_MAC)
1818 QApplication::setActiveWindow(0);
1819 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(0));
1820 QCOMPARE(edit.isCursorVisible(), false);
1821 QCOMPARE(spy.count(), 10);
1823 QApplication::setActiveWindow(&view);
1824 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
1825 QCOMPARE(edit.isCursorVisible(), true);
1826 QCOMPARE(spy.count(), 11);
1830 void tst_qdeclarativetextedit::delegateLoading_data()
1832 QTest::addColumn<QString>("qmlfile");
1833 QTest::addColumn<QString>("error");
1836 QTest::newRow("pass") << "cursorHttpTestPass.qml" << "";
1837 QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "http://localhost:42332/FailItem.qml: Remote host closed the connection ";
1838 QTest::newRow("fail2") << "cursorHttpTestFail2.qml" << "http://localhost:42332/ErrItem.qml:4:5: Fungus is not a type ";
1841 void tst_qdeclarativetextedit::delegateLoading()
1843 QFETCH(QString, qmlfile);
1844 QFETCH(QString, error);
1846 TestHTTPServer server(42332);
1847 server.serveDirectory(SRCDIR "/data/httpfail", TestHTTPServer::Disconnect);
1848 server.serveDirectory(SRCDIR "/data/httpslow", TestHTTPServer::Delay);
1849 server.serveDirectory(SRCDIR "/data/http");
1851 QDeclarativeView* view = new QDeclarativeView(0);
1853 view->setSource(QUrl(QLatin1String("http://localhost:42332/") + qmlfile));
1857 if (!error.isEmpty()) {
1858 QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
1859 QTRY_VERIFY(view->status()==QDeclarativeView::Error);
1860 QTRY_VERIFY(!view->rootObject()); // there is fail item inside this test
1862 QTRY_VERIFY(view->rootObject());//Wait for loading to finish.
1863 QDeclarative1TextEdit *textEditObject = view->rootObject()->findChild<QDeclarative1TextEdit*>("textEditObject");
1864 // view->rootObject()->dumpObjectTree();
1865 QVERIFY(textEditObject != 0);
1866 textEditObject->setFocus(true);
1867 QDeclarativeItem *delegate;
1868 delegate = view->rootObject()->findChild<QDeclarativeItem*>("delegateOkay");
1870 delegate = view->rootObject()->findChild<QDeclarativeItem*>("delegateSlow");
1877 //A test should be added here with a component which is ready but component.create() returns null
1878 //Not sure how to accomplish this with QDeclarative1TextEdits cursor delegate
1879 //###This was only needed for code coverage, and could be a case of overzealous defensive programming
1880 //delegate = view->rootObject()->findChild<QDeclarativeItem*>("delegateErrorB");
1881 //QVERIFY(!delegate);
1887 TextEdit element should only handle left/right keys until the cursor reaches
1888 the extent of the text, then they should ignore the keys.
1890 void tst_qdeclarativetextedit::navigation()
1892 QDeclarativeView *canvas = createView(SRCDIR "/data/navigation.qml");
1896 QVERIFY(canvas->rootObject() != 0);
1898 QDeclarativeItem *input = qobject_cast<QDeclarativeItem *>(qvariant_cast<QObject *>(canvas->rootObject()->property("myInput")));
1900 QVERIFY(input != 0);
1901 QTRY_VERIFY(input->hasActiveFocus() == true);
1902 simulateKey(canvas, Qt::Key_Left);
1903 QVERIFY(input->hasActiveFocus() == false);
1904 simulateKey(canvas, Qt::Key_Right);
1905 QVERIFY(input->hasActiveFocus() == true);
1906 simulateKey(canvas, Qt::Key_Right);
1907 QVERIFY(input->hasActiveFocus() == true);
1908 simulateKey(canvas, Qt::Key_Right);
1909 QVERIFY(input->hasActiveFocus() == false);
1910 simulateKey(canvas, Qt::Key_Left);
1911 QVERIFY(input->hasActiveFocus() == true);
1916 void tst_qdeclarativetextedit::copyAndPaste() {
1917 #ifndef QT_NO_CLIPBOARD
1921 PasteboardRef pasteboard;
1922 OSStatus status = PasteboardCreate(0, &pasteboard);
1923 if (status == noErr)
1924 CFRelease(pasteboard);
1926 QSKIP("This machine doesn't support the clipboard", SkipAll);
1930 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
1931 QDeclarativeComponent textEditComponent(&engine);
1932 textEditComponent.setData(componentStr.toLatin1(), QUrl());
1933 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit*>(textEditComponent.create());
1934 QVERIFY(textEdit != 0);
1937 QCOMPARE(textEdit->text().length(), 12);
1938 textEdit->select(0, textEdit->text().length());;
1940 QCOMPARE(textEdit->selectedText(), QString("Hello world!"));
1941 QCOMPARE(textEdit->selectedText().length(), 12);
1942 textEdit->setCursorPosition(0);
1943 QVERIFY(textEdit->canPaste());
1945 QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
1946 QCOMPARE(textEdit->text().length(), 24);
1949 QVERIFY(textEdit->canPaste());
1950 textEdit->setReadOnly(true);
1951 QVERIFY(!textEdit->canPaste());
1952 textEdit->setReadOnly(false);
1953 QVERIFY(textEdit->canPaste());
1956 // test that document and internal text attribute are in sync
1957 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(textEdit);
1958 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
1959 QCOMPARE(textEdit->text(), editPrivate->text);
1962 textEdit->setCursorPosition(0);
1963 textEdit->selectWord();
1964 QCOMPARE(textEdit->selectedText(), QString("Hello"));
1966 // select all and cut
1967 textEdit->selectAll();
1969 QCOMPARE(textEdit->text().length(), 0);
1971 QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
1972 QCOMPARE(textEdit->text().length(), 24);
1976 void tst_qdeclarativetextedit::canPaste() {
1977 #ifndef QT_NO_CLIPBOARD
1979 QApplication::clipboard()->setText("Some text");
1981 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
1982 QDeclarativeComponent textEditComponent(&engine);
1983 textEditComponent.setData(componentStr.toLatin1(), QUrl());
1984 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit*>(textEditComponent.create());
1985 QVERIFY(textEdit != 0);
1987 // check initial value - QTBUG-17765
1989 QCOMPARE(textEdit->canPaste(), tc.canPaste());
1994 void tst_qdeclarativetextedit::canPasteEmpty() {
1995 #ifndef QT_NO_CLIPBOARD
1997 QApplication::clipboard()->clear();
1999 QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
2000 QDeclarativeComponent textEditComponent(&engine);
2001 textEditComponent.setData(componentStr.toLatin1(), QUrl());
2002 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit*>(textEditComponent.create());
2003 QVERIFY(textEdit != 0);
2005 // check initial value - QTBUG-17765
2007 QCOMPARE(textEdit->canPaste(), tc.canPaste());
2012 void tst_qdeclarativetextedit::readOnly()
2014 QDeclarativeView *canvas = createView(SRCDIR "/data/readOnly.qml");
2018 QVERIFY(canvas->rootObject() != 0);
2020 QDeclarative1TextEdit *edit = qobject_cast<QDeclarative1TextEdit *>(qvariant_cast<QObject *>(canvas->rootObject()->property("myInput")));
2023 QTRY_VERIFY(edit->hasActiveFocus() == true);
2024 QVERIFY(edit->isReadOnly() == true);
2025 QString initial = edit->text();
2026 for(int k=Qt::Key_0; k<=Qt::Key_Z; k++)
2027 simulateKey(canvas, k);
2028 simulateKey(canvas, Qt::Key_Return);
2029 simulateKey(canvas, Qt::Key_Space);
2030 simulateKey(canvas, Qt::Key_Escape);
2031 QCOMPARE(edit->text(), initial);
2036 void tst_qdeclarativetextedit::simulateKey(QDeclarativeView *view, int key, Qt::KeyboardModifiers modifiers)
2038 QKeyEvent press(QKeyEvent::KeyPress, key, modifiers);
2039 QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers);
2041 QApplication::sendEvent(view, &press);
2042 QApplication::sendEvent(view, &release);
2045 QDeclarativeView *tst_qdeclarativetextedit::createView(const QString &filename)
2047 QDeclarativeView *canvas = new QDeclarativeView(0);
2049 canvas->setSource(QUrl::fromLocalFile(filename));
2053 class MyInputContext : public QInputContext
2056 MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {}
2057 ~MyInputContext() {}
2059 QString identifierName() { return QString(); }
2060 QString language() { return QString(); }
2064 bool isComposing() const { return false; }
2066 bool filterEvent( const QEvent *event )
2068 if (event->type() == QEvent::RequestSoftwareInputPanel)
2069 openInputPanelReceived = true;
2070 if (event->type() == QEvent::CloseSoftwareInputPanel)
2071 closeInputPanelReceived = true;
2072 return false; //QInputContext::filterEvent(event);
2075 void update() { updateReceived = true; }
2077 void sendPreeditText(const QString &text, int cursor)
2079 QList<QInputMethodEvent::Attribute> attributes;
2080 attributes.append(QInputMethodEvent::Attribute(
2081 QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
2083 QInputMethodEvent event(text, attributes);
2087 void mouseHandler(int x, QMouseEvent *event)
2090 eventType = event->type();
2091 eventPosition = event->pos();
2092 eventGlobalPosition = event->globalPos();
2093 eventButton = event->button();
2094 eventButtons = event->buttons();
2095 eventModifiers = event->modifiers();
2098 bool openInputPanelReceived;
2099 bool closeInputPanelReceived;
2100 bool updateReceived;
2102 QEvent::Type eventType;
2103 QPoint eventPosition;
2104 QPoint eventGlobalPosition;
2105 Qt::MouseButton eventButton;
2106 Qt::MouseButtons eventButtons;
2107 Qt::KeyboardModifiers eventModifiers;
2110 void tst_qdeclarativetextedit::textInput()
2112 QGraphicsScene scene;
2113 QGraphicsView view(&scene);
2114 QDeclarative1TextEdit edit;
2115 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit);
2116 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
2118 scene.addItem(&edit);
2120 QApplication::setActiveWindow(&view);
2121 QTest::qWaitForWindowShown(&view);
2122 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2123 edit.setFocus(true);
2124 QVERIFY(edit.hasActiveFocus() == true);
2126 // test that input method event is committed
2127 QInputMethodEvent event;
2128 event.setCommitString( "Hello world!", 0, 0);
2129 QApplication::sendEvent(&view, &event);
2130 QCOMPARE(edit.text(), QString("Hello world!"));
2133 // test that document and internal text attribute are in sync
2134 QCOMPARE(editPrivate->text, QString("Hello world!"));
2137 void tst_qdeclarativetextedit::openInputPanelOnClick()
2139 QGraphicsScene scene;
2140 QGraphicsView view(&scene);
2142 view.setInputContext(&ic);
2143 QDeclarative1TextEdit edit;
2144 QSignalSpy focusOnPressSpy(&edit, SIGNAL(activeFocusOnPressChanged(bool)));
2145 edit.setText("Hello world");
2147 scene.addItem(&edit);
2149 qApp->setAutoSipEnabled(true);
2150 QApplication::setActiveWindow(&view);
2151 QTest::qWaitForWindowShown(&view);
2152 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2154 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit);
2155 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
2157 // input panel on click
2158 editPrivate->showInputPanelOnFocus = false;
2160 QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
2161 view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
2162 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2163 QApplication::processEvents();
2164 if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) {
2165 QCOMPARE(ic.openInputPanelReceived, false);
2166 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2167 QApplication::processEvents();
2168 QCOMPARE(ic.openInputPanelReceived, true);
2169 } else if (behavior == QStyle::RSIP_OnMouseClick) {
2170 QCOMPARE(ic.openInputPanelReceived, true);
2172 ic.openInputPanelReceived = false;
2174 // focus should not cause input panels to open or close
2175 edit.setFocus(false);
2176 edit.setFocus(true);
2177 edit.setFocus(false);
2178 edit.setFocus(true);
2179 edit.setFocus(false);
2180 QApplication::processEvents();
2181 QCOMPARE(ic.openInputPanelReceived, false);
2182 QCOMPARE(ic.closeInputPanelReceived, false);
2185 void tst_qdeclarativetextedit::openInputPanelOnFocus()
2187 QGraphicsScene scene;
2188 QGraphicsView view(&scene);
2190 view.setInputContext(&ic);
2191 QDeclarative1TextEdit edit;
2192 QSignalSpy focusOnPressSpy(&edit, SIGNAL(activeFocusOnPressChanged(bool)));
2193 edit.setText("Hello world");
2195 scene.addItem(&edit);
2197 qApp->setAutoSipEnabled(true);
2198 QApplication::setActiveWindow(&view);
2199 QTest::qWaitForWindowShown(&view);
2200 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2202 QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit);
2203 QDeclarative1TextEditPrivate *editPrivate = static_cast<QDeclarative1TextEditPrivate*>(pri);
2204 editPrivate->showInputPanelOnFocus = true;
2206 // test default values
2207 QVERIFY(edit.focusOnPress());
2208 QCOMPARE(ic.openInputPanelReceived, false);
2209 QCOMPARE(ic.closeInputPanelReceived, false);
2211 // focus on press, input panel on focus
2212 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2213 QApplication::processEvents();
2214 QVERIFY(edit.hasActiveFocus());
2215 QCOMPARE(ic.openInputPanelReceived, true);
2216 ic.openInputPanelReceived = false;
2218 // no events on release
2219 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2220 QCOMPARE(ic.openInputPanelReceived, false);
2221 ic.openInputPanelReceived = false;
2223 // if already focused, input panel can be opened on press
2224 QVERIFY(edit.hasActiveFocus());
2225 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2226 QApplication::processEvents();
2227 QCOMPARE(ic.openInputPanelReceived, true);
2228 ic.openInputPanelReceived = false;
2230 // input method should stay enabled if focus
2231 // is lost to an item that also accepts inputs
2232 QDeclarative1TextEdit anotherEdit;
2233 scene.addItem(&anotherEdit);
2234 anotherEdit.setFocus(true);
2235 QApplication::processEvents();
2236 QCOMPARE(ic.openInputPanelReceived, true);
2237 ic.openInputPanelReceived = false;
2238 QCOMPARE(view.inputContext(), (QInputContext*)&ic);
2239 QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled));
2241 // input method should be disabled if focus
2242 // is lost to an item that doesn't accept inputs
2243 QDeclarativeItem item;
2244 scene.addItem(&item);
2245 item.setFocus(true);
2246 QApplication::processEvents();
2247 QCOMPARE(ic.openInputPanelReceived, false);
2248 QVERIFY(view.inputContext() == 0);
2249 QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
2251 // no automatic input panel events should
2252 // be sent if activeFocusOnPress is false
2253 edit.setFocusOnPress(false);
2254 QCOMPARE(focusOnPressSpy.count(),1);
2255 edit.setFocusOnPress(false);
2256 QCOMPARE(focusOnPressSpy.count(),1);
2257 edit.setFocus(false);
2258 edit.setFocus(true);
2259 QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2260 QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos()));
2261 QApplication::processEvents();
2262 QCOMPARE(ic.openInputPanelReceived, false);
2263 QCOMPARE(ic.closeInputPanelReceived, false);
2265 // one show input panel event should
2266 // be set when openSoftwareInputPanel is called
2267 edit.openSoftwareInputPanel();
2268 QCOMPARE(ic.openInputPanelReceived, true);
2269 QCOMPARE(ic.closeInputPanelReceived, false);
2270 ic.openInputPanelReceived = false;
2272 // one close input panel event should
2273 // be sent when closeSoftwareInputPanel is called
2274 edit.closeSoftwareInputPanel();
2275 QCOMPARE(ic.openInputPanelReceived, false);
2276 QCOMPARE(ic.closeInputPanelReceived, true);
2277 ic.closeInputPanelReceived = false;
2279 // set activeFocusOnPress back to true
2280 edit.setFocusOnPress(true);
2281 QCOMPARE(focusOnPressSpy.count(),2);
2282 edit.setFocusOnPress(true);
2283 QCOMPARE(focusOnPressSpy.count(),2);
2284 edit.setFocus(false);
2285 QApplication::processEvents();
2286 QCOMPARE(ic.openInputPanelReceived, false);
2287 QCOMPARE(ic.closeInputPanelReceived, false);
2288 ic.closeInputPanelReceived = false;
2290 // input panel should not re-open
2291 // if focus has already been set
2292 edit.setFocus(true);
2293 QCOMPARE(ic.openInputPanelReceived, true);
2294 ic.openInputPanelReceived = false;
2295 edit.setFocus(true);
2296 QCOMPARE(ic.openInputPanelReceived, false);
2298 // input method should be disabled
2299 // if TextEdit loses focus
2300 edit.setFocus(false);
2301 QApplication::processEvents();
2302 QVERIFY(view.inputContext() == 0);
2303 QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
2305 // input method should not be enabled
2306 // if TextEdit is read only.
2307 edit.setReadOnly(true);
2308 ic.openInputPanelReceived = false;
2309 edit.setFocus(true);
2310 QApplication::processEvents();
2311 QCOMPARE(ic.openInputPanelReceived, false);
2312 QVERIFY(view.inputContext() == 0);
2313 QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
2316 void tst_qdeclarativetextedit::geometrySignals()
2318 QDeclarativeComponent component(&engine, SRCDIR "/data/geometrySignals.qml");
2319 QObject *o = component.create();
2321 QCOMPARE(o->property("bindingWidth").toInt(), 400);
2322 QCOMPARE(o->property("bindingHeight").toInt(), 500);
2326 void tst_qdeclarativetextedit::pastingRichText_QTBUG_14003()
2328 #ifndef QT_NO_CLIPBOARD
2329 QString componentStr = "import QtQuick 1.0\nTextEdit { textFormat: TextEdit.PlainText }";
2330 QDeclarativeComponent component(&engine);
2331 component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
2332 QDeclarative1TextEdit *obj = qobject_cast<QDeclarative1TextEdit*>(component.create());
2334 QTRY_VERIFY(obj != 0);
2335 QTRY_VERIFY(obj->textFormat() == QDeclarative1TextEdit::PlainText);
2337 QMimeData *mData = new QMimeData;
2338 mData->setHtml("<font color=\"red\">Hello</font>");
2339 QApplication::clipboard()->setMimeData(mData);
2342 QTRY_VERIFY(obj->text() == "");
2343 QTRY_VERIFY(obj->textFormat() == QDeclarative1TextEdit::PlainText);
2347 void tst_qdeclarativetextedit::implicitSize_data()
2349 QTest::addColumn<QString>("text");
2350 QTest::addColumn<QString>("wrap");
2351 QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap";
2352 QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap";
2353 QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap";
2354 QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap";
2357 void tst_qdeclarativetextedit::implicitSize()
2359 QFETCH(QString, text);
2360 QFETCH(QString, wrap);
2361 QString componentStr = "import QtQuick 1.1\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
2362 QDeclarativeComponent textComponent(&engine);
2363 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
2364 QDeclarative1TextEdit *textObject = qobject_cast<QDeclarative1TextEdit*>(textComponent.create());
2366 QVERIFY(textObject->width() < textObject->implicitWidth());
2367 QVERIFY(textObject->height() == textObject->implicitHeight());
2369 textObject->resetWidth();
2370 QVERIFY(textObject->width() == textObject->implicitWidth());
2371 QVERIFY(textObject->height() == textObject->implicitHeight());
2374 void tst_qdeclarativetextedit::testQtQuick11Attributes()
2376 QFETCH(QString, code);
2377 QFETCH(QString, warning);
2378 QFETCH(QString, error);
2380 QDeclarativeEngine engine;
2383 QDeclarativeComponent valid(&engine);
2384 valid.setData("import QtQuick 1.1; TextEdit { " + code.toUtf8() + " }", QUrl(""));
2385 obj = valid.create();
2387 QVERIFY(valid.errorString().isEmpty());
2390 QDeclarativeComponent invalid(&engine);
2391 invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl(""));
2392 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2393 obj = invalid.create();
2394 QCOMPARE(invalid.errorString(), error);
2398 void tst_qdeclarativetextedit::testQtQuick11Attributes_data()
2400 QTest::addColumn<QString>("code");
2401 QTest::addColumn<QString>("warning");
2402 QTest::addColumn<QString>("error");
2404 QTest::newRow("canPaste") << "property bool foo: canPaste"
2405 << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste"
2408 QTest::newRow("lineCount") << "property int foo: lineCount"
2409 << "<Unknown File>:1: ReferenceError: Can't find variable: lineCount"
2412 QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)"
2413 << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection"
2416 QTest::newRow("deselect") << "Component.onCompleted: deselect()"
2417 << "<Unknown File>:1: ReferenceError: Can't find variable: deselect"
2420 QTest::newRow("onLinkActivated") << "onLinkActivated: {}"
2421 << "QDeclarativeComponent: Component is not ready"
2422 << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n";
2425 void tst_qdeclarativetextedit::preeditMicroFocus()
2427 QString preeditText = "super";
2429 QGraphicsScene scene;
2430 QGraphicsView view(&scene);
2432 view.setInputContext(&ic);
2433 QDeclarative1TextEdit edit;
2434 edit.setFocus(true);
2435 scene.addItem(&edit);
2437 QApplication::setActiveWindow(&view);
2438 QTest::qWaitForWindowShown(&view);
2439 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2441 QSignalSpy cursorRectangleSpy(&edit, SIGNAL(cursorRectangleChanged()));
2444 QRect previousRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2446 // Verify that the micro focus rect is positioned the same for position 0 as
2447 // it would be if there was no preedit text.
2448 ic.updateReceived = false;
2449 ic.sendPreeditText(preeditText, 0);
2450 currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2451 QCOMPARE(currentRect, previousRect);
2452 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
2453 QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed.
2455 QCOMPARE(cursorRectangleSpy.count(), 0);
2457 // Verify that the micro focus rect moves to the left as the cursor position
2459 for (int i = 1; i <= 5; ++i) {
2460 ic.updateReceived = false;
2461 ic.sendPreeditText(preeditText, i);
2462 currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2463 QVERIFY(previousRect.left() < currentRect.left());
2464 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
2465 QCOMPARE(ic.updateReceived, true);
2467 QVERIFY(cursorRectangleSpy.count() > 0);
2468 cursorRectangleSpy.clear();
2469 previousRect = currentRect;
2472 // Verify that if there is no preedit cursor then the micro focus rect is the
2473 // same as it would be if it were positioned at the end of the preedit text.
2474 ic.sendPreeditText(preeditText, 0);
2475 ic.updateReceived = false;
2476 ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
2477 currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
2478 QCOMPARE(currentRect, previousRect);
2479 #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
2480 QCOMPARE(ic.updateReceived, true);
2482 QVERIFY(cursorRectangleSpy.count() > 0);
2485 void tst_qdeclarativetextedit::inputContextMouseHandler()
2487 QString text = "supercalifragisiticexpialidocious!";
2489 QGraphicsScene scene;
2490 QGraphicsView view(&scene);
2492 view.setInputContext(&ic);
2493 QDeclarative1TextEdit edit;
2496 edit.setText(text.mid(0, 12));
2498 edit.setCursorPosition(12);
2499 edit.setFocus(true);
2500 scene.addItem(&edit);
2502 QApplication::setActiveWindow(&view);
2503 QTest::qWaitForWindowShown(&view);
2504 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2507 QFontMetricsF fm(edit.font());
2508 const qreal y = fm.height() / 2;
2510 QPoint position2 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 2)), y)));
2511 QPoint position8 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 8)), y)));
2512 QPoint position20 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 20)), y)));
2513 QPoint position27 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 27)), y)));
2514 QPoint globalPosition2 = view.viewport()->mapToGlobal(position2);
2515 QPoint globalposition8 = view.viewport()->mapToGlobal(position8);
2516 QPoint globalposition20 = view.viewport()->mapToGlobal(position20);
2517 QPoint globalposition27 = view.viewport()->mapToGlobal(position27);
2519 ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
2521 QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
2522 QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
2523 QCOMPARE(ic.eventPosition, position2);
2524 QCOMPARE(ic.eventGlobalPosition, globalPosition2);
2525 QCOMPARE(ic.eventButton, Qt::LeftButton);
2526 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2527 QVERIFY(ic.cursor < 0);
2528 ic.eventType = QEvent::None;
2530 QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
2531 QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
2532 QCOMPARE(ic.eventPosition, position2);
2533 QCOMPARE(ic.eventGlobalPosition, globalPosition2);
2534 QCOMPARE(ic.eventButton, Qt::LeftButton);
2535 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2536 QVERIFY(ic.cursor < 0);
2537 ic.eventType = QEvent::None;
2539 { QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
2540 QApplication::sendEvent(view.viewport(), &mv); }
2541 QCOMPARE(ic.eventType, QEvent::None);
2543 { QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
2544 QApplication::sendEvent(view.viewport(), &mv); }
2545 QCOMPARE(ic.eventType, QEvent::MouseMove);
2546 QCOMPARE(ic.eventPosition, position27);
2547 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2548 QCOMPARE(ic.eventButton, Qt::LeftButton);
2549 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2550 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); // 15 is expected but some platforms may be off by one.
2551 ic.eventType = QEvent::None;
2553 QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position27);
2554 QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
2555 QCOMPARE(ic.eventPosition, position27);
2556 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2557 QCOMPARE(ic.eventButton, Qt::LeftButton);
2558 QCOMPARE(ic.eventModifiers, Qt::NoModifier);
2559 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
2560 ic.eventType = QEvent::None;
2562 // And in the other direction.
2563 QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position27);
2564 QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
2565 QCOMPARE(ic.eventPosition, position27);
2566 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2567 QCOMPARE(ic.eventButton, Qt::LeftButton);
2568 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2569 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
2570 ic.eventType = QEvent::None;
2572 QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position27);
2573 QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
2574 QCOMPARE(ic.eventPosition, position27);
2575 QCOMPARE(ic.eventGlobalPosition, globalposition27);
2576 QCOMPARE(ic.eventButton, Qt::RightButton);
2577 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2578 QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
2579 ic.eventType = QEvent::None;
2581 { QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
2582 QApplication::sendEvent(view.viewport(), &mv); }
2583 QCOMPARE(ic.eventType, QEvent::MouseMove);
2584 QCOMPARE(ic.eventPosition, position20);
2585 QCOMPARE(ic.eventGlobalPosition, globalposition20);
2586 QCOMPARE(ic.eventButton, Qt::RightButton);
2587 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2588 QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
2589 ic.eventType = QEvent::None;
2591 { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
2592 QApplication::sendEvent(view.viewport(), &mv); }
2593 QCOMPARE(ic.eventType, QEvent::None);
2595 QTest::mouseRelease(view.viewport(), Qt::RightButton, Qt::ControlModifier, position2);
2596 QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
2597 QCOMPARE(ic.eventPosition, position2);
2598 QCOMPARE(ic.eventGlobalPosition, globalPosition2);
2599 QCOMPARE(ic.eventButton, Qt::RightButton);
2600 QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
2601 QVERIFY(ic.cursor < 0);
2602 ic.eventType = QEvent::None;
2605 void tst_qdeclarativetextedit::inputMethodComposing()
2607 QString text = "supercalifragisiticexpialidocious!";
2609 QGraphicsScene scene;
2610 QGraphicsView view(&scene);
2612 view.setInputContext(&ic);
2613 QDeclarative1TextEdit edit;
2615 edit.setText(text.mid(0, 12));
2616 edit.setCursorPosition(12);
2618 edit.setFocus(true);
2619 scene.addItem(&edit);
2621 QApplication::setActiveWindow(&view);
2622 QTest::qWaitForWindowShown(&view);
2623 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
2625 QSignalSpy spy(&edit, SIGNAL(inputMethodComposingChanged()));
2627 QCOMPARE(edit.isInputMethodComposing(), false);
2629 ic.sendEvent(QInputMethodEvent(text.mid(3), QList<QInputMethodEvent::Attribute>()));
2630 QCOMPARE(edit.isInputMethodComposing(), true);
2631 QCOMPARE(spy.count(), 1);
2633 ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
2634 QCOMPARE(edit.isInputMethodComposing(), true);
2635 QCOMPARE(spy.count(), 1);
2637 ic.sendEvent(QInputMethodEvent());
2638 QCOMPARE(edit.isInputMethodComposing(), false);
2639 QCOMPARE(spy.count(), 2);
2642 void tst_qdeclarativetextedit::cursorRectangleSize()
2644 QDeclarativeView *canvas = createView(SRCDIR "/data/CursorRect.qml");
2645 QVERIFY(canvas->rootObject() != 0);
2648 QApplication::setActiveWindow(canvas);
2649 QTest::qWaitForWindowShown(canvas);
2651 QDeclarative1TextEdit *textEdit = qobject_cast<QDeclarative1TextEdit *>(canvas->rootObject());
2652 QVERIFY(textEdit != 0);
2653 textEdit->setFocus(Qt::OtherFocusReason);
2654 QRectF cursorRect = textEdit->positionToRectangle(textEdit->cursorPosition());
2655 QRectF microFocusFromScene = canvas->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
2656 QRectF microFocusFromApp= QApplication::focusWidget()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
2658 QCOMPARE(microFocusFromScene.size(), cursorRect.size());
2659 QCOMPARE(microFocusFromApp.size(), cursorRect.size());
2661 QTEST_MAIN(tst_qdeclarativetextedit)
2663 #include "tst_qdeclarativetextedit.moc"