1 /****************************************************************************
3 ** Copyright (C) 2009 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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
46 #include <qtextdocument.h>
47 #include <qtexttable.h>
49 #include <qtextdocumentfragment.h>
50 #include <qabstracttextdocumentlayout.h>
51 #include <qtextlayout.h>
52 #include <qtextcursor.h>
55 //TESTED_FILES=gui/text/qtextcursor.cpp gui/text/qtextcursor_p.h
57 QT_FORWARD_DECLARE_CLASS(QTextDocument
)
59 class tst_QTextCursor
: public QObject
72 void navigation2_data();
82 void movePositionEndOfLine();
84 void insertWithBlockSeparator1();
85 void insertWithBlockSeparator2();
86 void insertWithBlockSeparator3();
87 void insertWithBlockSeparator4();
88 void clearObjectType1();
89 void clearObjectType2();
90 void clearObjectType3();
91 void comparisonOperators1();
92 void comparisonOperators2();
94 void dontCopyTableAttributes();
100 void selectionsInTable();
102 void insertBlockToUseCharFormat();
106 void insertBlockShouldRemoveSelection();
107 void insertBlockShouldRemoveSelection2();
108 void mergeCellShouldUpdateSelection();
110 void joinPreviousEditBlock();
112 void setBlockFormatInTable();
114 void blockCharFormat();
115 void blockCharFormat2();
116 void blockCharFormat3();
117 void blockCharFormatOnSelection();
119 void anchorInitialized1();
120 void anchorInitialized2();
121 void anchorInitialized3();
124 void selectWordWithSeparators_data();
125 void selectWordWithSeparators();
128 void selectVisually();
132 void insertFragmentShouldUseCurrentCharFormat();
136 void editBlocksDuringRemove();
141 void disallowSettingObjectIndicesOnCharFormats();
143 void blockAndColumnNumber();
147 void task244408_wordUnderCursor_data();
148 void task244408_wordUnderCursor();
157 Q_DECLARE_METATYPE(QList
<QVariant
>)
159 tst_QTextCursor::tst_QTextCursor()
162 void tst_QTextCursor::init()
164 doc
= new QTextDocument
;
165 cursor
= QTextCursor(doc
);
168 void tst_QTextCursor::cleanup()
170 cursor
= QTextCursor();
175 void tst_QTextCursor::navigation1()
178 cursor
.insertText("Hello World");
179 QVERIFY(doc
->toPlainText() == "Hello World");
181 cursor
.movePosition(QTextCursor::End
);
182 QVERIFY(cursor
.position() == 11);
183 cursor
.deletePreviousChar();
184 QVERIFY(cursor
.position() == 10);
185 cursor
.deletePreviousChar();
186 cursor
.deletePreviousChar();
187 cursor
.deletePreviousChar();
188 cursor
.deletePreviousChar();
189 cursor
.deletePreviousChar();
190 QVERIFY(doc
->toPlainText() == "Hello");
192 QTextCursor
otherCursor(doc
);
193 otherCursor
.movePosition(QTextCursor::Start
);
194 otherCursor
.movePosition(QTextCursor::Right
);
195 cursor
= otherCursor
;
196 cursor
.movePosition(QTextCursor::Right
);
197 QVERIFY(cursor
!= otherCursor
);
198 otherCursor
.insertText("Hey");
199 QVERIFY(cursor
.position() == 5);
202 QVERIFY(cursor
.position() == 2);
204 QVERIFY(cursor
.position() == 5);
209 QVERIFY(doc
->toPlainText() == "Hello World");
211 cursor
.movePosition(QTextCursor::Start
);
212 cursor
.movePosition(QTextCursor::Right
, QTextCursor::MoveAnchor
, 6);
213 QVERIFY(cursor
.position() == 6);
214 otherCursor
= cursor
;
215 otherCursor
.movePosition(QTextCursor::Right
, QTextCursor::MoveAnchor
, 2);
216 otherCursor
.deletePreviousChar();
217 otherCursor
.deletePreviousChar();
218 otherCursor
.deletePreviousChar();
219 QVERIFY(cursor
.position() == 5);
221 cursor
.movePosition(QTextCursor::End
);
222 cursor
.insertBlock();
224 int oldPos
= cursor
.position();
225 cursor
.movePosition(QTextCursor::End
);
226 QVERIFY(cursor
.position() == oldPos
);
228 QVERIFY(cursor
.atBlockStart());
229 QVERIFY(cursor
.position() == 9);
232 fmt
.setForeground(Qt::blue
);
233 cursor
.insertText("Test", fmt
);
234 QVERIFY(fmt
== cursor
.charFormat());
235 QVERIFY(cursor
.position() == 13);
238 void tst_QTextCursor::navigation2_data()
240 QTest::addColumn
<QStringList
>("sl");
241 QTest::addColumn
<QList
<QVariant
> >("movement");
242 QTest::addColumn
<int>("finalPos");
244 QTest::newRow("startBlock1") << QStringList("Happy happy happy joy joy joy")
245 << (QList
<QVariant
>() << QVariant(QTextCursor::StartOfBlock
)) << 0;
246 QTest::newRow("endBlock1") << QStringList("Happy happy happy joy joy joy")
247 << (QList
<QVariant
>() << QVariant(QTextCursor::StartOfBlock
)
248 << QVariant(QTextCursor::EndOfBlock
)) << 29;
249 QTest::newRow("startBlock2") << QStringList("Happy happy happy joy joy joy")
250 << (QList
<QVariant
>() << QVariant(QTextCursor::StartOfBlock
)
251 << QVariant(QTextCursor::EndOfBlock
)
252 << QVariant(QTextCursor::StartOfBlock
)) << 0;
253 QTest::newRow("endBlock2") << QStringList("Happy happy happy joy joy joy")
254 << (QList
<QVariant
>() << QVariant(QTextCursor::StartOfBlock
)
255 << QVariant(QTextCursor::EndOfBlock
)
256 << QVariant(QTextCursor::StartOfBlock
)
257 << QVariant(QTextCursor::EndOfBlock
)
259 QTest::newRow("multiBlock1") << (QStringList() << QString("Happy happy happy")
260 << QString("Joy Joy Joy"))
261 << (QList
<QVariant
>() << QVariant(QTextCursor::StartOfBlock
))
263 QTest::newRow("multiBlock2") << (QStringList() << QString("Happy happy happy")
264 << QString("Joy Joy Joy"))
265 << (QList
<QVariant
>() << QVariant(QTextCursor::StartOfBlock
)
266 << QVariant(QTextCursor::EndOfBlock
))
268 QTest::newRow("multiBlock3") << (QStringList() << QString("Happy happy happy")
269 << QString("Joy Joy Joy"))
270 << (QList
<QVariant
>() << QVariant(QTextCursor::StartOfBlock
)
271 << QVariant(QTextCursor::StartOfBlock
))
273 QTest::newRow("multiBlock4") << (QStringList() << QString("Happy happy happy")
274 << QString("Joy Joy Joy"))
275 << (QList
<QVariant
>() << QVariant(QTextCursor::Start
)
276 << QVariant(QTextCursor::EndOfBlock
))
278 QTest::newRow("multiBlock5") << (QStringList() << QString("Happy happy happy")
279 << QString("Joy Joy Joy"))
280 << (QList
<QVariant
>() << QVariant(QTextCursor::Start
)
281 << QVariant(QTextCursor::EndOfBlock
)
282 << QVariant(QTextCursor::EndOfBlock
))
284 QTest::newRow("multiBlock6") << (QStringList() << QString("Happy happy happy")
285 << QString("Joy Joy Joy"))
286 << (QList
<QVariant
>() << QVariant(QTextCursor::End
)
287 << QVariant(QTextCursor::StartOfBlock
))
289 QTest::newRow("multiBlock7") << (QStringList() << QString("Happy happy happy")
290 << QString("Joy Joy Joy"))
291 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousBlock
))
293 QTest::newRow("multiBlock8") << (QStringList() << QString("Happy happy happy")
294 << QString("Joy Joy Joy"))
295 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousBlock
)
296 << QVariant(QTextCursor::EndOfBlock
))
298 QTest::newRow("multiBlock9") << (QStringList() << QString("Happy happy happy")
299 << QString("Joy Joy Joy"))
300 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousBlock
)
301 << QVariant(QTextCursor::NextBlock
))
303 QTest::newRow("multiBlock10") << (QStringList() << QString("Happy happy happy")
304 << QString("Joy Joy Joy"))
305 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousBlock
)
306 << QVariant(QTextCursor::NextBlock
)
307 << QVariant(QTextCursor::NextBlock
))
309 QTest::newRow("multiBlock11") << (QStringList() << QString("Happy happy happy")
310 << QString("Joy Joy Joy"))
311 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousBlock
)
312 << QVariant(QTextCursor::NextBlock
)
313 << QVariant(QTextCursor::EndOfBlock
))
315 QTest::newRow("PreviousWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
316 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousWord
))
318 QTest::newRow("PreviousWord2") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
319 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousWord
)
320 << QVariant(QTextCursor::PreviousWord
))
322 QTest::newRow("EndWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
323 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousWord
)
324 << QVariant(QTextCursor::PreviousWord
)
325 << QVariant(QTextCursor::EndOfWord
))
327 QTest::newRow("NextWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
328 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousWord
)
329 << QVariant(QTextCursor::PreviousWord
)
330 << QVariant(QTextCursor::NextWord
))
332 QTest::newRow("NextWord2") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
333 << (QList
<QVariant
>() << QVariant(QTextCursor::Start
)
334 << QVariant(QTextCursor::NextWord
)
335 << QVariant(QTextCursor::EndOfWord
))
337 QTest::newRow("StartWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
338 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousWord
)
339 << QVariant(QTextCursor::PreviousWord
)
340 << QVariant(QTextCursor::StartOfWord
))
342 QTest::newRow("StartWord3") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
343 << (QList
<QVariant
>() << QVariant(QTextCursor::Start
)
344 << QVariant(QTextCursor::NextWord
)
345 << QVariant(QTextCursor::EndOfWord
)
346 << QVariant(QTextCursor::StartOfWord
))
349 QTest::newRow("PreviousCharacter") << (QStringList() << QString("Happy happy Joy Joy"))
350 << (QList
<QVariant
>() << QVariant(QTextCursor::PreviousCharacter
)
351 << QVariant(QTextCursor::PreviousCharacter
))
355 void tst_QTextCursor::navigation2()
357 QFETCH(QStringList
, sl
);
358 QFETCH(QList
<QVariant
>, movement
);
360 for (i
= 0; i
< sl
.size(); ++i
) {
361 cursor
.insertText(sl
.at(i
));
362 if (i
< sl
.size() - 1)
363 cursor
.insertBlock();
366 for (i
= 0; i
< movement
.size(); ++i
)
367 cursor
.movePosition(QTextCursor::MoveOperation(movement
.at(i
).toInt()));
368 QTEST(cursor
.position(), "finalPos");
371 void tst_QTextCursor::navigation3()
373 cursor
.insertText("a");
374 cursor
.deletePreviousChar();
375 QCOMPARE(cursor
.position(), 0);
376 QVERIFY(doc
->toPlainText().isEmpty());
379 void tst_QTextCursor::navigation4()
381 cursor
.insertText(" Test ");
383 cursor
.setPosition(4);
384 cursor
.movePosition(QTextCursor::EndOfWord
);
385 QCOMPARE(cursor
.position(), 6);
388 void tst_QTextCursor::navigation5()
390 cursor
.insertText("Test");
391 cursor
.insertBlock();
392 cursor
.insertText("Test");
394 cursor
.setPosition(0);
395 cursor
.movePosition(QTextCursor::EndOfBlock
);
396 QCOMPARE(cursor
.position(), 4);
399 void tst_QTextCursor::navigation6()
401 // triger creation of document layout, so that QTextLines are there
402 doc
->documentLayout();
403 doc
->setTextWidth(1000);
405 cursor
.insertText("Test ");
407 cursor
.movePosition(QTextCursor::Start
);
408 cursor
.movePosition(QTextCursor::EndOfLine
);
409 QCOMPARE(cursor
.position(), 8);
412 void tst_QTextCursor::navigation7()
414 QVERIFY(doc
->isEmpty());
415 for (int i
= QTextCursor::Start
; i
<= QTextCursor::WordRight
; ++i
)
416 QVERIFY(!cursor
.movePosition(QTextCursor::MoveOperation(i
)));
418 doc
->setPlainText("Hello World");
419 cursor
.movePosition(QTextCursor::Start
);
421 } while (cursor
.movePosition(QTextCursor::NextCharacter
));
422 QVERIFY(true /*reached*/);
425 void tst_QTextCursor::navigation8()
427 cursor
.insertList(QTextListFormat::ListDecimal
);
428 QCOMPARE(cursor
.position(), 1);
429 cursor
.insertText("foo");
430 QCOMPARE(cursor
.position(), 4);
432 cursor
.insertList(QTextListFormat::ListCircle
);
433 QCOMPARE(cursor
.position(), 5);
434 cursor
.insertText("something");
435 QCOMPARE(cursor
.position(), 14);
437 cursor
.movePosition(QTextCursor::PreviousCharacter
);
438 QCOMPARE(cursor
.position(), 13);
440 cursor
.setPosition(2);
441 cursor
.movePosition(QTextCursor::NextCharacter
);
442 QCOMPARE(cursor
.position(), 3);
445 void tst_QTextCursor::navigation9()
447 cursor
.insertText("Hello &-=+\t World");
448 cursor
.movePosition(QTextCursor::PreviousWord
);
449 QCOMPARE(cursor
.position(), 15);
450 cursor
.movePosition(QTextCursor::PreviousWord
);
451 QCOMPARE(cursor
.position(), 7);
452 cursor
.movePosition(QTextCursor::PreviousWord
);
453 QCOMPARE(cursor
.position(), 0);
454 cursor
.movePosition(QTextCursor::NextWord
);
455 QCOMPARE(cursor
.position(), 7);
456 cursor
.movePosition(QTextCursor::NextWord
);
457 QCOMPARE(cursor
.position(), 15);
460 void tst_QTextCursor::navigation10()
462 doc
->setHtml("<html><p>just a simple paragraph.</p>"
464 "<tr><td>Cell number 1</td><td>another cell</td><td></td><td>previous</br>is</br>empty</td></tr>"
465 "<tr><td>row 2</td><td colspan=\"2\">foo bar</td><td>last cell</td></tr>"
466 "<tr><td colspan=\"3\">row 3</td><td>a</td></tr>"
468 QCOMPARE(cursor
.position(), 101); // end of document
469 cursor
.setPosition(0);
470 QCOMPARE(cursor
.position(), 0);
471 bool ok
= cursor
.movePosition(QTextCursor::EndOfLine
);
473 QCOMPARE(cursor
.position(), 24);
474 ok
= cursor
.movePosition(QTextCursor::NextBlock
);
475 QCOMPARE(cursor
.position(), 25); // cell 1
476 ok
= cursor
.movePosition(QTextCursor::NextCell
);
478 QCOMPARE(cursor
.position(), 39); // another..
479 ok
= cursor
.movePosition(QTextCursor::NextCell
);
481 QCOMPARE(cursor
.position(), 52); // empty
482 ok
= cursor
.movePosition(QTextCursor::NextCell
);
484 QCOMPARE(cursor
.position(), 53); // last on row 1
485 ok
= cursor
.movePosition(QTextCursor::NextCell
);
487 QCOMPARE(cursor
.position(), 69); // row 2
488 ok
= cursor
.movePosition(QTextCursor::NextCell
);
490 QCOMPARE(cursor
.position(), 75);
491 ok
= cursor
.movePosition(QTextCursor::NextCell
);
493 QCOMPARE(cursor
.position(), 83);
494 ok
= cursor
.movePosition(QTextCursor::NextCell
);
496 QCOMPARE(cursor
.position(), 93); // row 3
497 ok
= cursor
.movePosition(QTextCursor::NextCell
);
499 QCOMPARE(cursor
.position(), 99);
500 ok
= cursor
.movePosition(QTextCursor::NextCell
);
501 QVERIFY(ok
== false);
502 QCOMPARE(cursor
.position(), 99); // didn't move.
503 QVERIFY(cursor
.currentTable());
505 // same thing in reverse...
506 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
508 QCOMPARE(cursor
.position(), 93);
509 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
511 QCOMPARE(cursor
.position(), 83);
512 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
514 QCOMPARE(cursor
.position(), 75);
515 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
517 QCOMPARE(cursor
.position(), 69);
518 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
520 QCOMPARE(cursor
.position(), 53);
521 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
523 QCOMPARE(cursor
.position(), 52);
524 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
526 QCOMPARE(cursor
.position(), 39);
527 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
529 QCOMPARE(cursor
.position(), 25);
530 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
532 QCOMPARE(cursor
.position(), 25); // can't leave the table
534 ok
= cursor
.movePosition(QTextCursor::NextRow
);
536 QCOMPARE(cursor
.position(), 69);
537 ok
= cursor
.movePosition(QTextCursor::NextRow
);
539 QCOMPARE(cursor
.position(), 93);
540 ok
= cursor
.movePosition(QTextCursor::NextRow
);
542 QCOMPARE(cursor
.position(), 93); // didn't move
544 ok
= cursor
.movePosition(QTextCursor::PreviousRow
);
546 QCOMPARE(cursor
.position(), 83); // last col in row 2
547 ok
= cursor
.movePosition(QTextCursor::PreviousRow
);
549 QCOMPARE(cursor
.position(), 53); // last col in row 1
550 ok
= cursor
.movePosition(QTextCursor::PreviousRow
);
552 QCOMPARE(cursor
.position(), 53);
554 // test usecase of jumping over a cell
556 doc
->setHtml("<html><table>tr><td rowspan=\"2\">a</td><td>b</td></tr><tr><td>c</td></tr></table></html>");
557 cursor
.setPosition(1); // a
558 ok
= cursor
.movePosition(QTextCursor::NextCell
);
560 QCOMPARE(cursor
.position(), 3); // b
561 ok
= cursor
.movePosition(QTextCursor::NextCell
);
563 QCOMPARE(cursor
.position(), 5); // c
564 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
566 QCOMPARE(cursor
.position(), 3); // b
567 ok
= cursor
.movePosition(QTextCursor::PreviousCell
);
569 QCOMPARE(cursor
.position(), 1); // a
572 void tst_QTextCursor::insertBlock()
574 QTextBlockFormat fmt
;
575 fmt
.setTopMargin(100);
576 cursor
.insertBlock(fmt
);
577 QVERIFY(cursor
.position() == 1);
578 QVERIFY(cursor
.blockFormat() == fmt
);
581 void tst_QTextCursor::insertWithBlockSeparator1()
583 QString text
= "Hello" + QString(QChar::ParagraphSeparator
) + "World";
585 cursor
.insertText(text
);
587 cursor
.movePosition(QTextCursor::PreviousBlock
);
588 QVERIFY(cursor
.position() == 0);
590 cursor
.movePosition(QTextCursor::NextBlock
);
591 QVERIFY(cursor
.position() == 6);
594 void tst_QTextCursor::insertWithBlockSeparator2()
596 cursor
.insertText(QString(QChar::ParagraphSeparator
));
597 QVERIFY(cursor
.position() == 1);
600 void tst_QTextCursor::insertWithBlockSeparator3()
602 cursor
.insertText(QString(QChar::ParagraphSeparator
) + "Hi" + QString(QChar::ParagraphSeparator
));
603 QVERIFY(cursor
.position() == 4);
606 void tst_QTextCursor::insertWithBlockSeparator4()
608 cursor
.insertText(QString(QChar::ParagraphSeparator
) + QString(QChar::ParagraphSeparator
));
609 QVERIFY(cursor
.position() == 2);
612 void tst_QTextCursor::clearObjectType1()
614 cursor
.insertImage("test.png");
615 QVERIFY(cursor
.charFormat().isValid());
616 QVERIFY(cursor
.charFormat().isImageFormat());
617 cursor
.insertText("Hey");
618 QVERIFY(cursor
.charFormat().isValid());
619 QVERIFY(!cursor
.charFormat().isImageFormat());
622 void tst_QTextCursor::clearObjectType2()
624 cursor
.insertImage("test.png");
625 QVERIFY(cursor
.charFormat().isValid());
626 QVERIFY(cursor
.charFormat().isImageFormat());
627 cursor
.insertBlock();
628 QVERIFY(cursor
.charFormat().isValid());
629 QVERIFY(!cursor
.charFormat().isImageFormat());
632 void tst_QTextCursor::clearObjectType3()
634 // like clearObjectType2 but tests different insertBlock overload
635 cursor
.insertImage("test.png");
636 QVERIFY(cursor
.charFormat().isValid());
637 QVERIFY(cursor
.charFormat().isImageFormat());
638 QTextBlockFormat bfmt
;
639 bfmt
.setAlignment(Qt::AlignRight
);
640 cursor
.insertBlock(bfmt
);
641 QVERIFY(cursor
.charFormat().isValid());
642 QVERIFY(!cursor
.charFormat().isImageFormat());
645 void tst_QTextCursor::comparisonOperators1()
647 cursor
.insertText("Hello World");
649 cursor
.movePosition(QTextCursor::PreviousWord
);
651 QTextCursor startCursor
= cursor
;
652 startCursor
.movePosition(QTextCursor::Start
);
654 QVERIFY(startCursor
< cursor
);
656 QTextCursor midCursor
= startCursor
;
657 midCursor
.movePosition(QTextCursor::NextWord
);
659 QVERIFY(midCursor
<= cursor
);
660 QVERIFY(midCursor
== cursor
);
661 QVERIFY(midCursor
>= cursor
);
663 QVERIFY(midCursor
> startCursor
);
665 QVERIFY(midCursor
!= startCursor
);
666 QVERIFY(!(midCursor
== startCursor
));
668 QTextCursor nullCursor
;
670 QVERIFY(!(startCursor
< nullCursor
));
671 QVERIFY(!(nullCursor
< nullCursor
));
672 QVERIFY(nullCursor
< startCursor
);
674 QVERIFY(nullCursor
<= startCursor
);
675 QVERIFY(!(startCursor
<= nullCursor
));
677 QVERIFY(!(nullCursor
>= startCursor
));
678 QVERIFY(startCursor
>= nullCursor
);
680 QVERIFY(!(nullCursor
> startCursor
));
681 QVERIFY(!(nullCursor
> nullCursor
));
682 QVERIFY(startCursor
> nullCursor
);
685 void tst_QTextCursor::comparisonOperators2()
690 QTextCursor
cursor1(&doc1
);
691 QTextCursor
cursor2(&doc2
);
693 QVERIFY(cursor1
!= cursor2
);
694 QVERIFY(cursor1
== QTextCursor(&doc1
));
697 void tst_QTextCursor::selection1()
699 cursor
.insertText("Hello World");
701 cursor
.setPosition(0);
702 cursor
.clearSelection();
703 cursor
.setPosition(4, QTextCursor::KeepAnchor
);
705 QCOMPARE(cursor
.selectionStart(), 0);
706 QCOMPARE(cursor
.selectionEnd(), 4);
709 void tst_QTextCursor::dontCopyTableAttributes()
711 /* when pressing 'enter' inside a cell it shouldn't
712 * enlarge the table by adding another cell but just
714 QTextTable
*table
= cursor
.insertTable(2, 2);
715 QVERIFY(cursor
== table
->cellAt(0, 0).firstCursorPosition());
716 cursor
.insertBlock();
717 QCOMPARE(table
->columns(), 2);
720 void tst_QTextCursor::checkFrame1()
722 QVERIFY(cursor
.position() == 0);
723 QPointer
<QTextFrame
> frame
= cursor
.insertFrame(QTextFrameFormat());
726 QTextFrame
*root
= frame
->parentFrame();
729 QVERIFY(frame
->firstPosition() == 1);
730 QVERIFY(frame
->lastPosition() == 1);
731 QVERIFY(frame
->parentFrame() != 0);
732 QVERIFY(root
->childFrames().size() == 1);
734 QVERIFY(cursor
.position() == 1);
735 QVERIFY(cursor
.selectionStart() == 1);
736 QVERIFY(cursor
.selectionEnd() == 1);
741 QVERIFY(root
->childFrames().size() == 0);
743 QVERIFY(cursor
.position() == 0);
744 QVERIFY(cursor
.selectionStart() == 0);
745 QVERIFY(cursor
.selectionEnd() == 0);
749 frame
= doc
->frameAt(1);
752 QVERIFY(frame
->firstPosition() == 1);
753 QVERIFY(frame
->lastPosition() == 1);
754 QVERIFY(frame
->parentFrame() != 0);
755 QVERIFY(root
->childFrames().size() == 1);
757 QVERIFY(cursor
.position() == 1);
758 QVERIFY(cursor
.selectionStart() == 1);
759 QVERIFY(cursor
.selectionEnd() == 1);
761 // cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
762 // QVERIFY(cursor.position() == 2);
763 // QVERIFY(cursor.selectionStart() == 0);
764 // QVERIFY(cursor.selectionEnd() == 2);
767 void tst_QTextCursor::checkFrame2()
769 QVERIFY(cursor
.position() == 0);
770 cursor
.insertText("A");
771 QVERIFY(cursor
.position() == 1);
772 cursor
.movePosition(QTextCursor::Start
, QTextCursor::KeepAnchor
);
774 QPointer
<QTextFrame
> frame
= cursor
.insertFrame(QTextFrameFormat());
775 QTextFrame
*root
= frame
->parentFrame();
777 QVERIFY(frame
->firstPosition() == 1);
778 QVERIFY(frame
->lastPosition() == 2);
779 QVERIFY(frame
->parentFrame() != 0);
780 QVERIFY(root
->childFrames().size() == 1);
782 QVERIFY(cursor
.position() == 1);
783 QVERIFY(cursor
.selectionStart() == 1);
784 QVERIFY(cursor
.selectionEnd() == 2);
789 QVERIFY(root
->childFrames().size() == 0);
791 QVERIFY(cursor
.position() == 0);
792 QVERIFY(cursor
.selectionStart() == 0);
793 QVERIFY(cursor
.selectionEnd() == 1);
797 frame
= doc
->frameAt(1);
800 QVERIFY(frame
->firstPosition() == 1);
801 QVERIFY(frame
->lastPosition() == 2);
802 QVERIFY(frame
->parentFrame() != 0);
803 QVERIFY(root
->childFrames().size() == 1);
805 QVERIFY(cursor
.position() == 1);
806 QVERIFY(cursor
.selectionStart() == 1);
807 QVERIFY(cursor
.selectionEnd() == 2);
809 cursor
.movePosition(QTextCursor::Left
, QTextCursor::KeepAnchor
);
810 QVERIFY(cursor
.position() == 0);
811 QVERIFY(cursor
.selectionStart() == 0);
812 QVERIFY(cursor
.selectionEnd() == 3);
815 void tst_QTextCursor::insertBlockToUseCharFormat()
818 fmt
.setForeground(Qt::blue
);
819 cursor
.insertText("Hello", fmt
);
820 QCOMPARE(cursor
.charFormat().foreground().color(), QColor(Qt::blue
));
822 cursor
.insertBlock();
823 QCOMPARE(cursor
.charFormat().foreground().color(), QColor(Qt::blue
));
825 fmt
.setForeground(Qt::red
);
826 cursor
.insertText("Hello\nWorld", fmt
);
827 cursor
.insertText("Blah");
828 QCOMPARE(cursor
.charFormat().foreground().color(), QColor(Qt::red
));
830 // ### we might want a testcase for createTable, too, as it calls insertBlock, too,
831 // and we might want to have the char format copied (the one that gets inserted
832 // as table separators, that are undeletable)
835 void tst_QTextCursor::tableMovement()
837 QVERIFY(cursor
.position() == 0);
838 cursor
.insertText("AA");
839 QVERIFY(cursor
.position() == 2);
840 cursor
.movePosition(QTextCursor::Left
);
842 cursor
.insertTable(3, 3);
843 QCOMPARE(cursor
.position(), 2);
845 cursor
.movePosition(QTextCursor::Down
);
846 QCOMPARE(cursor
.position(), 5);
848 cursor
.movePosition(QTextCursor::Right
);
849 QCOMPARE(cursor
.position(), 6);
851 cursor
.movePosition(QTextCursor::Up
);
852 QCOMPARE(cursor
.position(), 3);
854 cursor
.movePosition(QTextCursor::Right
);
855 QCOMPARE(cursor
.position(), 4);
857 cursor
.movePosition(QTextCursor::Right
);
858 QCOMPARE(cursor
.position(), 5);
860 cursor
.movePosition(QTextCursor::Up
);
861 QCOMPARE(cursor
.position(), 2);
863 cursor
.movePosition(QTextCursor::Up
);
864 QCOMPARE(cursor
.position(), 0);
868 void tst_QTextCursor::selectionsInTable()
870 QTextTable
*table
= cursor
.insertTable(2, 2);
871 table
->cellAt(0, 0).firstCursorPosition().insertText("First");
872 table
->cellAt(0, 1).firstCursorPosition().insertText("Second");
873 table
->cellAt(1, 0).firstCursorPosition().insertText("Third");
874 table
->cellAt(1, 1).firstCursorPosition().insertText("Fourth");
876 cursor
= table
->cellAt(0, 0).lastCursorPosition();
877 QVERIFY(cursor
.movePosition(QTextCursor::PreviousWord
, QTextCursor::KeepAnchor
));
878 QVERIFY(cursor
.movePosition(QTextCursor::PreviousWord
, QTextCursor::KeepAnchor
) == false);
880 cursor
= table
->cellAt(1, 0).lastCursorPosition();
881 QVERIFY(cursor
.movePosition(QTextCursor::PreviousWord
, QTextCursor::KeepAnchor
));
882 QVERIFY(cursor
.movePosition(QTextCursor::PreviousWord
, QTextCursor::KeepAnchor
) == false);
884 cursor
= table
->cellAt(0, 1).firstCursorPosition();
885 QVERIFY(cursor
.movePosition(QTextCursor::NextWord
, QTextCursor::KeepAnchor
));
886 QVERIFY(cursor
.movePosition(QTextCursor::NextWord
, QTextCursor::KeepAnchor
) == false);
888 cursor
= table
->cellAt(1, 1).firstCursorPosition();
889 QVERIFY(cursor
.movePosition(QTextCursor::NextWord
, QTextCursor::KeepAnchor
));
890 QVERIFY(cursor
.movePosition(QTextCursor::NextWord
, QTextCursor::KeepAnchor
) == false);
893 void tst_QTextCursor::selectedText()
895 cursor
.insertText("Hello World");
896 cursor
.movePosition(QTextCursor::Start
);
897 cursor
.movePosition(QTextCursor::End
, QTextCursor::KeepAnchor
);
899 QCOMPARE(cursor
.selectedText(), QString("Hello World"));
902 void tst_QTextCursor::insertBlockShouldRemoveSelection()
904 cursor
.insertText("Hello World");
905 cursor
.movePosition(QTextCursor::Start
);
906 cursor
.movePosition(QTextCursor::EndOfWord
, QTextCursor::KeepAnchor
);
908 QVERIFY(cursor
.hasSelection());
909 QCOMPARE(cursor
.selectedText(), QString("Hello"));
911 cursor
.insertBlock();
913 QVERIFY(!cursor
.hasSelection());
914 QVERIFY(doc
->toPlainText().indexOf("Hello") == -1);
917 void tst_QTextCursor::insertBlockShouldRemoveSelection2()
919 cursor
.insertText("Hello World");
920 cursor
.movePosition(QTextCursor::Start
);
921 cursor
.movePosition(QTextCursor::EndOfWord
, QTextCursor::KeepAnchor
);
923 QVERIFY(cursor
.hasSelection());
924 QCOMPARE(cursor
.selectedText(), QString("Hello"));
926 QTextBlockFormat fmt
= cursor
.blockFormat();
927 cursor
.insertBlock(fmt
);
929 QVERIFY(!cursor
.hasSelection());
930 QVERIFY(doc
->toPlainText().indexOf("Hello") == -1);
933 void tst_QTextCursor::mergeCellShouldUpdateSelection()
935 QTextTable
*table
= cursor
.insertTable(4, 4);
936 cursor
.setPosition(table
->cellAt(0, 0).firstPosition());
937 cursor
.setPosition(table
->cellAt(3, 0).firstPosition(), QTextCursor::KeepAnchor
); // aka bottom left
938 int firstRow
, numRows
, firstColumn
, numColumns
;
939 cursor
.selectedTableCells(&firstRow
, &numRows
, &firstColumn
, &numColumns
);
940 QCOMPARE(firstRow
, 0);
941 QCOMPARE(numRows
, 4);
942 QCOMPARE(firstColumn
, 0);
943 QCOMPARE(numColumns
, 1);
945 table
->removeColumns(firstColumn
, numColumns
);
947 QCOMPARE(cursor
.anchor(), table
->cellAt(0, 0).firstPosition());
948 QCOMPARE(cursor
.position(), table
->cellAt(0, 0).firstPosition());
949 QCOMPARE(cursor
.position(), cursor
.anchor()); // empty. I don't really care where it ends up.
951 // prepare for another test with multiple cursors.
952 // note we have a 4 rows, 3 cols table now.
953 cursor
.setPosition(table
->cellAt(0, 0).firstPosition());
954 cursor
.setPosition(table
->cellAt(0, 2).firstPosition(), QTextCursor::KeepAnchor
);
956 // now create a selection of a whole row.
957 QTextCursor c2
= table
->cellAt(2, 0).firstCursorPosition();
958 c2
.setPosition(table
->cellAt(2, 2).firstPosition(), QTextCursor::KeepAnchor
);
960 // just for good measure, another one for a block of cells.
961 QTextCursor c3
= table
->cellAt(2, 1).firstCursorPosition();
962 c3
.setPosition(table
->cellAt(3, 2).firstPosition(), QTextCursor::KeepAnchor
);
964 table
->removeRows(2, 1);
966 QCOMPARE(cursor
.anchor(), table
->cellAt(0, 0).firstPosition());
967 QCOMPARE(cursor
.position(), table
->cellAt(0, 2).firstPosition());
969 QCOMPARE(c2
.position(), c2
.anchor()); // empty. I don't really care where it ends up.
971 QCOMPARE(c3
.anchor(), table
->cellAt(2, 1).firstPosition());
972 QCOMPARE(c3
.position(), table
->cellAt(2, 2).firstPosition());
975 // prepare for another test where we remove a column
976 // note we have a 3 rows, 3 cols table now.
977 cursor
.setPosition(table
->cellAt(0, 0).firstPosition());
978 cursor
.setPosition(table
->cellAt(2, 1).firstPosition(), QTextCursor::KeepAnchor
);
980 c2
.setPosition(table
->cellAt(0, 1).firstPosition());
981 c2
.setPosition(table
->cellAt(2, 2).firstPosition(), QTextCursor::KeepAnchor
);
983 table
->removeColumns(1, 1);
985 QCOMPARE(cursor
.anchor(), table
->cellAt(0, 0).firstPosition());
986 QCOMPARE(cursor
.position(), table
->cellAt(2, 0).firstPosition());
988 QCOMPARE(c2
.anchor(), table
->cellAt(0, 1).firstPosition());
989 QCOMPARE(c2
.position(), table
->cellAt(2, 1).firstPosition());
991 // test for illegal cursor positions.
992 // note we have a 3 rows, 2 cols table now.
993 cursor
.setPosition(table
->cellAt(2, 0).firstPosition());
994 cursor
.setPosition(table
->cellAt(2, 1).firstPosition(), QTextCursor::KeepAnchor
);
996 c2
.setPosition(table
->cellAt(0, 0).firstPosition());
997 c2
.setPosition(table
->cellAt(2, 1).firstPosition(), QTextCursor::KeepAnchor
);
999 c3
.setPosition(table
->cellAt(2, 1).firstPosition());
1001 table
->removeRows(2, 1);
1003 QCOMPARE(cursor
.anchor(), table
->cellAt(1, 1).lastPosition()+1);
1004 QCOMPARE(cursor
.position(), cursor
.anchor());
1006 QCOMPARE(c2
.anchor(), table
->cellAt(0, 0).firstPosition());
1007 QCOMPARE(c2
.position(), table
->cellAt(1, 1).firstPosition());
1009 QCOMPARE(c3
.anchor(), table
->cellAt(1, 1).firstPosition());
1010 QCOMPARE(c3
.position(), table
->cellAt(1, 1).firstPosition());
1013 void tst_QTextCursor::joinPreviousEditBlock()
1015 cursor
.beginEditBlock();
1016 cursor
.insertText("Hello");
1017 cursor
.insertText("World");
1018 cursor
.endEditBlock();
1019 QVERIFY(doc
->toPlainText().startsWith("HelloWorld"));
1021 cursor
.joinPreviousEditBlock();
1022 cursor
.insertText("Hey");
1023 cursor
.endEditBlock();
1024 QVERIFY(doc
->toPlainText().startsWith("HelloWorldHey"));
1027 QVERIFY(!doc
->toPlainText().contains("HelloWorldHey"));
1030 void tst_QTextCursor::setBlockFormatInTable()
1032 // someone reported this on qt4-preview-feedback
1033 QTextBlockFormat fmt
;
1034 fmt
.setBackground(Qt::blue
);
1035 cursor
.setBlockFormat(fmt
);
1037 QTextTable
*table
= cursor
.insertTable(2, 2);
1038 cursor
= table
->cellAt(0, 0).firstCursorPosition();
1039 fmt
.setBackground(Qt::red
);
1040 cursor
.setBlockFormat(fmt
);
1042 cursor
.movePosition(QTextCursor::Start
);
1043 QVERIFY(cursor
.blockFormat().background().color() == Qt::blue
);
1046 void tst_QTextCursor::blockCharFormat2()
1048 QTextCharFormat fmt
;
1049 fmt
.setForeground(Qt::green
);
1050 cursor
.mergeBlockCharFormat(fmt
);
1052 fmt
.setForeground(Qt::red
);
1054 cursor
.insertText("Test", fmt
);
1055 cursor
.movePosition(QTextCursor::Start
);
1056 cursor
.insertText("Red");
1057 cursor
.movePosition(QTextCursor::PreviousCharacter
);
1058 QVERIFY(cursor
.charFormat().foreground().color() == Qt::red
);
1061 void tst_QTextCursor::blockCharFormat3()
1063 QVERIFY(cursor
.atBlockStart());
1064 QVERIFY(cursor
.atBlockEnd());
1065 QVERIFY(cursor
.atStart());
1067 QTextCharFormat fmt
;
1068 fmt
.setForeground(Qt::green
);
1069 cursor
.setBlockCharFormat(fmt
);
1070 cursor
.insertText("Test");
1071 cursor
.movePosition(QTextCursor::Start
);
1072 cursor
.movePosition(QTextCursor::NextCharacter
);
1073 QVERIFY(cursor
.charFormat().foreground().color() == Qt::green
);
1075 cursor
.movePosition(QTextCursor::Start
);
1076 QVERIFY(cursor
.charFormat().foreground().color() == Qt::green
);
1078 fmt
.setForeground(Qt::red
);
1079 cursor
.setBlockCharFormat(fmt
);
1080 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::red
);
1082 cursor
.movePosition(QTextCursor::End
);
1083 cursor
.movePosition(QTextCursor::Start
);
1084 QVERIFY(cursor
.charFormat().foreground().color() == Qt::green
);
1086 cursor
.insertText("Test");
1087 QVERIFY(cursor
.charFormat().foreground().color() == Qt::green
);
1089 cursor
.select(QTextCursor::Document
);
1090 cursor
.removeSelectedText();
1091 QVERIFY(cursor
.atBlockStart());
1092 QVERIFY(cursor
.atBlockEnd());
1093 QVERIFY(cursor
.atStart());
1095 cursor
.insertText("Test");
1096 QVERIFY(cursor
.charFormat().foreground().color() == Qt::red
);
1099 void tst_QTextCursor::blockCharFormat()
1101 QTextCharFormat fmt
;
1102 fmt
.setForeground(Qt::blue
);
1103 cursor
.insertBlock(QTextBlockFormat(), fmt
);
1104 cursor
.insertText("Hm");
1106 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::blue
);
1108 fmt
.setForeground(Qt::red
);
1110 cursor
.setBlockCharFormat(fmt
);
1111 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::red
);
1114 void tst_QTextCursor::blockCharFormatOnSelection()
1116 QTextCharFormat fmt
;
1117 fmt
.setForeground(Qt::blue
);
1118 cursor
.insertBlock(QTextBlockFormat(), fmt
);
1120 fmt
.setForeground(Qt::green
);
1121 cursor
.insertText("Hm", fmt
);
1123 fmt
.setForeground(Qt::red
);
1124 cursor
.insertBlock(QTextBlockFormat(), fmt
);
1125 cursor
.insertText("Ah");
1127 fmt
.setForeground(Qt::white
);
1128 cursor
.insertBlock(QTextBlockFormat(), fmt
);
1129 cursor
.insertText("bleh");
1131 cursor
.movePosition(QTextCursor::Start
);
1132 cursor
.movePosition(QTextCursor::NextBlock
);
1133 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::blue
);
1134 cursor
.movePosition(QTextCursor::NextBlock
);
1135 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::red
);
1136 cursor
.movePosition(QTextCursor::NextBlock
);
1137 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::white
);
1139 cursor
.movePosition(QTextCursor::Start
);
1140 cursor
.movePosition(QTextCursor::NextBlock
);
1141 cursor
.movePosition(QTextCursor::NextBlock
, QTextCursor::KeepAnchor
);
1143 fmt
.setForeground(Qt::cyan
);
1144 cursor
.setBlockCharFormat(fmt
);
1146 cursor
.movePosition(QTextCursor::Start
);
1147 cursor
.movePosition(QTextCursor::NextBlock
);
1148 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::cyan
);
1150 cursor
.movePosition(QTextCursor::Right
);
1151 cursor
.movePosition(QTextCursor::Right
);
1152 QVERIFY(cursor
.charFormat().foreground().color() == Qt::green
);
1154 cursor
.movePosition(QTextCursor::NextBlock
);
1155 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::cyan
);
1157 cursor
.movePosition(QTextCursor::NextBlock
);
1158 QVERIFY(cursor
.blockCharFormat().foreground().color() == Qt::white
);
1161 void tst_QTextCursor::anchorInitialized1()
1163 cursor
.insertBlock();
1164 cursor
= QTextCursor(cursor
.block());
1165 QCOMPARE(cursor
.position(), 1);
1166 QCOMPARE(cursor
.anchor(), 1);
1167 QCOMPARE(cursor
.selectionStart(), 1);
1168 QCOMPARE(cursor
.selectionEnd(), 1);
1171 void tst_QTextCursor::anchorInitialized2()
1173 cursor
.insertBlock();
1174 cursor
= QTextCursor(cursor
.block().docHandle(), 1);
1175 QCOMPARE(cursor
.position(), 1);
1176 QCOMPARE(cursor
.anchor(), 1);
1177 QCOMPARE(cursor
.selectionStart(), 1);
1178 QCOMPARE(cursor
.selectionEnd(), 1);
1181 void tst_QTextCursor::anchorInitialized3()
1183 QTextFrame
*frame
= cursor
.insertFrame(QTextFrameFormat());
1184 cursor
= QTextCursor(frame
);
1185 QCOMPARE(cursor
.position(), 1);
1186 QCOMPARE(cursor
.anchor(), 1);
1187 QCOMPARE(cursor
.selectionStart(), 1);
1188 QCOMPARE(cursor
.selectionEnd(), 1);
1191 void tst_QTextCursor::selectWord()
1193 cursor
.insertText("first second third");
1194 cursor
.insertBlock();
1195 cursor
.insertText("words in second paragraph");
1197 cursor
.setPosition(9);
1198 cursor
.select(QTextCursor::WordUnderCursor
);
1199 QVERIFY(cursor
.hasSelection());
1200 QCOMPARE(cursor
.selectionStart(), 6);
1201 QCOMPARE(cursor
.selectionEnd(), 12);
1203 cursor
.setPosition(5);
1204 cursor
.select(QTextCursor::WordUnderCursor
);
1205 QVERIFY(cursor
.hasSelection());
1206 QCOMPARE(cursor
.selectionStart(), 0);
1207 QCOMPARE(cursor
.selectionEnd(), 5);
1209 cursor
.setPosition(6);
1210 cursor
.select(QTextCursor::WordUnderCursor
);
1211 QVERIFY(cursor
.hasSelection());
1212 QCOMPARE(cursor
.selectionStart(), 6);
1213 QCOMPARE(cursor
.selectionEnd(), 12);
1215 cursor
.setPosition(14);
1216 cursor
.select(QTextCursor::WordUnderCursor
);
1217 QVERIFY(cursor
.hasSelection());
1218 QCOMPARE(cursor
.selectionStart(), 6);
1219 QCOMPARE(cursor
.selectionEnd(), 12);
1221 cursor
.movePosition(QTextCursor::Start
);
1222 cursor
.select(QTextCursor::WordUnderCursor
);
1223 QVERIFY(cursor
.hasSelection());
1224 QCOMPARE(cursor
.selectionStart(), 0);
1225 QCOMPARE(cursor
.selectionEnd(), 5);
1227 cursor
.movePosition(QTextCursor::EndOfBlock
);
1228 cursor
.select(QTextCursor::WordUnderCursor
);
1229 QVERIFY(cursor
.hasSelection());
1230 QCOMPARE(cursor
.selectionStart(), 17);
1231 QCOMPARE(cursor
.selectionEnd(), 22);
1234 void tst_QTextCursor::selectWordWithSeparators_data()
1236 QTest::addColumn
<QString
>("text");
1237 QTest::addColumn
<int>("initialPosition");
1238 QTest::addColumn
<QString
>("expectedSelectedText");
1240 QTest::newRow("dereference") << QString::fromLatin1("foo->bar()") << 1 << QString::fromLatin1("foo");
1241 QTest::newRow("funcsignature") << QString::fromLatin1("bar(int x);") << 1 << QString::fromLatin1("bar");
1242 QTest::newRow("def") << QString::fromLatin1("foo *f;") << 1 << QString::fromLatin1("foo");
1245 void tst_QTextCursor::selectWordWithSeparators()
1247 QFETCH(QString
, text
);
1248 QFETCH(int, initialPosition
);
1249 QFETCH(QString
, expectedSelectedText
);
1251 cursor
.insertText(text
);
1252 cursor
.setPosition(initialPosition
);
1253 cursor
.select(QTextCursor::WordUnderCursor
);
1255 QCOMPARE(cursor
.selectedText(), expectedSelectedText
);
1258 void tst_QTextCursor::startOfWord()
1260 cursor
.insertText("first second");
1261 cursor
.setPosition(7);
1262 cursor
.movePosition(QTextCursor::StartOfWord
);
1263 QCOMPARE(cursor
.position(), 0);
1266 void tst_QTextCursor::selectBlock()
1268 cursor
.insertText("foobar");
1269 QTextBlockFormat blockFmt
;
1270 blockFmt
.setAlignment(Qt::AlignHCenter
);
1271 cursor
.insertBlock(blockFmt
);
1272 cursor
.insertText("blah");
1273 cursor
.insertBlock(QTextBlockFormat());
1275 cursor
.movePosition(QTextCursor::PreviousBlock
);
1276 QCOMPARE(cursor
.block().text(), QString("blah"));
1278 cursor
.select(QTextCursor::BlockUnderCursor
);
1279 QVERIFY(cursor
.hasSelection());
1281 QTextDocumentFragment
fragment(cursor
);
1283 cursor
.insertFragment(fragment
);
1284 QCOMPARE(blockCount(), 2);
1286 cursor
.movePosition(QTextCursor::Start
);
1287 cursor
.movePosition(QTextCursor::NextBlock
);
1288 QVERIFY(cursor
.blockFormat().alignment() == Qt::AlignHCenter
);
1289 QCOMPARE(cursor
.block().text(), QString("blah"));
1292 void tst_QTextCursor::selectVisually()
1294 cursor
.insertText("Foo\nlong line which is probably going to be cut in two when shown in a widget\nparagraph 3\n");
1296 cursor
.setPosition(6); // somewhere in the long paragraph.
1297 cursor
.select(QTextCursor::LineUnderCursor
);
1298 // since we are not yet layed-out, we expect the whole paragraph to be selected.
1299 QCOMPARE(cursor
.position(), 77);
1300 QCOMPARE(cursor
.anchor(), 4);
1303 void tst_QTextCursor::insertText()
1305 QString txt
= "Foo\nBar\r\nMeep";
1306 txt
+= QChar::LineSeparator
;
1308 txt
+= QChar::ParagraphSeparator
;
1310 cursor
.insertText(txt
);
1311 QCOMPARE(blockCount(), 4);
1312 cursor
.movePosition(QTextCursor::Start
);
1313 QCOMPARE(cursor
.block().text(), QString("Foo"));
1314 cursor
.movePosition(QTextCursor::NextBlock
);
1315 QCOMPARE(cursor
.block().text(), QString("Bar"));
1316 cursor
.movePosition(QTextCursor::NextBlock
);
1317 QCOMPARE(cursor
.block().text(), QString(QString("Meep") + QChar(QChar::LineSeparator
) + QString("Baz")));
1318 cursor
.movePosition(QTextCursor::NextBlock
);
1319 QCOMPARE(cursor
.block().text(), QString("yoyodyne"));
1322 void tst_QTextCursor::insertFragmentShouldUseCurrentCharFormat()
1324 QTextDocumentFragment fragment
= QTextDocumentFragment::fromPlainText("Hello World");
1325 QTextCharFormat fmt
;
1326 fmt
.setFontUnderline(true);
1328 cursor
.clearSelection();
1329 cursor
.setCharFormat(fmt
);
1330 cursor
.insertFragment(fragment
);
1331 cursor
.movePosition(QTextCursor::Start
);
1332 cursor
.movePosition(QTextCursor::NextCharacter
);
1333 QVERIFY(cursor
.charFormat() == fmt
);
1336 int tst_QTextCursor::blockCount()
1339 for (QTextBlock blk
= doc
->begin(); blk
.isValid(); blk
= blk
.next())
1344 void tst_QTextCursor::endOfLine()
1346 doc
->setPageSize(QSizeF(100000, INT_MAX
));
1348 QString
text("First Line \nSecond Line ");
1349 text
.replace(QLatin1Char('\n'), QChar(QChar::LineSeparator
));
1350 cursor
.insertText(text
);
1353 doc
->documentLayout()->documentSize();
1355 cursor
.movePosition(QTextCursor::Start
);
1357 QCOMPARE(cursor
.block().layout()->lineCount(), 2);
1359 cursor
.movePosition(QTextCursor::EndOfLine
);
1360 QCOMPARE(cursor
.position(), 14);
1361 cursor
.movePosition(QTextCursor::NextCharacter
);
1362 QCOMPARE(cursor
.position(), 15);
1363 cursor
.movePosition(QTextCursor::EndOfLine
);
1364 QCOMPARE(cursor
.position(), 28);
1367 class CursorListener
: public QObject
1371 CursorListener(QTextCursor
*_cursor
) : lastRecordedPosition(-1), lastRecordedAnchor(-1), recordingCount(0), cursor(_cursor
) {}
1373 int lastRecordedPosition
;
1374 int lastRecordedAnchor
;
1378 void recordCursorPosition()
1380 lastRecordedPosition
= cursor
->position();
1381 lastRecordedAnchor
= cursor
->anchor();
1386 QTextCursor
*cursor
;
1389 void tst_QTextCursor::editBlocksDuringRemove()
1391 CursorListener
listener(&cursor
);
1393 cursor
.insertText("Hello World");
1394 cursor
.movePosition(QTextCursor::Start
, QTextCursor::KeepAnchor
);
1395 QCOMPARE(cursor
.selectedText(), QString("Hello World"));
1397 connect(doc
, SIGNAL(contentsChanged()), &listener
, SLOT(recordCursorPosition()));
1398 listener
.recordingCount
= 0;
1399 cursor
.deleteChar();
1401 QCOMPARE(listener
.recordingCount
, 1);
1402 QCOMPARE(listener
.lastRecordedPosition
, 0);
1403 QCOMPARE(listener
.lastRecordedAnchor
, 0);
1405 QVERIFY(doc
->toPlainText().isEmpty());
1408 void tst_QTextCursor::update_data()
1410 QTest::addColumn
<QString
>("text");
1411 QTest::addColumn
<int>("position");
1412 QTest::addColumn
<int>("anchor");
1413 QTest::addColumn
<int>("modifyPosition");
1414 QTest::addColumn
<int>("modifyAnchor");
1415 QTest::addColumn
<QString
>("insertText");
1416 QTest::addColumn
<int>("expectedPosition");
1417 QTest::addColumn
<int>("expectedAnchor");
1419 QString
text("Hello big world");
1420 int charsToDelete
= 3;
1421 QTest::newRow("removeInsideSelection")
1424 << /*anchor*/ text
.length()
1427 << 6 + charsToDelete
1428 << QString() // don't insert anything, just remove
1429 << /*expectedPosition*/ 0
1430 << /*expectedAnchor*/ text
.length() - charsToDelete
1433 text
= "Hello big world";
1435 QTest::newRow("removeInsideSelectionWithSwappedAnchorAndPosition")
1437 << /*position*/ text
.length()
1441 << 6 + charsToDelete
1442 << QString() // don't insert anything, just remove
1443 << /*expectedPosition*/ text
.length() - charsToDelete
1444 << /*expectedAnchor*/ 0
1448 text
= "Hello big world";
1450 QString
textToInsert("small");
1451 QTest::newRow("replaceInsideSelection")
1454 << /*anchor*/ text
.length()
1457 << 6 + charsToDelete
1458 << textToInsert
// ... and replace 'big' with 'small'
1459 << /*expectedPosition*/ 0
1460 << /*expectedAnchor*/ text
.length() - charsToDelete
+ textToInsert
.length()
1463 text
= "Hello big world";
1465 textToInsert
= "small";
1466 QTest::newRow("replaceInsideSelectionWithSwappedAnchorAndPosition")
1468 << /*position*/ text
.length()
1472 << 6 + charsToDelete
1473 << textToInsert
// ... and replace 'big' with 'small'
1474 << /*expectedPosition*/ text
.length() - charsToDelete
+ textToInsert
.length()
1475 << /*expectedAnchor*/ 0
1479 text
= "Hello big world";
1481 QTest::newRow("removeBeforeSelection")
1483 << /*position*/ text
.length() - 5
1484 << /*anchor*/ text
.length()
1487 << 6 + charsToDelete
1488 << QString() // don't insert anything, just remove
1489 << /*expectedPosition*/ text
.length() - 5 - charsToDelete
1490 << /*expectedAnchor*/ text
.length() - charsToDelete
1493 text
= "Hello big world";
1495 QTest::newRow("removeAfterSelection")
1501 << 6 + charsToDelete
1502 << QString() // don't insert anything, just remove
1503 << /*expectedPosition*/ 0
1504 << /*expectedAnchor*/ 4
1509 void tst_QTextCursor::update()
1511 QFETCH(QString
, text
);
1513 doc
->setPlainText(text
);
1515 QFETCH(int, position
);
1516 QFETCH(int, anchor
);
1518 cursor
.setPosition(anchor
);
1519 cursor
.setPosition(position
, QTextCursor::KeepAnchor
);
1521 QCOMPARE(cursor
.position(), position
);
1522 QCOMPARE(cursor
.anchor(), anchor
);
1524 QFETCH(int, modifyPosition
);
1525 QFETCH(int, modifyAnchor
);
1527 QTextCursor modifyCursor
= cursor
;
1528 modifyCursor
.setPosition(modifyAnchor
);
1529 modifyCursor
.setPosition(modifyPosition
, QTextCursor::KeepAnchor
);
1531 QCOMPARE(modifyCursor
.position(), modifyPosition
);
1532 QCOMPARE(modifyCursor
.anchor(), modifyAnchor
);
1534 QFETCH(QString
, insertText
);
1535 modifyCursor
.insertText(insertText
);
1537 QFETCH(int, expectedPosition
);
1538 QFETCH(int, expectedAnchor
);
1540 QCOMPARE(cursor
.position(), expectedPosition
);
1541 QCOMPARE(cursor
.anchor(), expectedAnchor
);
1544 void tst_QTextCursor::disallowSettingObjectIndicesOnCharFormats()
1546 QTextCharFormat fmt
;
1547 fmt
.setObjectIndex(42);
1548 cursor
.insertText("Hey", fmt
);
1549 QCOMPARE(cursor
.charFormat().objectIndex(), -1);
1551 cursor
.select(QTextCursor::Document
);
1552 cursor
.mergeCharFormat(fmt
);
1553 QCOMPARE(doc
->begin().begin().fragment().charFormat().objectIndex(), -1);
1555 cursor
.select(QTextCursor::Document
);
1556 cursor
.setCharFormat(fmt
);
1557 QCOMPARE(doc
->begin().begin().fragment().charFormat().objectIndex(), -1);
1559 cursor
.setBlockCharFormat(fmt
);
1560 QCOMPARE(cursor
.blockCharFormat().objectIndex(), -1);
1562 cursor
.movePosition(QTextCursor::End
);
1563 cursor
.insertBlock(QTextBlockFormat(), fmt
);
1564 QCOMPARE(cursor
.blockCharFormat().objectIndex(), -1);
1568 QTextTable
*table
= cursor
.insertTable(1, 1);
1569 cursor
.select(QTextCursor::Document
);
1570 cursor
.setCharFormat(fmt
);
1572 cursor
= table
->cellAt(0, 0).firstCursorPosition();
1573 QVERIFY(!cursor
.isNull());
1574 QCOMPARE(cursor
.blockCharFormat().objectIndex(), table
->objectIndex());
1577 void tst_QTextCursor::blockAndColumnNumber()
1579 QCOMPARE(QTextCursor().columnNumber(), 0);
1580 QCOMPARE(QTextCursor().blockNumber(), 0);
1582 QCOMPARE(cursor
.columnNumber(), 0);
1583 QCOMPARE(cursor
.blockNumber(), 0);
1584 cursor
.insertText("Hello");
1585 QCOMPARE(cursor
.columnNumber(), 5);
1586 QCOMPARE(cursor
.blockNumber(), 0);
1588 cursor
.insertBlock();
1589 QCOMPARE(cursor
.columnNumber(), 0);
1590 QCOMPARE(cursor
.blockNumber(), 1);
1591 cursor
.insertText("Blah");
1592 QCOMPARE(cursor
.blockNumber(), 1);
1595 doc
->documentLayout();
1597 cursor
.insertBlock();
1598 QCOMPARE(cursor
.columnNumber(), 0);
1599 QCOMPARE(cursor
.blockNumber(), 2);
1600 cursor
.insertText("Test");
1601 QCOMPARE(cursor
.columnNumber(), 4);
1602 QCOMPARE(cursor
.blockNumber(), 2);
1603 cursor
.insertText(QString(QChar(QChar::LineSeparator
)));
1604 QCOMPARE(cursor
.columnNumber(), 0);
1605 QCOMPARE(cursor
.blockNumber(), 2);
1606 cursor
.insertText("A");
1607 QCOMPARE(cursor
.columnNumber(), 1);
1608 QCOMPARE(cursor
.blockNumber(), 2);
1611 void tst_QTextCursor::movePositionEndOfLine()
1613 cursor
.insertText("blah\nblah\n");
1614 // Select part of the second line ("la")
1615 cursor
.setPosition(6);
1616 cursor
.movePosition(QTextCursor::NextCharacter
, QTextCursor::KeepAnchor
, 2);
1617 QCOMPARE(cursor
.selectedText(), QLatin1String("la"));
1620 doc
->documentLayout();
1622 // Remove "la" and append "something" to the end in one undo operation
1623 cursor
.beginEditBlock();
1624 cursor
.removeSelectedText();
1625 QTextCursor
c2(doc
);
1627 c2
.insertText("foo"); // append to doc without touching the cursor.
1629 QCOMPARE(cursor
.position(), 6);
1630 cursor
.movePosition(QTextCursor::EndOfLine
); // in an edit block visual movement is moved to the end of the paragraph
1631 QCOMPARE(cursor
.position(), 10);
1632 cursor
.endEditBlock();
1635 void tst_QTextCursor::clearCells()
1637 QTextTable
*table
= cursor
.insertTable(3, 5);
1638 cursor
.setPosition(table
->cellAt(0,0).firstPosition()); // select cell 1 and cell 2
1639 cursor
.setPosition(table
->cellAt(0,1).firstPosition(), QTextCursor::KeepAnchor
);
1640 cursor
.deleteChar(); // should clear the cells, and not crash ;)
1643 void tst_QTextCursor::task244408_wordUnderCursor_data()
1645 QTest::addColumn
<QString
>("input");
1646 QTest::addColumn
<QString
>("expected");
1647 QTest::newRow("trailingSpace") << QString::fromLatin1("foo ") << QString::fromLatin1("");
1648 QTest::newRow("noTrailingSpace") << QString::fromLatin1("foo") << QString::fromLatin1("foo");
1651 void tst_QTextCursor::task244408_wordUnderCursor()
1653 QFETCH(QString
, input
);
1654 QFETCH(QString
, expected
);
1655 cursor
.insertText(input
);
1656 cursor
.movePosition(QTextCursor::End
);
1657 cursor
.select(QTextCursor::WordUnderCursor
);
1658 QCOMPARE(cursor
.selectedText(), expected
);
1661 QTEST_MAIN(tst_QTextCursor
)
1662 #include "tst_qtextcursor.moc"