Fix macplist autotest
[qt-netbsd.git] / tests / auto / qtextcursor / tst_qtextcursor.cpp
blob88ecc73a857ce5699f5823fae783a935b331a0a6
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
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
14 ** this package.
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.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
43 #include <QtTest/QtTest>
46 #include <qtextdocument.h>
47 #include <qtexttable.h>
48 #include <qvariant.h>
49 #include <qtextdocumentfragment.h>
50 #include <qabstracttextdocumentlayout.h>
51 #include <qtextlayout.h>
52 #include <qtextcursor.h>
53 #include <qdebug.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
61 Q_OBJECT
63 public:
64 tst_QTextCursor();
67 public slots:
68 void init();
69 void cleanup();
70 private slots:
71 void navigation1();
72 void navigation2_data();
73 void navigation2();
74 void navigation3();
75 void navigation4();
76 void navigation5();
77 void navigation6();
78 void navigation7();
79 void navigation8();
80 void navigation9();
81 void navigation10();
82 void movePositionEndOfLine();
83 void insertBlock();
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();
93 void selection1();
94 void dontCopyTableAttributes();
96 void checkFrame1();
97 void checkFrame2();
99 void tableMovement();
100 void selectionsInTable();
102 void insertBlockToUseCharFormat();
104 void selectedText();
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();
123 void selectWord();
124 void selectWordWithSeparators_data();
125 void selectWordWithSeparators();
126 void startOfWord();
127 void selectBlock();
128 void selectVisually();
130 void insertText();
132 void insertFragmentShouldUseCurrentCharFormat();
134 void endOfLine();
136 void editBlocksDuringRemove();
138 void update_data();
139 void update();
141 void disallowSettingObjectIndicesOnCharFormats();
143 void blockAndColumnNumber();
145 void clearCells();
147 void task244408_wordUnderCursor_data();
148 void task244408_wordUnderCursor();
150 private:
151 int blockCount();
153 QTextDocument *doc;
154 QTextCursor cursor;
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();
171 delete doc;
172 doc = 0;
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);
201 doc->undo();
202 QVERIFY(cursor.position() == 2);
203 doc->redo();
204 QVERIFY(cursor.position() == 5);
206 doc->undo();
208 doc->undo();
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);
231 QTextCharFormat fmt;
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)
258 ) << 29;
259 QTest::newRow("multiBlock1") << (QStringList() << QString("Happy happy happy")
260 << QString("Joy Joy Joy"))
261 << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock))
262 << 18;
263 QTest::newRow("multiBlock2") << (QStringList() << QString("Happy happy happy")
264 << QString("Joy Joy Joy"))
265 << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)
266 << QVariant(QTextCursor::EndOfBlock))
267 << 29;
268 QTest::newRow("multiBlock3") << (QStringList() << QString("Happy happy happy")
269 << QString("Joy Joy Joy"))
270 << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)
271 << QVariant(QTextCursor::StartOfBlock))
272 << 18;
273 QTest::newRow("multiBlock4") << (QStringList() << QString("Happy happy happy")
274 << QString("Joy Joy Joy"))
275 << (QList<QVariant>() << QVariant(QTextCursor::Start)
276 << QVariant(QTextCursor::EndOfBlock))
277 << 17;
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))
283 << 17;
284 QTest::newRow("multiBlock6") << (QStringList() << QString("Happy happy happy")
285 << QString("Joy Joy Joy"))
286 << (QList<QVariant>() << QVariant(QTextCursor::End)
287 << QVariant(QTextCursor::StartOfBlock))
288 << 18;
289 QTest::newRow("multiBlock7") << (QStringList() << QString("Happy happy happy")
290 << QString("Joy Joy Joy"))
291 << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock))
292 << 0;
293 QTest::newRow("multiBlock8") << (QStringList() << QString("Happy happy happy")
294 << QString("Joy Joy Joy"))
295 << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock)
296 << QVariant(QTextCursor::EndOfBlock))
297 << 17;
298 QTest::newRow("multiBlock9") << (QStringList() << QString("Happy happy happy")
299 << QString("Joy Joy Joy"))
300 << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock)
301 << QVariant(QTextCursor::NextBlock))
302 << 18;
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))
308 << 18;
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))
314 << 29;
315 QTest::newRow("PreviousWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
316 << (QList<QVariant>() << QVariant(QTextCursor::PreviousWord))
317 << 26;
318 QTest::newRow("PreviousWord2") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
319 << (QList<QVariant>() << QVariant(QTextCursor::PreviousWord)
320 << QVariant(QTextCursor::PreviousWord))
321 << 22;
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))
326 << 25;
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))
331 << 26;
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))
336 << 11;
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))
341 << 22;
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))
347 << 6;
349 QTest::newRow("PreviousCharacter") << (QStringList() << QString("Happy happy Joy Joy"))
350 << (QList<QVariant>() << QVariant(QTextCursor::PreviousCharacter)
351 << QVariant(QTextCursor::PreviousCharacter))
352 << 17;
355 void tst_QTextCursor::navigation2()
357 QFETCH(QStringList, sl);
358 QFETCH(QList<QVariant>, movement);
359 int i;
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);
420 do {
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>"
463 "<table>"
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>"
467 "</table></html");
468 QCOMPARE(cursor.position(), 101); // end of document
469 cursor.setPosition(0);
470 QCOMPARE(cursor.position(), 0);
471 bool ok = cursor.movePosition(QTextCursor::EndOfLine);
472 QVERIFY(ok);
473 QCOMPARE(cursor.position(), 24);
474 ok = cursor.movePosition(QTextCursor::NextBlock);
475 QCOMPARE(cursor.position(), 25); // cell 1
476 ok = cursor.movePosition(QTextCursor::NextCell);
477 QVERIFY(ok);
478 QCOMPARE(cursor.position(), 39); // another..
479 ok = cursor.movePosition(QTextCursor::NextCell);
480 QVERIFY(ok);
481 QCOMPARE(cursor.position(), 52); // empty
482 ok = cursor.movePosition(QTextCursor::NextCell);
483 QVERIFY(ok);
484 QCOMPARE(cursor.position(), 53); // last on row 1
485 ok = cursor.movePosition(QTextCursor::NextCell);
486 QVERIFY(ok);
487 QCOMPARE(cursor.position(), 69); // row 2
488 ok = cursor.movePosition(QTextCursor::NextCell);
489 QVERIFY(ok);
490 QCOMPARE(cursor.position(), 75);
491 ok = cursor.movePosition(QTextCursor::NextCell);
492 QVERIFY(ok);
493 QCOMPARE(cursor.position(), 83);
494 ok = cursor.movePosition(QTextCursor::NextCell);
495 QVERIFY(ok);
496 QCOMPARE(cursor.position(), 93); // row 3
497 ok = cursor.movePosition(QTextCursor::NextCell);
498 QVERIFY(ok);
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);
507 QVERIFY(ok);
508 QCOMPARE(cursor.position(), 93);
509 ok = cursor.movePosition(QTextCursor::PreviousCell);
510 QVERIFY(ok);
511 QCOMPARE(cursor.position(), 83);
512 ok = cursor.movePosition(QTextCursor::PreviousCell);
513 QVERIFY(ok);
514 QCOMPARE(cursor.position(), 75);
515 ok = cursor.movePosition(QTextCursor::PreviousCell);
516 QVERIFY(ok);
517 QCOMPARE(cursor.position(), 69);
518 ok = cursor.movePosition(QTextCursor::PreviousCell);
519 QVERIFY(ok);
520 QCOMPARE(cursor.position(), 53);
521 ok = cursor.movePosition(QTextCursor::PreviousCell);
522 QVERIFY(ok);
523 QCOMPARE(cursor.position(), 52);
524 ok = cursor.movePosition(QTextCursor::PreviousCell);
525 QVERIFY(ok);
526 QCOMPARE(cursor.position(), 39);
527 ok = cursor.movePosition(QTextCursor::PreviousCell);
528 QVERIFY(ok);
529 QCOMPARE(cursor.position(), 25);
530 ok = cursor.movePosition(QTextCursor::PreviousCell);
531 QVERIFY(!ok);
532 QCOMPARE(cursor.position(), 25); // can't leave the table
534 ok = cursor.movePosition(QTextCursor::NextRow);
535 QVERIFY(ok);
536 QCOMPARE(cursor.position(), 69);
537 ok = cursor.movePosition(QTextCursor::NextRow);
538 QVERIFY(ok);
539 QCOMPARE(cursor.position(), 93);
540 ok = cursor.movePosition(QTextCursor::NextRow);
541 QVERIFY(!ok);
542 QCOMPARE(cursor.position(), 93); // didn't move
544 ok = cursor.movePosition(QTextCursor::PreviousRow);
545 QVERIFY(ok);
546 QCOMPARE(cursor.position(), 83); // last col in row 2
547 ok = cursor.movePosition(QTextCursor::PreviousRow);
548 QVERIFY(ok);
549 QCOMPARE(cursor.position(), 53); // last col in row 1
550 ok = cursor.movePosition(QTextCursor::PreviousRow);
551 QVERIFY(!ok);
552 QCOMPARE(cursor.position(), 53);
554 // test usecase of jumping over a cell
555 doc->clear();
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);
559 QVERIFY(ok);
560 QCOMPARE(cursor.position(), 3); // b
561 ok = cursor.movePosition(QTextCursor::NextCell);
562 QVERIFY(ok);
563 QCOMPARE(cursor.position(), 5); // c
564 ok = cursor.movePosition(QTextCursor::PreviousCell);
565 QVERIFY(ok);
566 QCOMPARE(cursor.position(), 3); // b
567 ok = cursor.movePosition(QTextCursor::PreviousCell);
568 QVERIFY(ok);
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()
687 QTextDocument doc1;
688 QTextDocument doc2;
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
713 * extend the cell */
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());
724 QVERIFY(frame != 0);
726 QTextFrame *root = frame->parentFrame();
727 QVERIFY(root != 0);
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);
738 doc->undo();
740 QVERIFY(!frame);
741 QVERIFY(root->childFrames().size() == 0);
743 QVERIFY(cursor.position() == 0);
744 QVERIFY(cursor.selectionStart() == 0);
745 QVERIFY(cursor.selectionEnd() == 0);
747 doc->redo();
749 frame = doc->frameAt(1);
751 QVERIFY(frame);
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);
786 doc->undo();
788 QVERIFY(!frame);
789 QVERIFY(root->childFrames().size() == 0);
791 QVERIFY(cursor.position() == 0);
792 QVERIFY(cursor.selectionStart() == 0);
793 QVERIFY(cursor.selectionEnd() == 1);
795 doc->redo();
797 frame = doc->frameAt(1);
799 QVERIFY(frame);
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()
817 QTextCharFormat fmt;
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"));
1026 doc->undo();
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);
1282 doc->clear();
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;
1307 txt += "Baz";
1308 txt += QChar::ParagraphSeparator;
1309 txt += "yoyodyne";
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()
1338 int cnt = 0;
1339 for (QTextBlock blk = doc->begin(); blk.isValid(); blk = blk.next())
1340 ++cnt;
1341 return cnt;
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);
1352 // ensure layouted
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
1369 Q_OBJECT
1370 public:
1371 CursorListener(QTextCursor *_cursor) : lastRecordedPosition(-1), lastRecordedAnchor(-1), recordingCount(0), cursor(_cursor) {}
1373 int lastRecordedPosition;
1374 int lastRecordedAnchor;
1375 int recordingCount;
1377 public slots:
1378 void recordCursorPosition()
1380 lastRecordedPosition = cursor->position();
1381 lastRecordedAnchor = cursor->anchor();
1382 ++recordingCount;
1385 private:
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")
1422 << text
1423 << /*position*/ 0
1424 << /*anchor*/ text.length()
1425 // delete 'big'
1426 << 6
1427 << 6 + charsToDelete
1428 << QString() // don't insert anything, just remove
1429 << /*expectedPosition*/ 0
1430 << /*expectedAnchor*/ text.length() - charsToDelete
1433 text = "Hello big world";
1434 charsToDelete = 3;
1435 QTest::newRow("removeInsideSelectionWithSwappedAnchorAndPosition")
1436 << text
1437 << /*position*/ text.length()
1438 << /*anchor*/ 0
1439 // delete 'big'
1440 << 6
1441 << 6 + charsToDelete
1442 << QString() // don't insert anything, just remove
1443 << /*expectedPosition*/ text.length() - charsToDelete
1444 << /*expectedAnchor*/ 0
1448 text = "Hello big world";
1449 charsToDelete = 3;
1450 QString textToInsert("small");
1451 QTest::newRow("replaceInsideSelection")
1452 << text
1453 << /*position*/ 0
1454 << /*anchor*/ text.length()
1455 // delete 'big' ...
1456 << 6
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";
1464 charsToDelete = 3;
1465 textToInsert = "small";
1466 QTest::newRow("replaceInsideSelectionWithSwappedAnchorAndPosition")
1467 << text
1468 << /*position*/ text.length()
1469 << /*anchor*/ 0
1470 // delete 'big' ...
1471 << 6
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";
1480 charsToDelete = 3;
1481 QTest::newRow("removeBeforeSelection")
1482 << text
1483 << /*position*/ text.length() - 5
1484 << /*anchor*/ text.length()
1485 // delete 'big'
1486 << 6
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";
1494 charsToDelete = 3;
1495 QTest::newRow("removeAfterSelection")
1496 << text
1497 << /*position*/ 0
1498 << /*anchor*/ 4
1499 // delete 'big'
1500 << 6
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);
1566 doc->clear();
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);
1594 // trigger a layout
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"));
1619 // trigger a layout
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);
1626 c2.setPosition(7);
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"