tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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.
       
    15 **
       
    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.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #define private public
       
    46 
       
    47 #include <qtextdocument.h>
       
    48 #include <private/qtextdocument_p.h>
       
    49 #include <qabstracttextdocumentlayout.h>
       
    50 #include <qtextobject.h>
       
    51 #include <qdebug.h>
       
    52 #include <stdlib.h>
       
    53 #include <qtextcursor.h>
       
    54 #include "../qtextdocument/common.h"
       
    55 
       
    56 //TESTED_FILES=gui/text/qtextdocument_p.cpp gui/text/qtextdocument_p.h
       
    57 
       
    58 class tst_QTextPieceTable : public QObject
       
    59 {
       
    60     Q_OBJECT
       
    61 
       
    62 public:
       
    63     tst_QTextPieceTable();
       
    64 
       
    65 
       
    66 public slots:
       
    67     void init();
       
    68     void cleanup();
       
    69 private slots:
       
    70     void insertion1();
       
    71     void insertion2();
       
    72     void insertion3();
       
    73     void insertion4();
       
    74     void insertion5();
       
    75 
       
    76     void removal1();
       
    77     void removal2();
       
    78     void removal3();
       
    79     void removal4();
       
    80 
       
    81     void undoRedo1();
       
    82     void undoRedo2();
       
    83     void undoRedo3();
       
    84     void undoRedo4();
       
    85     void undoRedo5();
       
    86     void undoRedo6();
       
    87     void undoRedo7();
       
    88     void undoRedo8();
       
    89     void undoRedo9();
       
    90     void undoRedo10();
       
    91     void undoRedo11();
       
    92 
       
    93     void checkDocumentChanged();
       
    94     void checkDocumentChanged2();
       
    95     void setBlockFormat();
       
    96 
       
    97     void blockInsertion();
       
    98     void blockInsertion2();
       
    99 
       
   100     void blockRemoval1();
       
   101     void blockRemoval2();
       
   102     void blockRemoval3();
       
   103     void blockRemoval4();
       
   104     void blockRemoval5();
       
   105 
       
   106     void checkBlockSeparation();
       
   107 
       
   108     void checkFrames1();
       
   109     void removeFrameDirect();
       
   110     void removeWithChildFrame();
       
   111     void clearWithFrames();
       
   112 
       
   113 private:
       
   114     QTextDocument *doc;
       
   115     QTextDocumentPrivate *table;
       
   116     int blockFormatIndex;
       
   117     int charFormatIndex;
       
   118 };
       
   119 
       
   120 tst_QTextPieceTable::tst_QTextPieceTable()
       
   121 { doc = 0; table = 0; }
       
   122 
       
   123 
       
   124 void tst_QTextPieceTable::init()
       
   125 {
       
   126     doc = new QTextDocument(0);
       
   127     table = doc->d_func();
       
   128     blockFormatIndex = table->formatCollection()->indexForFormat(QTextBlockFormat());
       
   129     charFormatIndex = table->formatCollection()->indexForFormat(QTextCharFormat());
       
   130 }
       
   131 
       
   132 void tst_QTextPieceTable::cleanup()
       
   133 {
       
   134     delete doc;
       
   135     doc = 0;
       
   136 }
       
   137 
       
   138 void tst_QTextPieceTable::insertion1()
       
   139 {
       
   140     table->insert(0, "aacc", charFormatIndex);
       
   141     QCOMPARE(table->plainText(), QString("aacc"));
       
   142     table->insert(2, "bb", charFormatIndex);
       
   143     QCOMPARE(table->plainText(), QString("aabbcc"));
       
   144     table->insert(1, "1", charFormatIndex);
       
   145     QCOMPARE(table->plainText(), QString("a1abbcc"));
       
   146     table->insert(6, "d", charFormatIndex);
       
   147     QCOMPARE(table->plainText(), QString("a1abbcdc"));
       
   148     table->insert(8, "z", charFormatIndex);
       
   149     QCOMPARE(table->plainText(), QString("a1abbcdcz"));
       
   150 }
       
   151 
       
   152 void tst_QTextPieceTable::insertion2()
       
   153 {
       
   154     table->insert(0, "bb", charFormatIndex);
       
   155     QCOMPARE(table->plainText(), QString("bb"));
       
   156 }
       
   157 
       
   158 void tst_QTextPieceTable::insertion3()
       
   159 {
       
   160     QString compare;
       
   161     for (int i = 0; i < 20000; ++i) {
       
   162 	int pos = rand() % (i+1);
       
   163 	QChar c((unsigned short)(i & 0xff) + 1);
       
   164 	QString str;
       
   165 	str += c;
       
   166 	table->insert(pos, str, charFormatIndex);
       
   167 	compare.insert(pos, str);
       
   168     }
       
   169     QVERIFY(table->plainText() == compare);
       
   170 }
       
   171 
       
   172 void tst_QTextPieceTable::insertion4()
       
   173 {
       
   174     QString compare;
       
   175     for (int i = 0; i < 20000; ++i) {
       
   176 	int pos = rand() % (i+1);
       
   177 	QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
       
   178 	QString str;
       
   179 	str += c;
       
   180 	str += c;
       
   181 	table->insert(pos, str, charFormatIndex);
       
   182 	compare.insert(pos, str);
       
   183 	// 	    if (table->text() != compare) {
       
   184 	// 		qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot      '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->text().latin1());
       
   185 	// 		exit(12);
       
   186 	// 	    }
       
   187     }
       
   188     QVERIFY(table->plainText() == compare);
       
   189 }
       
   190 
       
   191 void tst_QTextPieceTable::insertion5()
       
   192 {
       
   193     QString compare;
       
   194     for (int i = 0; i < 20000; ++i) {
       
   195 	int pos = rand() % (i+1);
       
   196 	QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
       
   197 	QString str;
       
   198 	str += c;
       
   199 	str += c;
       
   200 	if (c == 'a') {
       
   201 	    table->insertBlock(pos, blockFormatIndex, charFormatIndex);
       
   202 	    str = QChar(QChar::ParagraphSeparator);
       
   203 	} else {
       
   204 	    table->insert(pos, str, charFormatIndex);
       
   205 	}
       
   206 	compare.insert(pos, str);
       
   207     }
       
   208     QVERIFY(table->plainText() == compare);
       
   209     for (QTextBlock it = table->blocksBegin(); it != table->blocksEnd(); it = it.next()) {
       
   210 	QTextDocumentPrivate::FragmentIterator fit = table->find(it.position());
       
   211 	QVERIFY(fit.position() == it.position());
       
   212     }
       
   213 }
       
   214 
       
   215 void tst_QTextPieceTable::removal1()
       
   216 {
       
   217     table->insert(0, "abbccc", charFormatIndex);
       
   218     QCOMPARE(table->plainText(), QString("abbccc"));
       
   219     table->remove(1, 2);
       
   220     QCOMPARE(table->plainText(), QString("accc"));
       
   221     table->insert(1, "1", charFormatIndex);
       
   222     QCOMPARE(table->plainText(), QString("a1ccc"));
       
   223     table->remove(4, 1);
       
   224     QCOMPARE(table->plainText(), QString("a1cc"));
       
   225     table->insert(4, "z", charFormatIndex);
       
   226     QCOMPARE(table->plainText(), QString("a1ccz"));
       
   227 }
       
   228 
       
   229 void tst_QTextPieceTable::removal2()
       
   230 {
       
   231     table->insert(0, "bb", charFormatIndex);
       
   232     QCOMPARE(table->plainText(), QString("bb"));
       
   233     table->remove(0, 2);
       
   234     QCOMPARE(table->plainText(), QString(""));
       
   235     table->insertBlock(0, blockFormatIndex, charFormatIndex);
       
   236     QCOMPARE(table->plainText(), QString(QChar(QChar::ParagraphSeparator)));
       
   237     table->remove(0, 1);
       
   238     QCOMPARE(table->plainText(), QString(""));
       
   239 
       
   240     table->insert(0, "bb", charFormatIndex);
       
   241     QCOMPARE(table->plainText(), QString("bb"));
       
   242     table->insertBlock(1, blockFormatIndex, charFormatIndex);
       
   243     QCOMPARE(table->plainText(), QString("b") + QString(QChar(QChar::ParagraphSeparator)) + QString("b"));
       
   244     table->remove(1, 1);
       
   245     QCOMPARE(table->plainText(), QString("bb"));
       
   246 }
       
   247 
       
   248 void tst_QTextPieceTable::removal3()
       
   249 {
       
   250     QString compare;
       
   251     int l = 0;
       
   252     for (int i = 0; i < 20000; ++i) {
       
   253 	bool remove = l && (rand() % 2);
       
   254 	int pos = rand() % (remove ? l : (l+1));
       
   255 	QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
       
   256 	QString str;
       
   257 	str += c;
       
   258 	str += c;
       
   259 	if (remove && pos < table->length()) {
       
   260 	    compare.remove(pos, 1);
       
   261 	    table->remove(pos, 1);
       
   262 	} else {
       
   263 	    compare.insert(pos, str);
       
   264 	    table->insert(pos, str, charFormatIndex);
       
   265 	}
       
   266 	l += remove ? -1 : 2;
       
   267 	// 	    if (table->text() != compare) {
       
   268 	// 		qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot      '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->text().latin1());
       
   269 	// 		exit(12);
       
   270 	// 	    }
       
   271     }
       
   272     QVERIFY(table->plainText() == compare);
       
   273 }
       
   274 
       
   275 void tst_QTextPieceTable::removal4()
       
   276 {
       
   277     QString compare;
       
   278     int l = 0;
       
   279     for (int i = 0; i < 20000; ++i) {
       
   280 	bool remove = l && (rand() % 2);
       
   281 	int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0;
       
   282 	QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
       
   283 	QString str;
       
   284 	if (c != 'a') {
       
   285 	    str += c;
       
   286 	    str += c;
       
   287 	} else {
       
   288 	    str = QChar(QChar::ParagraphSeparator);
       
   289 	}
       
   290 	if (remove && pos < table->length() - 1) {
       
   291 	    compare.remove(pos, 1);
       
   292 	    table->remove(pos, 1);
       
   293 	} else {
       
   294 	    if (str[0] == QChar(QChar::ParagraphSeparator))
       
   295 		table->insertBlock(pos, blockFormatIndex, charFormatIndex);
       
   296 	    else
       
   297 		table->insert(pos, str, charFormatIndex);
       
   298 	    compare.insert(pos, str);
       
   299 	}
       
   300 	l += remove ? -1 : 2;
       
   301 // 	if (table->plainText() != compare) {
       
   302 // 	    qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot      '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->plainText().latin1());
       
   303 // 	    exit(12);
       
   304 // 	}
       
   305     }
       
   306     QVERIFY(table->plainText() == compare);
       
   307 }
       
   308 
       
   309 void tst_QTextPieceTable::undoRedo1()
       
   310 {
       
   311     table->insert(0, "01234567", charFormatIndex);
       
   312     table->insert(0, "a", charFormatIndex);
       
   313     table->insert(1, "b", charFormatIndex);
       
   314     QCOMPARE(table->plainText(), QString("ab01234567"));
       
   315     table->undo();
       
   316     QCOMPARE(table->plainText(), QString("01234567"));
       
   317     table->redo();
       
   318     QCOMPARE(table->plainText(), QString("ab01234567"));
       
   319     table->undo();
       
   320     table->insert(1, "c", charFormatIndex);
       
   321     QCOMPARE(table->plainText(), QString("0c1234567"));
       
   322     table->undo();
       
   323     QCOMPARE(table->plainText(), QString("01234567"));
       
   324     table->undo();
       
   325     QVERIFY(table->plainText().isEmpty());
       
   326 }
       
   327 
       
   328 void tst_QTextPieceTable::undoRedo2()
       
   329 {
       
   330     table->insert(0, "01", charFormatIndex);
       
   331     table->insert(1, "a", charFormatIndex);
       
   332     QCOMPARE(table->plainText(), QString("0a1"));
       
   333     table->undo();
       
   334     QCOMPARE(table->plainText(), QString("01"));
       
   335     table->undo();
       
   336     QCOMPARE(table->plainText(), QString(""));
       
   337     table->redo();
       
   338     QCOMPARE(table->plainText(), QString("01"));
       
   339     table->redo();
       
   340     QCOMPARE(table->plainText(), QString("0a1"));
       
   341 }
       
   342 
       
   343 void tst_QTextPieceTable::undoRedo3()
       
   344 {
       
   345     table->insert(0, "01", charFormatIndex);
       
   346     table->insert(2, "ab", charFormatIndex);
       
   347     table->remove(2, 1);
       
   348     QCOMPARE(table->plainText(), QString("01b"));
       
   349     table->undo();
       
   350     QCOMPARE(table->plainText(), QString("01ab"));
       
   351     table->undo();
       
   352     QVERIFY(table->plainText().isEmpty());
       
   353     table->redo();
       
   354     QCOMPARE(table->plainText(), QString("01ab"));
       
   355     table->redo();
       
   356     QCOMPARE(table->plainText(), QString("01b"));
       
   357 }
       
   358 
       
   359 void tst_QTextPieceTable::undoRedo4()
       
   360 {
       
   361     table->insert(0, "01", charFormatIndex);
       
   362     table->insert(0, "ab", charFormatIndex);
       
   363     table->remove(0, 1);
       
   364     QCOMPARE(table->plainText(), QString("b01"));
       
   365     table->undo();
       
   366     QCOMPARE(table->plainText(), QString("ab01"));
       
   367     table->undo();
       
   368     QCOMPARE(table->plainText(), QString("01"));
       
   369     table->undo();
       
   370     QCOMPARE(table->plainText(), QString(""));
       
   371     table->redo();
       
   372     QCOMPARE(table->plainText(), QString("01"));
       
   373     table->redo();
       
   374     QCOMPARE(table->plainText(), QString("ab01"));
       
   375     table->redo();
       
   376     QCOMPARE(table->plainText(), QString("b01"));
       
   377 }
       
   378 
       
   379 void tst_QTextPieceTable::undoRedo5()
       
   380 {
       
   381     table->beginEditBlock();
       
   382     table->insert(0, "01", charFormatIndex);
       
   383     table->remove(1, 1);
       
   384     table->endEditBlock();
       
   385     QCOMPARE(table->plainText(), QString("0"));
       
   386     table->undo();
       
   387     QCOMPARE(table->plainText(), QString(""));
       
   388 }
       
   389 
       
   390 void tst_QTextPieceTable::undoRedo6()
       
   391 {
       
   392     // this is essentially a test for the undoStack[undoPosition - 1].block = false in PieceTable::endUndoBlock()
       
   393     QTextDocument doc;
       
   394     QTextCursor cursor(&doc);
       
   395     cursor.insertText("Hello World");
       
   396 
       
   397     cursor.insertBlock();
       
   398     cursor.insertText("Hello World2");
       
   399 
       
   400     cursor.movePosition(QTextCursor::Start);
       
   401     QTextBlockFormat bfmt;
       
   402     bfmt.setAlignment(Qt::AlignHCenter);
       
   403     cursor.setBlockFormat(bfmt);
       
   404     QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter);
       
   405 
       
   406     QTextCursor range = cursor;
       
   407     range.clearSelection();
       
   408     range.movePosition(QTextCursor::Start);
       
   409     range.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
       
   410 
       
   411     QTextCharFormat modifier;
       
   412     modifier.setFontItalic(true);
       
   413     range.mergeCharFormat(modifier);
       
   414 
       
   415     cursor.movePosition(QTextCursor::Start);
       
   416     QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter);
       
   417 
       
   418     doc.undo();
       
   419 
       
   420     QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter);
       
   421 }
       
   422 
       
   423 void tst_QTextPieceTable::undoRedo7()
       
   424 {
       
   425     table->insert(0, "a", charFormatIndex);
       
   426     table->insert(1, "b", charFormatIndex);
       
   427     QCOMPARE(table->plainText(), QString("ab"));
       
   428 
       
   429     table->undo();
       
   430     QVERIFY(table->plainText().isEmpty());
       
   431 }
       
   432 
       
   433 void tst_QTextPieceTable::undoRedo8()
       
   434 {
       
   435     table->insert(0, "a", charFormatIndex);
       
   436     table->insert(1, "b", charFormatIndex);
       
   437     QCOMPARE(table->plainText(), QString("ab"));
       
   438 
       
   439     table->remove(0, 1);
       
   440     table->remove(0, 1);
       
   441 
       
   442     QVERIFY(table->plainText().isEmpty());
       
   443     table->undo();
       
   444     QCOMPARE(table->plainText(), QString("ab"));
       
   445 }
       
   446 
       
   447 void tst_QTextPieceTable::undoRedo9()
       
   448 {
       
   449     table->insert(0, "a", charFormatIndex);
       
   450     table->insert(1, "b", charFormatIndex);
       
   451     QCOMPARE(table->plainText(), QString("ab"));
       
   452 
       
   453     table->remove(1, 1);
       
   454     table->remove(0, 1);
       
   455 
       
   456     QVERIFY(table->plainText().isEmpty());
       
   457     table->undo();
       
   458     QCOMPARE(table->plainText(), QString("ab"));
       
   459 }
       
   460 
       
   461 void tst_QTextPieceTable::undoRedo10()
       
   462 {
       
   463     // testcase for the beginUndoBlock/endUndoBlock calls being surrounded by an if (undoEnabled)
       
   464     QTextCharFormat cf;
       
   465     cf.setForeground(Qt::blue);
       
   466     int cfIdx = table->formatCollection()->indexForFormat(cf);
       
   467 
       
   468     QTextBlockFormat f;
       
   469     int idx = table->formatCollection()->indexForFormat(f);
       
   470 
       
   471     table->insert(0, "a", cfIdx);
       
   472     table->insertBlock(1, idx, cfIdx);
       
   473     table->insert(1, "b", cfIdx);
       
   474 
       
   475     cf.setForeground(Qt::red);
       
   476     int newCfIdx = table->formatCollection()->indexForFormat(cf);
       
   477 
       
   478     table->setCharFormat(0, 3, cf, QTextDocumentPrivate::MergeFormat);
       
   479 
       
   480     QCOMPARE(table->find(0).value()->format, newCfIdx);
       
   481 
       
   482     table->undo();
       
   483 
       
   484     QCOMPARE(table->find(0).value()->format, cfIdx);
       
   485 }
       
   486 
       
   487 void tst_QTextPieceTable::undoRedo11()
       
   488 {
       
   489     srand(3);
       
   490     const int loops = 20;
       
   491     QString compare;
       
   492     int l = 0;
       
   493     for (int i = 0; i < loops; ++i) {
       
   494 	bool remove = l && (rand() % 2);
       
   495 	int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0;
       
   496 	QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
       
   497 	QString str;
       
   498 	str += c;
       
   499 	str += c;
       
   500 	if (remove) {
       
   501 	    compare.remove(pos, 1);
       
   502 	    table->remove(pos, 1);
       
   503 	} else {
       
   504 	    compare.insert(pos, str);
       
   505 	    table->insert(pos, str, charFormatIndex);
       
   506 	}
       
   507 	l += remove ? -1 : 2;
       
   508     }
       
   509     QVERIFY(table->plainText() == compare);
       
   510     for (int i = 0; i < loops; ++i)
       
   511 	table->undo();
       
   512     QVERIFY(table->plainText() == QString(""));
       
   513     for (int i = 0; i < loops; ++i)
       
   514 	table->redo();
       
   515     QVERIFY(table->plainText() == compare);
       
   516 }
       
   517 
       
   518 
       
   519 void tst_QTextPieceTable::checkDocumentChanged()
       
   520 {
       
   521     table->enableUndoRedo(false);
       
   522     QTestDocumentLayout *layout = new QTestDocumentLayout(doc);
       
   523     doc->setDocumentLayout(layout);
       
   524 
       
   525     // single insert
       
   526     layout->expect(0, 0, 15);
       
   527     table->insert(0, "012345678901234", charFormatIndex);
       
   528     QVERIFY(!layout->error);
       
   529 
       
   530     // single remove
       
   531     layout->expect(0, 5, 0);
       
   532     table->remove(0, 5);
       
   533     QVERIFY(!layout->error);
       
   534 
       
   535     // symmetric insert/remove
       
   536     layout->expect(0, 0, 0);
       
   537     table->beginEditBlock();
       
   538     table->insert(0, "01234", charFormatIndex);
       
   539     table->remove(0, 5);
       
   540     table->endEditBlock();
       
   541     QVERIFY(!layout->error);
       
   542 
       
   543     layout->expect(0, 5, 5);
       
   544     table->beginEditBlock();
       
   545     table->remove(0, 5);
       
   546     table->insert(0, "01234", charFormatIndex);
       
   547     table->endEditBlock();
       
   548     QVERIFY(!layout->error);
       
   549 
       
   550     // replace
       
   551     layout->expect(0, 3, 5);
       
   552     table->beginEditBlock();
       
   553     table->remove(0, 3);
       
   554     table->insert(0, "01234", charFormatIndex);
       
   555     table->endEditBlock();
       
   556     QVERIFY(!layout->error);
       
   557 
       
   558     layout->expect(0, 0, 2);
       
   559     table->beginEditBlock();
       
   560     table->insert(0, "01234", charFormatIndex);
       
   561     table->remove(0, 3);
       
   562     table->endEditBlock();
       
   563     QVERIFY(!layout->error);
       
   564 
       
   565     // insert + remove inside insert block
       
   566     layout->expect(0, 0, 2);
       
   567     table->beginEditBlock();
       
   568     table->insert(0, "01234", charFormatIndex);
       
   569     table->remove(1, 3);
       
   570     table->endEditBlock();
       
   571     QVERIFY(!layout->error);
       
   572 
       
   573     layout->expect(0, 0, 2);
       
   574     table->beginEditBlock();
       
   575     table->insert(0, "01234", charFormatIndex);
       
   576     table->remove(2, 3);
       
   577     table->endEditBlock();
       
   578     QVERIFY(!layout->error);
       
   579 
       
   580     // insert + remove partly outside
       
   581     layout->expect(0, 1, 0);
       
   582     table->beginEditBlock();
       
   583     table->insert(1, "0", charFormatIndex);
       
   584     table->remove(0, 2);
       
   585     table->endEditBlock();
       
   586     QVERIFY(!layout->error);
       
   587 
       
   588     layout->expect(0, 1, 1);
       
   589     table->beginEditBlock();
       
   590     table->insert(1, "01", charFormatIndex);
       
   591     table->remove(0, 2);
       
   592     table->endEditBlock();
       
   593     QVERIFY(!layout->error);
       
   594 
       
   595     layout->expect(0, 1, 2);
       
   596     table->beginEditBlock();
       
   597     table->insert(1, "012", charFormatIndex);
       
   598     table->remove(0, 2);
       
   599     table->endEditBlock();
       
   600     QVERIFY(!layout->error);
       
   601 
       
   602     layout->expect(1, 1, 0);
       
   603     table->beginEditBlock();
       
   604     table->insert(1, "0", charFormatIndex);
       
   605     table->remove(1, 2);
       
   606     table->endEditBlock();
       
   607     QVERIFY(!layout->error);
       
   608 
       
   609     layout->expect(1, 1, 1);
       
   610     table->beginEditBlock();
       
   611     table->insert(1, "01", charFormatIndex);
       
   612     table->remove(2, 2);
       
   613     table->endEditBlock();
       
   614     QVERIFY(!layout->error);
       
   615 
       
   616     layout->expect(1, 1, 2);
       
   617     table->beginEditBlock();
       
   618     table->insert(1, "012", charFormatIndex);
       
   619     table->remove(3, 2);
       
   620     table->endEditBlock();
       
   621     QVERIFY(!layout->error);
       
   622 
       
   623     // insert + remove non overlapping
       
   624     layout->expect(0, 1, 1);
       
   625     table->beginEditBlock();
       
   626     table->insert(1, "0", charFormatIndex);
       
   627     table->remove(0, 1);
       
   628     table->endEditBlock();
       
   629     QVERIFY(!layout->error);
       
   630 
       
   631     layout->expect(0, 2, 2);
       
   632     table->beginEditBlock();
       
   633     table->insert(2, "1", charFormatIndex);
       
   634     table->remove(0, 1);
       
   635     table->endEditBlock();
       
   636     QVERIFY(!layout->error);
       
   637 
       
   638     layout->expect(0, 2, 2);
       
   639     table->beginEditBlock();
       
   640     table->remove(0, 1);
       
   641     table->insert(1, "0", charFormatIndex);
       
   642     table->endEditBlock();
       
   643     QVERIFY(!layout->error);
       
   644 
       
   645     layout->expect(0, 3, 3);
       
   646     table->beginEditBlock();
       
   647     table->remove(0, 1);
       
   648     table->insert(2, "1", charFormatIndex);
       
   649     table->endEditBlock();
       
   650 
       
   651 
       
   652     layout->expect(0, 3, 3);
       
   653     QTextCharFormat fmt;
       
   654     fmt.setForeground(Qt::blue);
       
   655     table->beginEditBlock();
       
   656     table->setCharFormat(0, 1, fmt);
       
   657     table->setCharFormat(2, 1, fmt);
       
   658     table->endEditBlock();
       
   659     QVERIFY(!layout->error);
       
   660 }
       
   661 
       
   662 void tst_QTextPieceTable::checkDocumentChanged2()
       
   663 {
       
   664     QTestDocumentLayout *layout = new QTestDocumentLayout(doc);
       
   665     doc->setDocumentLayout(layout);
       
   666 
       
   667     QTextCharFormat fmt;
       
   668     fmt.setForeground(Qt::blue);
       
   669     int anotherCharFormatIndex = table->formatCollection()->indexForFormat(fmt);
       
   670 
       
   671     layout->expect(0, 0, 12);
       
   672     table->beginEditBlock();
       
   673     table->insert(0, "0123", charFormatIndex);
       
   674     table->insert(4, "4567", anotherCharFormatIndex);
       
   675     table->insert(8, "8901", charFormatIndex);
       
   676     table->endEditBlock();
       
   677     QVERIFY(!layout->error);
       
   678 
       
   679     fmt.setFontItalic(true);
       
   680 
       
   681     layout->expect(1, 10, 10);
       
   682     table->beginEditBlock();
       
   683     table->setCharFormat(8, 3, fmt);
       
   684     table->setCharFormat(4, 4, fmt);
       
   685     table->setCharFormat(1, 3, fmt);
       
   686     table->endEditBlock();
       
   687     QVERIFY(!layout->error);
       
   688 }
       
   689 
       
   690 void tst_QTextPieceTable::setBlockFormat()
       
   691 {
       
   692     QTextBlockFormat bfmt;
       
   693     int index = table->formatCollection()->indexForFormat(bfmt);
       
   694 
       
   695     table->insertBlock(0, index, charFormatIndex);
       
   696     table->insertBlock(0, index, charFormatIndex);
       
   697     table->insertBlock(0, index, charFormatIndex);
       
   698 
       
   699     QTextBlockFormat newbfmt = bfmt;
       
   700     newbfmt.setAlignment(Qt::AlignRight);
       
   701     index = table->formatCollection()->indexForFormat(bfmt);
       
   702     QTextBlock b = table->blocksFind(1);
       
   703     table->setBlockFormat(b, b, newbfmt);
       
   704 
       
   705     QVERIFY(table->blocksFind(0).blockFormat() == bfmt);
       
   706     QVERIFY(table->blocksFind(1).blockFormat() == newbfmt);
       
   707     QVERIFY(table->blocksFind(2).blockFormat() == bfmt);
       
   708 }
       
   709 
       
   710 
       
   711 void tst_QTextPieceTable::blockInsertion()
       
   712 {
       
   713     QTextBlockFormat fmt;
       
   714     fmt.setTopMargin(100);
       
   715     int idx = table->formatCollection()->indexForFormat(fmt);
       
   716     int charFormat = table->formatCollection()->indexForFormat(QTextCharFormat());
       
   717     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   718 
       
   719     table->insertBlock(0, idx, charFormat);
       
   720     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   721     QVERIFY(table->blocksFind(1).blockFormat() == fmt);
       
   722 
       
   723     table->undo();
       
   724     QVERIFY(table->blockMap().length() == 1);
       
   725     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   726 
       
   727     table->redo();
       
   728     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   729     QVERIFY(table->blocksFind(1).blockFormat() == fmt);
       
   730 }
       
   731 
       
   732 void tst_QTextPieceTable::blockInsertion2()
       
   733 {
       
   734     // caused evil failing assertion in fragmentmap
       
   735     int pos = 0;
       
   736     table->insertBlock(pos, blockFormatIndex, charFormatIndex);
       
   737     pos += 1;
       
   738     table->insert(pos, "a", charFormatIndex);
       
   739     pos += 1;
       
   740 
       
   741     pos -= 1;
       
   742     table->insertBlock(pos, blockFormatIndex, charFormatIndex);
       
   743     QCOMPARE(table->blocksFind(0).position(), 0);
       
   744     QCOMPARE(table->blocksFind(1).position(), 1);
       
   745     QCOMPARE(table->blocksFind(2).position(), 2);
       
   746 }
       
   747 
       
   748 /*
       
   749   Tests correct removal behaviour when deleting over block boundaries or complete blocks.
       
   750 */
       
   751 
       
   752 void tst_QTextPieceTable::blockRemoval1()
       
   753 {
       
   754     QTextBlockFormat fmt1;
       
   755     fmt1.setTopMargin(100);
       
   756     QTextBlockFormat fmt2;
       
   757     fmt2.setAlignment(Qt::AlignRight);
       
   758     int idx1 = table->formatCollection()->indexForFormat(fmt1);
       
   759     int idx2 = table->formatCollection()->indexForFormat(fmt2);
       
   760 
       
   761     table->insert(0, "0123", charFormatIndex);
       
   762     table->insertBlock(4, idx1, charFormatIndex);
       
   763     table->insert(5, "5678", charFormatIndex);
       
   764     table->insertBlock(9, idx2, charFormatIndex);
       
   765     table->insert(10, "0123", charFormatIndex);
       
   766 
       
   767     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   768     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   769     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   770     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   771     QVERIFY(table->blocksFind(1).position() == 0);
       
   772     QVERIFY(table->blocksFind(6).position() == 5);
       
   773     QVERIFY(table->blocksFind(11).position() == 10);
       
   774 
       
   775     table->beginEditBlock();
       
   776     table->remove(5, 5);
       
   777     table->endEditBlock();
       
   778     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   779     QVERIFY(table->blocksFind(5).blockFormat() == fmt2);
       
   780     QVERIFY(table->blocksFind(4).position() == 0);
       
   781     QVERIFY(table->blocksFind(5).position() == 5);
       
   782 
       
   783     table->undo();
       
   784 
       
   785     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   786     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   787     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   788     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   789     QVERIFY(table->blocksFind(1).position() == 0);
       
   790     QVERIFY(table->blocksFind(6).position() == 5);
       
   791     QVERIFY(table->blocksFind(11).position() == 10);
       
   792 
       
   793     table->redo();
       
   794     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   795     QVERIFY(table->blocksFind(5).blockFormat() == fmt2);
       
   796     QVERIFY(table->blocksFind(4).position() == 0);
       
   797     QVERIFY(table->blocksFind(5).position() == 5);
       
   798 }
       
   799 
       
   800 void tst_QTextPieceTable::blockRemoval2()
       
   801 {
       
   802     QTextBlockFormat fmt1;
       
   803     fmt1.setTopMargin(100);
       
   804     QTextBlockFormat fmt2;
       
   805     fmt2.setAlignment(Qt::AlignRight);
       
   806     int idx1 = table->formatCollection()->indexForFormat(fmt1);
       
   807     int idx2 = table->formatCollection()->indexForFormat(fmt2);
       
   808 
       
   809     table->insert(0, "0123", charFormatIndex);
       
   810     table->insertBlock(4, idx1, charFormatIndex);
       
   811     table->insert(5, "5678", charFormatIndex);
       
   812     table->insertBlock(9, idx2, charFormatIndex);
       
   813     table->insert(10, "0123", charFormatIndex);
       
   814 
       
   815     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   816     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   817     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   818     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   819     QVERIFY(table->blocksFind(1).position() == 0);
       
   820     QVERIFY(table->blocksFind(6).position() == 5);
       
   821     QVERIFY(table->blocksFind(11).position() == 10);
       
   822 
       
   823     table->remove(4, 1);
       
   824     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   825     QVERIFY(table->blocksFind(6).blockFormat() == QTextBlockFormat());
       
   826     QVERIFY(table->blocksFind(4).position() == 0);
       
   827     QVERIFY(table->blocksFind(6).position() == 0);
       
   828 
       
   829     table->undo();
       
   830 
       
   831     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   832     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   833     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   834     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   835     QVERIFY(table->blocksFind(1).position() == 0);
       
   836     QVERIFY(table->blocksFind(6).position() == 5);
       
   837     QVERIFY(table->blocksFind(11).position() == 10);
       
   838 
       
   839     table->redo();
       
   840     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   841     QVERIFY(table->blocksFind(6).blockFormat() == QTextBlockFormat());
       
   842     QVERIFY(table->blocksFind(4).position() == 0);
       
   843     QVERIFY(table->blocksFind(6).position() == 0);
       
   844 }
       
   845 
       
   846 void tst_QTextPieceTable::blockRemoval3()
       
   847 {
       
   848     QTextBlockFormat fmt1;
       
   849     fmt1.setTopMargin(100);
       
   850     QTextBlockFormat fmt2;
       
   851     fmt2.setAlignment(Qt::AlignRight);
       
   852     int idx1 = table->formatCollection()->indexForFormat(fmt1);
       
   853     int idx2 = table->formatCollection()->indexForFormat(fmt2);
       
   854 
       
   855     table->insert(0, "0123", charFormatIndex);
       
   856     table->insertBlock(4, idx1, charFormatIndex);
       
   857     table->insert(5, "5678", charFormatIndex);
       
   858     table->insertBlock(9, idx2, charFormatIndex);
       
   859     table->insert(10, "0123", charFormatIndex);
       
   860 
       
   861     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   862     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   863     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   864     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   865     QVERIFY(table->blocksFind(1).position() == 0);
       
   866     QVERIFY(table->blocksFind(6).position() == 5);
       
   867     QVERIFY(table->blocksFind(11).position() == 10);
       
   868 
       
   869     table->beginEditBlock();
       
   870     table->remove(3, 4);
       
   871     table->endEditBlock();
       
   872 
       
   873     QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat());
       
   874     QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat());
       
   875     QVERIFY(table->blocksFind(1).position() == 0);
       
   876     QVERIFY(table->blocksFind(5).position() == 0);
       
   877 
       
   878     table->undo();
       
   879 
       
   880     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   881     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   882     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   883     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   884     QVERIFY(table->blocksFind(1).position() == 0);
       
   885     QVERIFY(table->blocksFind(6).position() == 5);
       
   886     QVERIFY(table->blocksFind(11).position() == 10);
       
   887 
       
   888     table->redo();
       
   889     QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat());
       
   890     QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat());
       
   891     QVERIFY(table->blocksFind(1).position() == 0);
       
   892     QVERIFY(table->blocksFind(5).position() == 0);
       
   893 }
       
   894 
       
   895 void tst_QTextPieceTable::blockRemoval4()
       
   896 {
       
   897 #if 0
       
   898     QTextBlockFormat fmt1;
       
   899     fmt1.setTopMargin(100);
       
   900     QTextBlockFormat fmt2;
       
   901     fmt2.setAlignment(Qt::AlignRight);
       
   902     int idx1 = table->formatCollection()->indexForFormat(fmt1);
       
   903     int idx2 = table->formatCollection()->indexForFormat(fmt2);
       
   904 
       
   905     table->insert(0, "0123", charFormatIndex);
       
   906     table->insertBlock(4, idx1, charFormatIndex);
       
   907     table->insert(5, "5678", charFormatIndex);
       
   908     table->insertBlock(9, idx2, charFormatIndex);
       
   909     table->insert(10, "0123", charFormatIndex);
       
   910 
       
   911     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   912     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   913     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   914     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   915     QVERIFY(table->blocksFind(1).position() == 0);
       
   916     QVERIFY(table->blocksFind(6).position() == 5);
       
   917     QVERIFY(table->blocksFind(11).position() == 10);
       
   918 
       
   919     table->remove(3, 7);
       
   920     QVERIFY(table->blocksFind(1).position() == 0);
       
   921     QVERIFY(table->blocksFind(5).position() == 0);
       
   922     QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat());
       
   923     QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat());
       
   924 
       
   925     table->undo();
       
   926 
       
   927     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   928     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   929     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   930     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   931     QVERIFY(table->blocksFind(1).position() == 0);
       
   932     QVERIFY(table->blocksFind(6).position() == 5);
       
   933     QVERIFY(table->blocksFind(11).position() == 10);
       
   934 
       
   935     table->redo();
       
   936     QVERIFY(table->blocksFind(1).position() == 0);
       
   937     QVERIFY(table->blocksFind(5).position() == 0);
       
   938     QVERIFY(table->blocksFind(1).blockFormat() == QTextBlockFormat());
       
   939     QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat());
       
   940 #endif
       
   941 }
       
   942 
       
   943 void tst_QTextPieceTable::blockRemoval5()
       
   944 {
       
   945     QTextBlockFormat fmt1;
       
   946     fmt1.setTopMargin(100);
       
   947     QTextBlockFormat fmt2;
       
   948     fmt2.setAlignment(Qt::AlignRight);
       
   949     int idx1 = table->formatCollection()->indexForFormat(fmt1);
       
   950     int idx2 = table->formatCollection()->indexForFormat(fmt2);
       
   951 
       
   952     table->insert(0, "0123", charFormatIndex);
       
   953     table->insertBlock(4, idx1, charFormatIndex);
       
   954     table->insert(5, "5678", charFormatIndex);
       
   955     table->insertBlock(9, idx2, charFormatIndex);
       
   956     table->insert(10, "0123", charFormatIndex);
       
   957 
       
   958     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   959     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   960     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   961     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   962     QVERIFY(table->blocksFind(1).position() == 0);
       
   963     QVERIFY(table->blocksFind(6).position() == 5);
       
   964     QVERIFY(table->blocksFind(11).position() == 10);
       
   965 
       
   966     table->beginEditBlock();
       
   967     table->remove(3, 8);
       
   968     table->endEditBlock();
       
   969 
       
   970     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   971     QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat());
       
   972     QVERIFY(table->blocksFind(1).position() == 0);
       
   973     QVERIFY(table->blocksFind(5).position() == 0);
       
   974 
       
   975     table->undo();
       
   976 
       
   977     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   978     QVERIFY(table->blocksFind(4).blockFormat() == QTextBlockFormat());
       
   979     QVERIFY(table->blocksFind(5).blockFormat() == fmt1);
       
   980     QVERIFY(table->blocksFind(10).blockFormat() == fmt2);
       
   981     QVERIFY(table->blocksFind(1).position() == 0);
       
   982     QVERIFY(table->blocksFind(6).position() == 5);
       
   983     QVERIFY(table->blocksFind(11).position() == 10);
       
   984 
       
   985     table->redo();
       
   986     QVERIFY(table->blocksFind(0).blockFormat() == QTextBlockFormat());
       
   987     QVERIFY(table->blocksFind(5).blockFormat() == QTextBlockFormat());
       
   988     QVERIFY(table->blocksFind(1).position() == 0);
       
   989     QVERIFY(table->blocksFind(5).position() == 0);
       
   990 }
       
   991 
       
   992 
       
   993 void tst_QTextPieceTable::checkBlockSeparation()
       
   994 {
       
   995     table->insertBlock(0, blockFormatIndex, charFormatIndex);
       
   996     table->insertBlock(1, blockFormatIndex, charFormatIndex);
       
   997 
       
   998     QVERIFY(table->find(0) != table->find(1));
       
   999 }
       
  1000 
       
  1001 void tst_QTextPieceTable::checkFrames1()
       
  1002 {
       
  1003     QTextFrameFormat ffmt;
       
  1004     table->insert(0, "Hello", charFormatIndex);
       
  1005     QPointer<QTextFrame> frame = table->insertFrame(1, 3, ffmt);
       
  1006     QTextFrame *root = table->rootFrame();
       
  1007 
       
  1008     QVERIFY(root == frame->parentFrame());
       
  1009 
       
  1010     QVERIFY(root);
       
  1011     QVERIFY(root->parentFrame() == 0);
       
  1012 
       
  1013     QVERIFY(root->childFrames().count() == 1);
       
  1014     QVERIFY(frame->format() == ffmt);
       
  1015     QVERIFY(frame->firstPosition() == 2);
       
  1016     QVERIFY(frame->lastPosition() == 4);
       
  1017 
       
  1018 
       
  1019     QPointer<QTextFrame> frame2 = table->insertFrame(2, 3, ffmt);
       
  1020 
       
  1021     QVERIFY(root->childFrames().count() == 1);
       
  1022     QVERIFY(root->childFrames().at(0) == frame);
       
  1023     QVERIFY(frame->childFrames().count() == 1);
       
  1024     QVERIFY(frame2->childFrames().count() == 0);
       
  1025     QVERIFY(frame2->parentFrame() == frame);
       
  1026     QVERIFY(frame2->firstPosition() == 3);
       
  1027     QVERIFY(frame2->lastPosition() == 4);
       
  1028 
       
  1029     QVERIFY(frame->format() == ffmt);
       
  1030     QVERIFY(frame->firstPosition() == 2);
       
  1031     QVERIFY(frame->lastPosition() == 6);
       
  1032 
       
  1033     table->removeFrame(frame);
       
  1034 
       
  1035     QVERIFY(root->childFrames().count() == 1);
       
  1036     QVERIFY(root->childFrames().at(0) == frame2);
       
  1037     QVERIFY(!frame);
       
  1038     QVERIFY(frame2->childFrames().count() == 0);
       
  1039     QVERIFY(frame2->parentFrame() == root);
       
  1040     QVERIFY(frame2->firstPosition() == 2);
       
  1041     QVERIFY(frame2->lastPosition() == 3);
       
  1042 
       
  1043     table->undo();
       
  1044 
       
  1045     frame = table->frameAt(2);
       
  1046 
       
  1047     QVERIFY(root->childFrames().count() == 1);
       
  1048     QVERIFY(root->childFrames().at(0) == frame);
       
  1049     QVERIFY(frame->childFrames().count() == 1);
       
  1050     QVERIFY(frame->childFrames().at(0) == frame2);
       
  1051     QVERIFY(frame2->childFrames().count() == 0);
       
  1052     QVERIFY(frame2->parentFrame() == frame);
       
  1053     QVERIFY(frame2->firstPosition() == 3);
       
  1054     QVERIFY(frame2->lastPosition() == 4);
       
  1055 
       
  1056     QVERIFY(frame->firstPosition() == 2);
       
  1057     QVERIFY(frame->lastPosition() == 6);
       
  1058 
       
  1059     table->undo();
       
  1060 
       
  1061     QVERIFY(root->childFrames().count() == 1);
       
  1062     QVERIFY(root->childFrames().at(0) == frame);
       
  1063     QVERIFY(frame->childFrames().count() == 0);
       
  1064     QVERIFY(!frame2);
       
  1065 
       
  1066     QVERIFY(frame->firstPosition() == 2);
       
  1067     QVERIFY(frame->lastPosition() == 4);
       
  1068 }
       
  1069 
       
  1070 void tst_QTextPieceTable::removeFrameDirect()
       
  1071 {
       
  1072     QTextFrameFormat ffmt;
       
  1073     table->insert(0, "Hello", charFormatIndex);
       
  1074 
       
  1075     QTextFrame *frame = table->insertFrame(1, 5, ffmt);
       
  1076 
       
  1077     QVERIFY(frame->parentFrame() == table->rootFrame());
       
  1078 
       
  1079     const int start = frame->firstPosition() - 1;
       
  1080     const int end = frame->lastPosition();
       
  1081     const int length = end - start + 1;
       
  1082 
       
  1083     table->remove(start, length);
       
  1084 }
       
  1085 
       
  1086 void tst_QTextPieceTable::removeWithChildFrame()
       
  1087 {
       
  1088     /*
       
  1089        The piecetable layout is:
       
  1090 
       
  1091        ...
       
  1092        1 BeginningOfFrame(first frame)
       
  1093        2 text
       
  1094        3 BeginningOfFrame(second frame)
       
  1095        4 text
       
  1096        5 text
       
  1097        6 EndOfFrame(second frame)
       
  1098        7 text
       
  1099        8 text
       
  1100        9 EndOfFrame(first frame)
       
  1101        ...
       
  1102 
       
  1103        The idea is to remove from [2] until [6], basically some trailing text and the second frame.
       
  1104        In this case frameAt(2) != frameAt(6), so the assertion in remove() needed an adjustement.
       
  1105      */
       
  1106     QTextFrameFormat ffmt;
       
  1107     table->insert(0, "Hello World", charFormatIndex);
       
  1108 
       
  1109     QTextFrame *frame = table->insertFrame(1, 6, ffmt);
       
  1110     QTextFrame *childFrame = table->insertFrame(3, 5, ffmt);
       
  1111 
       
  1112     // used to give a failing assertion
       
  1113     table->remove(2, 5);
       
  1114     QVERIFY(true);
       
  1115 }
       
  1116 
       
  1117 void tst_QTextPieceTable::clearWithFrames()
       
  1118 {
       
  1119     /*
       
  1120        The piecetable layout is:
       
  1121 
       
  1122        ...
       
  1123        1 BeginningOfFrame(first frame)
       
  1124        2 text
       
  1125        3 EndOfFrame(first frame)
       
  1126        4 BeginningOfFrame(second frame)
       
  1127        5 text
       
  1128        6 text
       
  1129        7 EndOfFrame(second frame)
       
  1130        ...
       
  1131 
       
  1132        The idea is to remove from [1] until [7].
       
  1133      */
       
  1134     QTextFrameFormat ffmt;
       
  1135     table->insert(0, "Hello World", charFormatIndex);
       
  1136 
       
  1137     QTextFrame *firstFrame = table->insertFrame(1, 2, ffmt);
       
  1138     QTextFrame *secondFrame = table->insertFrame(4, 6, ffmt);
       
  1139 
       
  1140     const int start = firstFrame->firstPosition() - 1;
       
  1141     const int end = secondFrame->lastPosition();
       
  1142     const int length = end - start + 1;
       
  1143     // used to give a failing assertion
       
  1144     table->remove(start, length);
       
  1145     QVERIFY(true);
       
  1146 }
       
  1147 
       
  1148 QTEST_MAIN(tst_QTextPieceTable)
       
  1149 
       
  1150 
       
  1151 #include "tst_qtextpiecetable.moc"
       
  1152