tests/auto/qplaintextedit/tst_qplaintextedit.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 
       
    46 #include <qtextedit.h>
       
    47 #include <qtextcursor.h>
       
    48 #include <qtextlist.h>
       
    49 #include <qdebug.h>
       
    50 #include <qapplication.h>
       
    51 #include <qclipboard.h>
       
    52 #include <qtextbrowser.h>
       
    53 #include <private/qtextcontrol_p.h>
       
    54 #include <qscrollbar.h>
       
    55 #include <qtextobject.h>
       
    56 
       
    57 #include <qabstracttextdocumentlayout.h>
       
    58 #include <qtextdocumentfragment.h>
       
    59 
       
    60 #include "qplaintextedit.h"
       
    61 
       
    62 //Used in copyAvailable
       
    63 typedef QPair<Qt::Key, Qt::KeyboardModifier> keyPairType;
       
    64 typedef QList<keyPairType> pairListType;
       
    65 Q_DECLARE_METATYPE(pairListType);
       
    66 Q_DECLARE_METATYPE(keyPairType);
       
    67 Q_DECLARE_METATYPE(QList<bool>);
       
    68 
       
    69 #ifdef Q_WS_MAC
       
    70 #include <Carbon/Carbon.h>
       
    71 #endif
       
    72 
       
    73 QT_FORWARD_DECLARE_CLASS(QPlainTextEdit)
       
    74 
       
    75 //TESTED_CLASS=
       
    76 //TESTED_FILES=gui/widgets/qtextedit.h gui/widgets/qtextedit.cpp
       
    77 
       
    78 class tst_QPlainTextEdit : public QObject
       
    79 {
       
    80     Q_OBJECT
       
    81 public:
       
    82     tst_QPlainTextEdit();
       
    83 
       
    84 public slots:
       
    85     void initTestCase();
       
    86     void init();
       
    87     void cleanup();
       
    88 private slots:
       
    89     void getSetCheck();
       
    90 #ifndef QT_NO_CLIPBOARD
       
    91     void clearMustNotChangeClipboard();
       
    92 #endif
       
    93     void clearMustNotResetRootFrameMarginToDefault();
       
    94     void paragSeparatorOnPlaintextAppend();
       
    95 #ifndef QT_NO_CLIPBOARD
       
    96     void selectAllSetsNotSelection();
       
    97 #endif
       
    98     void asciiTab();
       
    99     void setDocument();
       
   100     void emptyAppend();
       
   101     void appendOnEmptyDocumentShouldReuseInitialParagraph();
       
   102     void cursorPositionChanged();
       
   103     void setTextCursor();
       
   104 #ifndef QT_NO_CLIPBOARD
       
   105     void undoAvailableAfterPaste();
       
   106 #endif
       
   107     void undoRedoAvailableRepetition();
       
   108     void appendShouldNotTouchTheSelection();
       
   109     void backspace();
       
   110     void shiftBackspace();
       
   111     void undoRedo();
       
   112     void preserveCharFormatInAppend();
       
   113 #ifndef QT_NO_CLIPBOARD
       
   114     void copyAndSelectAllInReadonly();
       
   115 #endif
       
   116     void ctrlAltInput();
       
   117     void noPropertiesOnDefaultTextEditCharFormat();
       
   118     void setPlainTextShouldEmitTextChangedOnce();
       
   119     void overwriteMode();
       
   120     void shiftDownInLineLastShouldSelectToEnd_data();
       
   121     void shiftDownInLineLastShouldSelectToEnd();
       
   122     void undoRedoShouldRepositionTextEditCursor();
       
   123     void lineWrapModes();
       
   124     void mouseCursorShape();
       
   125     void implicitClear();
       
   126     void undoRedoAfterSetContent();
       
   127     void numPadKeyNavigation();
       
   128     void moveCursor();
       
   129 #ifndef QT_NO_CLIPBOARD
       
   130     void mimeDataReimplementations();
       
   131 #endif
       
   132     void shiftEnterShouldInsertLineSeparator();
       
   133     void selectWordsFromStringsContainingSeparators_data();
       
   134     void selectWordsFromStringsContainingSeparators();
       
   135 #ifndef QT_NO_CLIPBOARD
       
   136     void canPaste();
       
   137     void copyAvailable_data();
       
   138     void copyAvailable();
       
   139 #endif
       
   140     void ensureCursorVisibleOnInitialShow();
       
   141     void setTextInsideResizeEvent();
       
   142     void colorfulAppend();
       
   143     void ensureVisibleWithRtl();
       
   144     void preserveCharFormatAfterSetPlainText();
       
   145     void extraSelections();
       
   146     void adjustScrollbars();
       
   147     void textObscuredByScrollbars();
       
   148     void setTextPreservesUndoRedoEnabled();
       
   149     void wordWrapProperty();
       
   150     void lineWrapProperty();
       
   151     void selectionChanged();
       
   152     void blockCountChanged();
       
   153 
       
   154 private:
       
   155     void createSelection();
       
   156     int blockCount() const;
       
   157     int lineCount() const;
       
   158     bool nativeClipboardWorking();
       
   159 
       
   160     QPlainTextEdit *ed;
       
   161     qreal rootFrameMargin;
       
   162 };
       
   163 
       
   164 bool tst_QPlainTextEdit::nativeClipboardWorking()
       
   165 {
       
   166 #ifdef Q_WS_MAC
       
   167     PasteboardRef pasteboard;
       
   168     OSStatus status = PasteboardCreate(0, &pasteboard);
       
   169     if (status == noErr)
       
   170         CFRelease(pasteboard);
       
   171     return status == noErr;
       
   172 #endif
       
   173     return true;
       
   174 }
       
   175 
       
   176 // Testing get/set functions
       
   177 void tst_QPlainTextEdit::getSetCheck()
       
   178 {
       
   179     QPlainTextEdit obj1;
       
   180     // QTextDocument * QPlainTextEdit::document()
       
   181     // void QPlainTextEdit::setDocument(QTextDocument *)
       
   182     QTextDocument *var1 = new QTextDocument;
       
   183     var1->setDocumentLayout(new QPlainTextDocumentLayout(var1));
       
   184     obj1.setDocument(var1);
       
   185     QCOMPARE(var1, obj1.document());
       
   186     obj1.setDocument((QTextDocument *)0);
       
   187     QVERIFY(var1 != obj1.document()); // QPlainTextEdit creates a new document when setting 0
       
   188     QVERIFY((QTextDocument *)0 != obj1.document());
       
   189     delete var1;
       
   190 
       
   191 
       
   192     // bool QPlainTextEdit::tabChangesFocus()
       
   193     // void QPlainTextEdit::setTabChangesFocus(bool)
       
   194     obj1.setTabChangesFocus(false);
       
   195     QCOMPARE(false, obj1.tabChangesFocus());
       
   196     obj1.setTabChangesFocus(true);
       
   197     QCOMPARE(true, obj1.tabChangesFocus());
       
   198 
       
   199     // LineWrapMode QPlainTextEdit::lineWrapMode()
       
   200     // void QPlainTextEdit::setLineWrapMode(LineWrapMode)
       
   201     obj1.setLineWrapMode(QPlainTextEdit::LineWrapMode(QPlainTextEdit::NoWrap));
       
   202     QCOMPARE(QPlainTextEdit::LineWrapMode(QPlainTextEdit::NoWrap), obj1.lineWrapMode());
       
   203     obj1.setLineWrapMode(QPlainTextEdit::LineWrapMode(QPlainTextEdit::WidgetWidth));
       
   204     QCOMPARE(QPlainTextEdit::LineWrapMode(QPlainTextEdit::WidgetWidth), obj1.lineWrapMode());
       
   205 //     obj1.setLineWrapMode(QPlainTextEdit::LineWrapMode(QPlainTextEdit::FixedPixelWidth));
       
   206 //     QCOMPARE(QPlainTextEdit::LineWrapMode(QPlainTextEdit::FixedPixelWidth), obj1.lineWrapMode());
       
   207 //     obj1.setLineWrapMode(QPlainTextEdit::LineWrapMode(QPlainTextEdit::FixedColumnWidth));
       
   208 //     QCOMPARE(QPlainTextEdit::LineWrapMode(QPlainTextEdit::FixedColumnWidth), obj1.lineWrapMode());
       
   209 
       
   210 
       
   211     // bool QPlainTextEdit::overwriteMode()
       
   212     // void QPlainTextEdit::setOverwriteMode(bool)
       
   213     obj1.setOverwriteMode(false);
       
   214     QCOMPARE(false, obj1.overwriteMode());
       
   215     obj1.setOverwriteMode(true);
       
   216     QCOMPARE(true, obj1.overwriteMode());
       
   217 
       
   218     // int QPlainTextEdit::tabStopWidth()
       
   219     // void QPlainTextEdit::setTabStopWidth(int)
       
   220     obj1.setTabStopWidth(0);
       
   221     QCOMPARE(0, obj1.tabStopWidth());
       
   222     obj1.setTabStopWidth(INT_MIN);
       
   223     QCOMPARE(0, obj1.tabStopWidth()); // Makes no sense to set a negative tabstop value
       
   224 #if defined(QT_ARCH_WINDOWSCE) || defined (QT_ARCH_SYMBIAN)
       
   225     // due to rounding error in qRound when qreal==float
       
   226     // we cannot use INT_MAX for this check
       
   227     obj1.setTabStopWidth(SHRT_MAX*2);
       
   228     QCOMPARE(SHRT_MAX*2, obj1.tabStopWidth());
       
   229 #else
       
   230     obj1.setTabStopWidth(INT_MAX);
       
   231     QCOMPARE(INT_MAX, obj1.tabStopWidth());
       
   232 #endif
       
   233 
       
   234 }
       
   235 
       
   236 class QtTestDocumentLayout : public QAbstractTextDocumentLayout
       
   237 {
       
   238     Q_OBJECT
       
   239 public:
       
   240     inline QtTestDocumentLayout(QPlainTextEdit *edit, QTextDocument *doc, int &itCount)
       
   241         : QAbstractTextDocumentLayout(doc), useBiggerSize(false), ed(edit), iterationCounter(itCount) {}
       
   242 
       
   243     virtual void draw(QPainter *, const QAbstractTextDocumentLayout::PaintContext &)  {}
       
   244 
       
   245     virtual int hitTest(const QPointF &, Qt::HitTestAccuracy ) const { return 0; }
       
   246 
       
   247     virtual void documentChanged(int, int, int) {}
       
   248 
       
   249     virtual int pageCount() const { return 1; }
       
   250 
       
   251     virtual QSizeF documentSize() const { return usedSize; }
       
   252 
       
   253     virtual QRectF frameBoundingRect(QTextFrame *) const { return QRectF(); }
       
   254     virtual QRectF blockBoundingRect(const QTextBlock &) const { return QRectF(); }
       
   255 
       
   256     bool useBiggerSize;
       
   257     QSize usedSize;
       
   258 
       
   259     QPlainTextEdit *ed;
       
   260 
       
   261     int &iterationCounter;
       
   262 };
       
   263 
       
   264 tst_QPlainTextEdit::tst_QPlainTextEdit()
       
   265 {}
       
   266 
       
   267 void tst_QPlainTextEdit::initTestCase()
       
   268 {
       
   269 #ifdef Q_OS_WINCE //disable magic for WindowsCE
       
   270     qApp->setAutoMaximizeThreshold(-1);
       
   271 #endif
       
   272 }
       
   273 
       
   274 void tst_QPlainTextEdit::init()
       
   275 {
       
   276     ed = new QPlainTextEdit(0);
       
   277     rootFrameMargin = ed->document()->documentMargin();
       
   278 }
       
   279 
       
   280 void tst_QPlainTextEdit::cleanup()
       
   281 {
       
   282     delete ed;
       
   283     ed = 0;
       
   284 }
       
   285 
       
   286 
       
   287 void tst_QPlainTextEdit::createSelection()
       
   288 {
       
   289     QTest::keyClicks(ed, "Hello World");
       
   290     /* go to start */
       
   291 #ifndef Q_WS_MAC
       
   292     QTest::keyClick(ed, Qt::Key_Home, Qt::ControlModifier);
       
   293 #else
       
   294     QTest::keyClick(ed, Qt::Key_Home);
       
   295 #endif
       
   296     QCOMPARE(ed->textCursor().position(), 0);
       
   297     /* select until end of text */
       
   298 #ifndef Q_WS_MAC
       
   299     QTest::keyClick(ed, Qt::Key_End, Qt::ControlModifier | Qt::ShiftModifier);
       
   300 #else
       
   301     QTest::keyClick(ed, Qt::Key_End, Qt::ShiftModifier);
       
   302 #endif
       
   303     QCOMPARE(ed->textCursor().position(), 11);
       
   304 }
       
   305 #ifndef QT_NO_CLIPBOARD
       
   306 void tst_QPlainTextEdit::clearMustNotChangeClipboard()
       
   307 {
       
   308     if (!nativeClipboardWorking())
       
   309         QSKIP("Clipboard not working with cron-started unit tests", SkipAll);
       
   310     ed->textCursor().insertText("Hello World");
       
   311     QString txt("This is different text");
       
   312     QApplication::clipboard()->setText(txt);
       
   313     ed->clear();
       
   314     QCOMPARE(QApplication::clipboard()->text(), txt);
       
   315 }
       
   316 #endif
       
   317 
       
   318 void tst_QPlainTextEdit::clearMustNotResetRootFrameMarginToDefault()
       
   319 {
       
   320     QCOMPARE(ed->document()->rootFrame()->frameFormat().margin(), rootFrameMargin);
       
   321     ed->clear();
       
   322     QCOMPARE(ed->document()->rootFrame()->frameFormat().margin(), rootFrameMargin);
       
   323 }
       
   324 
       
   325 
       
   326 void tst_QPlainTextEdit::paragSeparatorOnPlaintextAppend()
       
   327 {
       
   328     ed->appendPlainText("Hello\nWorld");
       
   329     int cnt = 0;
       
   330     QTextBlock blk = ed->document()->begin();
       
   331     while (blk.isValid()) {
       
   332         ++cnt;
       
   333         blk = blk.next();
       
   334     }
       
   335     QCOMPARE(cnt, 2);
       
   336 }
       
   337 
       
   338 #ifndef QT_NO_CLIPBOARD
       
   339 void tst_QPlainTextEdit::selectAllSetsNotSelection()
       
   340 {
       
   341     if (!QApplication::clipboard()->supportsSelection()) {
       
   342         QSKIP("Test only relevant for systems with selection", SkipAll);
       
   343         return;
       
   344     }
       
   345 
       
   346     QApplication::clipboard()->setText(QString("foobar"), QClipboard::Selection);
       
   347     QVERIFY(QApplication::clipboard()->text(QClipboard::Selection) == QString("foobar"));
       
   348 
       
   349     ed->insertPlainText("Hello World");
       
   350     ed->selectAll();
       
   351 
       
   352     QCOMPARE(QApplication::clipboard()->text(QClipboard::Selection), QString::fromAscii("foobar"));
       
   353 }
       
   354 #endif
       
   355 
       
   356 void tst_QPlainTextEdit::asciiTab()
       
   357 {
       
   358     QPlainTextEdit edit;
       
   359     edit.setPlainText("\t");
       
   360     edit.show();
       
   361     qApp->processEvents();
       
   362     QCOMPARE(edit.toPlainText().at(0), QChar('\t'));
       
   363 }
       
   364 
       
   365 void tst_QPlainTextEdit::setDocument()
       
   366 {
       
   367     QTextDocument *document = new QTextDocument(ed);
       
   368     document->setDocumentLayout(new QPlainTextDocumentLayout(document));
       
   369     QTextCursor(document).insertText("Test");
       
   370     ed->setDocument(document);
       
   371     QCOMPARE(ed->toPlainText(), QString("Test"));
       
   372 }
       
   373 
       
   374 
       
   375 int tst_QPlainTextEdit::blockCount() const
       
   376 {
       
   377     int blocks = 0;
       
   378     for (QTextBlock block = ed->document()->begin(); block.isValid(); block = block.next())
       
   379         ++blocks;
       
   380     return blocks;
       
   381 }
       
   382 
       
   383 int tst_QPlainTextEdit::lineCount() const
       
   384 {
       
   385     int lines = 0;
       
   386     for (QTextBlock block = ed->document()->begin(); block.isValid(); block = block.next()) {
       
   387         ed->document()->documentLayout()->blockBoundingRect(block);
       
   388         lines += block.layout()->lineCount();
       
   389     }
       
   390     return lines;
       
   391 }
       
   392 
       
   393 // Supporter issue #56783
       
   394 void tst_QPlainTextEdit::emptyAppend()
       
   395 {
       
   396     ed->appendPlainText("Blah");
       
   397     QCOMPARE(blockCount(), 1);
       
   398     ed->appendPlainText(QString::null);
       
   399     QCOMPARE(blockCount(), 2);
       
   400     ed->appendPlainText(QString("   "));
       
   401     QCOMPARE(blockCount(), 3);
       
   402 }
       
   403 
       
   404 void tst_QPlainTextEdit::appendOnEmptyDocumentShouldReuseInitialParagraph()
       
   405 {
       
   406     QCOMPARE(blockCount(), 1);
       
   407     ed->appendPlainText("Blah");
       
   408     QCOMPARE(blockCount(), 1);
       
   409 }
       
   410 
       
   411 
       
   412 class CursorPositionChangedRecorder : public QObject
       
   413 {
       
   414     Q_OBJECT
       
   415 public:
       
   416     inline CursorPositionChangedRecorder(QPlainTextEdit *ed)
       
   417         : editor(ed)
       
   418     {
       
   419         connect(editor, SIGNAL(cursorPositionChanged()), this, SLOT(recordCursorPos()));
       
   420     }
       
   421 
       
   422     QList<int> cursorPositions;
       
   423 
       
   424 private slots:
       
   425     void recordCursorPos()
       
   426     {
       
   427         cursorPositions.append(editor->textCursor().position());
       
   428     }
       
   429 
       
   430 private:
       
   431     QPlainTextEdit *editor;
       
   432 };
       
   433 
       
   434 void tst_QPlainTextEdit::cursorPositionChanged()
       
   435 {
       
   436     QSignalSpy spy(ed, SIGNAL(cursorPositionChanged()));
       
   437 
       
   438     spy.clear();
       
   439     QTest::keyClick(ed, Qt::Key_A);
       
   440     QCOMPARE(spy.count(), 1);
       
   441 
       
   442     QTextCursor cursor = ed->textCursor();
       
   443     cursor.movePosition(QTextCursor::Start);
       
   444     ed->setTextCursor(cursor);
       
   445     cursor.movePosition(QTextCursor::End);
       
   446     spy.clear();
       
   447     cursor.insertText("Test");
       
   448     QCOMPARE(spy.count(), 0);
       
   449 
       
   450     cursor.movePosition(QTextCursor::End);
       
   451     ed->setTextCursor(cursor);
       
   452     cursor.movePosition(QTextCursor::Start);
       
   453     spy.clear();
       
   454     cursor.insertText("Test");
       
   455     QCOMPARE(spy.count(), 1);
       
   456 
       
   457     spy.clear();
       
   458     QTest::keyClick(ed, Qt::Key_Left);
       
   459     QCOMPARE(spy.count(), 1);
       
   460 
       
   461     CursorPositionChangedRecorder spy2(ed);
       
   462     QVERIFY(ed->textCursor().position() > 0);
       
   463     ed->setPlainText("Hello World");
       
   464     QCOMPARE(spy2.cursorPositions.count(), 1);
       
   465     QCOMPARE(spy2.cursorPositions.at(0), 0);
       
   466     QCOMPARE(ed->textCursor().position(), 0);
       
   467 }
       
   468 
       
   469 void tst_QPlainTextEdit::setTextCursor()
       
   470 {
       
   471     QSignalSpy spy(ed, SIGNAL(cursorPositionChanged()));
       
   472 
       
   473     ed->setPlainText("Test");
       
   474     QTextCursor cursor = ed->textCursor();
       
   475     cursor.movePosition(QTextCursor::Start);
       
   476     cursor.movePosition(QTextCursor::NextCharacter);
       
   477 
       
   478     spy.clear();
       
   479 
       
   480     ed->setTextCursor(cursor);
       
   481     QCOMPARE(spy.count(), 1);
       
   482 }
       
   483 
       
   484 #ifndef QT_NO_CLIPBOARD
       
   485 void tst_QPlainTextEdit::undoAvailableAfterPaste()
       
   486 {
       
   487     if (!nativeClipboardWorking())
       
   488         QSKIP("Clipboard not working with cron-started unit tests", SkipAll);
       
   489 
       
   490     QSignalSpy spy(ed->document(), SIGNAL(undoAvailable(bool)));
       
   491 
       
   492     const QString txt("Test");
       
   493     QApplication::clipboard()->setText(txt);
       
   494     ed->paste();
       
   495     QVERIFY(spy.count() >= 1);
       
   496     QCOMPARE(ed->toPlainText(), txt);
       
   497 }
       
   498 #endif
       
   499 
       
   500 class UndoRedoRecorder : public QObject
       
   501 {
       
   502     Q_OBJECT
       
   503 public:
       
   504     UndoRedoRecorder(QTextDocument *doc)
       
   505         : undoRepetitions(false)
       
   506         , redoRepetitions(false)
       
   507         , undoCount(0)
       
   508         , redoCount(0)
       
   509     {
       
   510         connect(doc, SIGNAL(undoAvailable(bool)), this, SLOT(undoAvailable(bool)));
       
   511         connect(doc, SIGNAL(redoAvailable(bool)), this, SLOT(redoAvailable(bool)));
       
   512     }
       
   513 
       
   514     bool undoRepetitions;
       
   515     bool redoRepetitions;
       
   516 
       
   517 private slots:
       
   518     void undoAvailable(bool enabled) {
       
   519         if (undoCount > 0 && enabled == lastUndoEnabled)
       
   520             undoRepetitions = true;
       
   521 
       
   522         ++undoCount;
       
   523         lastUndoEnabled = enabled;
       
   524     }
       
   525 
       
   526     void redoAvailable(bool enabled) {
       
   527         if (redoCount > 0 && enabled == lastRedoEnabled)
       
   528             redoRepetitions = true;
       
   529 
       
   530         ++redoCount;
       
   531         lastRedoEnabled = enabled;
       
   532     }
       
   533 
       
   534 private:
       
   535     bool lastUndoEnabled;
       
   536     bool lastRedoEnabled;
       
   537 
       
   538     int undoCount;
       
   539     int redoCount;
       
   540 };
       
   541 
       
   542 void tst_QPlainTextEdit::undoRedoAvailableRepetition()
       
   543 {
       
   544     UndoRedoRecorder spy(ed->document());
       
   545 
       
   546     ed->textCursor().insertText("ABC\n\nDEF\n\nGHI\n");
       
   547     ed->textCursor().insertText("foo\n");
       
   548     ed->textCursor().insertText("bar\n");
       
   549     ed->undo(); ed->undo(); ed->undo();
       
   550     ed->redo(); ed->redo(); ed->redo();
       
   551 
       
   552     QVERIFY(!spy.undoRepetitions);
       
   553     QVERIFY(!spy.redoRepetitions);
       
   554 }
       
   555 
       
   556 void tst_QPlainTextEdit::appendShouldNotTouchTheSelection()
       
   557 {
       
   558     QTextCursor cursor(ed->document());
       
   559     QTextCharFormat fmt;
       
   560     fmt.setForeground(Qt::blue);
       
   561     cursor.insertText("H", fmt);
       
   562     fmt.setForeground(Qt::red);
       
   563     cursor.insertText("ey", fmt);
       
   564 
       
   565     cursor.insertText("some random text inbetween");
       
   566 
       
   567     cursor.movePosition(QTextCursor::Start);
       
   568     cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
       
   569     QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::blue));
       
   570     cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
       
   571     QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::red));
       
   572     cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
       
   573     QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::red));
       
   574     QCOMPARE(cursor.selectedText(), QString("Hey"));
       
   575 
       
   576     ed->setTextCursor(cursor);
       
   577     QVERIFY(ed->textCursor().hasSelection());
       
   578 
       
   579     ed->appendHtml("<b>Some Bold Text</b>");
       
   580     cursor.movePosition(QTextCursor::Start);
       
   581     cursor.movePosition(QTextCursor::NextCharacter);
       
   582     QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::blue));
       
   583 }
       
   584 
       
   585 void tst_QPlainTextEdit::backspace()
       
   586 {
       
   587     QTextCursor cursor = ed->textCursor();
       
   588 
       
   589     QTextListFormat listFmt;
       
   590     listFmt.setStyle(QTextListFormat::ListDisc);
       
   591     listFmt.setIndent(1);
       
   592     cursor.insertList(listFmt);
       
   593     cursor.insertText("A");
       
   594 
       
   595     ed->setTextCursor(cursor);
       
   596 
       
   597     // delete 'A'
       
   598     QTest::keyClick(ed, Qt::Key_Backspace);
       
   599     QVERIFY(ed->textCursor().currentList());
       
   600     // delete list
       
   601     QTest::keyClick(ed, Qt::Key_Backspace);
       
   602     QVERIFY(!ed->textCursor().currentList());
       
   603     QCOMPARE(ed->textCursor().blockFormat().indent(), 1);
       
   604     // outdent paragraph
       
   605     QTest::keyClick(ed, Qt::Key_Backspace);
       
   606     QCOMPARE(ed->textCursor().blockFormat().indent(), 0);
       
   607 }
       
   608 
       
   609 void tst_QPlainTextEdit::shiftBackspace()
       
   610 {
       
   611     QTextCursor cursor = ed->textCursor();
       
   612 
       
   613     QTextListFormat listFmt;
       
   614     listFmt.setStyle(QTextListFormat::ListDisc);
       
   615     listFmt.setIndent(1);
       
   616     cursor.insertList(listFmt);
       
   617     cursor.insertText("A");
       
   618 
       
   619     ed->setTextCursor(cursor);
       
   620 
       
   621     // delete 'A'
       
   622     QTest::keyClick(ed, Qt::Key_Backspace, Qt::ShiftModifier);
       
   623     QVERIFY(ed->textCursor().currentList());
       
   624     // delete list
       
   625     QTest::keyClick(ed, Qt::Key_Backspace, Qt::ShiftModifier);
       
   626     QVERIFY(!ed->textCursor().currentList());
       
   627     QCOMPARE(ed->textCursor().blockFormat().indent(), 1);
       
   628     // outdent paragraph
       
   629     QTest::keyClick(ed, Qt::Key_Backspace, Qt::ShiftModifier);
       
   630     QCOMPARE(ed->textCursor().blockFormat().indent(), 0);
       
   631 }
       
   632 
       
   633 void tst_QPlainTextEdit::undoRedo()
       
   634 {
       
   635     ed->clear();
       
   636     QTest::keyClicks(ed, "abc d");
       
   637     QCOMPARE(ed->toPlainText(), QString("abc d"));
       
   638     ed->undo();
       
   639     QCOMPARE(ed->toPlainText(), QString());
       
   640     ed->redo();
       
   641     QCOMPARE(ed->toPlainText(), QString("abc d"));
       
   642 #ifdef Q_WS_WIN
       
   643     // shortcut for undo
       
   644     QTest::keyClick(ed, Qt::Key_Backspace, Qt::AltModifier);
       
   645     QCOMPARE(ed->toPlainText(), QString());
       
   646     // shortcut for redo
       
   647     QTest::keyClick(ed, Qt::Key_Backspace, Qt::ShiftModifier|Qt::AltModifier);
       
   648     QCOMPARE(ed->toPlainText(), QString("abc d"));
       
   649 #endif
       
   650 }
       
   651 
       
   652 // Task #70465
       
   653 void tst_QPlainTextEdit::preserveCharFormatInAppend()
       
   654 {
       
   655     ed->appendHtml("First para");
       
   656     ed->appendHtml("<b>Second para</b>");
       
   657     ed->appendHtml("third para");
       
   658 
       
   659     QTextCursor cursor(ed->textCursor());
       
   660 
       
   661     cursor.movePosition(QTextCursor::Start);
       
   662     cursor.movePosition(QTextCursor::NextCharacter);
       
   663     QCOMPARE(cursor.charFormat().fontWeight(), (int)QFont::Normal);
       
   664     QCOMPARE(cursor.block().text(), QString("First para"));
       
   665 
       
   666     cursor.movePosition(QTextCursor::NextBlock);
       
   667     cursor.movePosition(QTextCursor::NextCharacter);
       
   668     QCOMPARE(cursor.charFormat().fontWeight(), (int)QFont::Bold);
       
   669     QCOMPARE(cursor.block().text(), QString("Second para"));
       
   670 
       
   671     cursor.movePosition(QTextCursor::NextBlock);
       
   672     cursor.movePosition(QTextCursor::NextCharacter);
       
   673     QCOMPARE(cursor.charFormat().fontWeight(), (int)QFont::Normal);
       
   674     QCOMPARE(cursor.block().text(), QString("third para"));
       
   675 }
       
   676 
       
   677 #ifndef QT_NO_CLIPBOARD
       
   678 void tst_QPlainTextEdit::copyAndSelectAllInReadonly()
       
   679 {
       
   680     if (!nativeClipboardWorking())
       
   681         QSKIP("Clipboard not working with cron-started unit tests", SkipAll);
       
   682 
       
   683     ed->setReadOnly(true);
       
   684     ed->setPlainText("Hello World");
       
   685 
       
   686     QTextCursor cursor = ed->textCursor();
       
   687     cursor.clearSelection();
       
   688     ed->setTextCursor(cursor);
       
   689     QVERIFY(!ed->textCursor().hasSelection());
       
   690 
       
   691     QCOMPARE(ed->toPlainText(), QString("Hello World"));
       
   692 
       
   693     // shouldn't do anything
       
   694     QTest::keyClick(ed, Qt::Key_A);
       
   695 
       
   696     QCOMPARE(ed->toPlainText(), QString("Hello World"));
       
   697 
       
   698     QTest::keyClick(ed, Qt::Key_A, Qt::ControlModifier);
       
   699 
       
   700     QVERIFY(ed->textCursor().hasSelection());
       
   701 
       
   702     QApplication::clipboard()->setText(QString());
       
   703     QVERIFY(QApplication::clipboard()->text().isEmpty());
       
   704 
       
   705     QTest::keyClick(ed, Qt::Key_C, Qt::ControlModifier);
       
   706     QCOMPARE(QApplication::clipboard()->text(), QString("Hello World"));
       
   707 }
       
   708 #endif
       
   709 
       
   710 void tst_QPlainTextEdit::ctrlAltInput()
       
   711 {
       
   712     QTest::keyClick(ed, Qt::Key_At, Qt::ControlModifier | Qt::AltModifier);
       
   713     QCOMPARE(ed->toPlainText(), QString("@"));
       
   714 }
       
   715 
       
   716 void tst_QPlainTextEdit::noPropertiesOnDefaultTextEditCharFormat()
       
   717 {
       
   718     // there should be no properties set on the default/initial char format
       
   719     // on a text edit. Font properties instead should be taken from the
       
   720     // widget's font (in sync with defaultFont property in document) and the
       
   721     // foreground color should be taken from the palette.
       
   722     QCOMPARE(ed->textCursor().charFormat().properties().count(), 0);
       
   723 }
       
   724 
       
   725 void tst_QPlainTextEdit::setPlainTextShouldEmitTextChangedOnce()
       
   726 {
       
   727     QSignalSpy spy(ed, SIGNAL(textChanged()));
       
   728     ed->setPlainText("Yankee Doodle");
       
   729     QCOMPARE(spy.count(), 1);
       
   730     ed->setPlainText("");
       
   731     QCOMPARE(spy.count(), 2);
       
   732 }
       
   733 
       
   734 void tst_QPlainTextEdit::overwriteMode()
       
   735 {
       
   736     QVERIFY(!ed->overwriteMode());
       
   737     QTest::keyClicks(ed, "Some first text");
       
   738 
       
   739     QCOMPARE(ed->toPlainText(), QString("Some first text"));
       
   740 
       
   741     ed->setOverwriteMode(true);
       
   742 
       
   743     QTextCursor cursor = ed->textCursor();
       
   744     cursor.setPosition(5);
       
   745     ed->setTextCursor(cursor);
       
   746 
       
   747     QTest::keyClicks(ed, "shiny");
       
   748     QCOMPARE(ed->toPlainText(), QString("Some shiny text"));
       
   749 
       
   750     cursor.movePosition(QTextCursor::End);
       
   751     ed->setTextCursor(cursor);
       
   752 
       
   753     QTest::keyClick(ed, Qt::Key_Enter);
       
   754 
       
   755     ed->setOverwriteMode(false);
       
   756     QTest::keyClicks(ed, "Second paragraph");
       
   757 
       
   758     QCOMPARE(blockCount(), 2);
       
   759 
       
   760     cursor.movePosition(QTextCursor::Start);
       
   761     cursor.movePosition(QTextCursor::EndOfBlock);
       
   762 
       
   763     QCOMPARE(cursor.position(), 15);
       
   764     ed->setTextCursor(cursor);
       
   765 
       
   766     ed->setOverwriteMode(true);
       
   767 
       
   768     QTest::keyClicks(ed, " blah");
       
   769 
       
   770     QCOMPARE(blockCount(), 2);
       
   771 
       
   772     QTextBlock block = ed->document()->begin();
       
   773     QCOMPARE(block.text(), QString("Some shiny text blah"));
       
   774     block = block.next();
       
   775     QCOMPARE(block.text(), QString("Second paragraph"));
       
   776 }
       
   777 
       
   778 void tst_QPlainTextEdit::shiftDownInLineLastShouldSelectToEnd_data()
       
   779 {
       
   780     // shift cursor-down in the last line should select to the end of the document
       
   781 
       
   782     QTest::addColumn<QString>("input");
       
   783     QTest::addColumn<int>("totalLineCount");
       
   784 
       
   785     QTest::newRow("1") << QString("Foo\nBar") << 2;
       
   786     QTest::newRow("2") << QString("Foo\nBar") + QChar(QChar::LineSeparator) + QString("Baz") << 3;
       
   787 }
       
   788 
       
   789 void tst_QPlainTextEdit::shiftDownInLineLastShouldSelectToEnd()
       
   790 {
       
   791     QFETCH(QString, input);
       
   792     QFETCH(int, totalLineCount);
       
   793 
       
   794     ed->setPlainText(input);
       
   795     ed->show();
       
   796 
       
   797     // ensure we're layouted
       
   798     for (QTextBlock block = ed->document()->begin(); block.isValid(); block = block.next())
       
   799         ed->document()->documentLayout()->blockBoundingRect(block);
       
   800 
       
   801     QCOMPARE(blockCount(), 2);
       
   802 
       
   803     int lineCount = 0;
       
   804     for (QTextBlock block = ed->document()->begin(); block.isValid(); block = block.next())
       
   805         lineCount += block.layout()->lineCount();
       
   806     QCOMPARE(lineCount, totalLineCount);
       
   807 
       
   808     QTextCursor cursor = ed->textCursor();
       
   809     cursor.movePosition(QTextCursor::Start);
       
   810     ed->setTextCursor(cursor);
       
   811 
       
   812     for (int i = 0; i < lineCount; ++i) {
       
   813         QTest::keyClick(ed, Qt::Key_Down, Qt::ShiftModifier);
       
   814     }
       
   815 
       
   816     input.replace(QLatin1Char('\n'), QChar(QChar::ParagraphSeparator));
       
   817     QCOMPARE(ed->textCursor().selectedText(), input);
       
   818     QVERIFY(ed->textCursor().atEnd());
       
   819 
       
   820     // also test that without shift modifier the cursor does not move to the end
       
   821     // for Key_Down in the last line
       
   822     cursor.movePosition(QTextCursor::Start);
       
   823     ed->setTextCursor(cursor);
       
   824     for (int i = 0; i < lineCount; ++i) {
       
   825         QTest::keyClick(ed, Qt::Key_Down);
       
   826     }
       
   827     QVERIFY(!ed->textCursor().atEnd());
       
   828 }
       
   829 
       
   830 void tst_QPlainTextEdit::undoRedoShouldRepositionTextEditCursor()
       
   831 {
       
   832     ed->setPlainText("five\nlines\nin\nthis\ntextedit");
       
   833     QTextCursor cursor = ed->textCursor();
       
   834     cursor.movePosition(QTextCursor::Start);
       
   835 
       
   836     ed->setUndoRedoEnabled(false);
       
   837     ed->setUndoRedoEnabled(true);
       
   838 
       
   839     QVERIFY(!ed->document()->isUndoAvailable());
       
   840     QVERIFY(!ed->document()->isRedoAvailable());
       
   841 
       
   842     cursor.insertText("Blah");
       
   843 
       
   844     QVERIFY(ed->document()->isUndoAvailable());
       
   845     QVERIFY(!ed->document()->isRedoAvailable());
       
   846 
       
   847     cursor.movePosition(QTextCursor::End);
       
   848     ed->setTextCursor(cursor);
       
   849 
       
   850     QVERIFY(QMetaObject::invokeMethod(ed, "undo"));
       
   851 
       
   852     QVERIFY(!ed->document()->isUndoAvailable());
       
   853     QVERIFY(ed->document()->isRedoAvailable());
       
   854 
       
   855     QCOMPARE(ed->textCursor().position(), 0);
       
   856 
       
   857     cursor.movePosition(QTextCursor::End);
       
   858     ed->setTextCursor(cursor);
       
   859 
       
   860     QVERIFY(QMetaObject::invokeMethod(ed, "redo"));
       
   861 
       
   862     QVERIFY(ed->document()->isUndoAvailable());
       
   863     QVERIFY(!ed->document()->isRedoAvailable());
       
   864 
       
   865     QCOMPARE(ed->textCursor().position(), 4);
       
   866 }
       
   867 
       
   868 void tst_QPlainTextEdit::lineWrapModes()
       
   869 {
       
   870     QWidget *window = new QWidget;
       
   871     ed->setParent(window);
       
   872     window->show();
       
   873     ed->show();
       
   874     ed->setPlainText("a b c d e f g h i j k l m n o p q r s t u v w x y z");
       
   875     ed->setLineWrapMode(QPlainTextEdit::NoWrap);
       
   876     QCOMPARE(lineCount(), 1);
       
   877     ed->setLineWrapMode(QPlainTextEdit::WidgetWidth);
       
   878 
       
   879     // QPlainTextEdit does lazy line layout on resize, only for the visible blocks.
       
   880     // We thus need to make it wide enough to show something visible.
       
   881     int minimumWidth = 2 * ed->document()->documentMargin();
       
   882     minimumWidth += ed->fontMetrics().width(QLatin1Char('a'));
       
   883     ed->resize(minimumWidth, 1000);
       
   884     QCOMPARE(lineCount(), 26);
       
   885     ed->setParent(0);
       
   886     delete window;
       
   887 }
       
   888 
       
   889 void tst_QPlainTextEdit::mouseCursorShape()
       
   890 {
       
   891 #ifndef QT_NO_CURSOR
       
   892     // always show an IBeamCursor, see change 170146
       
   893     QVERIFY(!ed->isReadOnly());
       
   894     QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor);
       
   895 
       
   896     ed->setReadOnly(true);
       
   897     QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor);
       
   898 
       
   899     ed->setPlainText("Foo");
       
   900     QVERIFY(ed->viewport()->cursor().shape() == Qt::IBeamCursor);
       
   901 #endif
       
   902 }
       
   903 
       
   904 void tst_QPlainTextEdit::implicitClear()
       
   905 {
       
   906     // test that QPlainTextEdit::setHtml, etc. avoid calling clear() but instead call
       
   907     // QTextDocument::setHtml/etc. instead, which also clear the contents and
       
   908     // cached resource but preserve manually added resources. setHtml on a textedit
       
   909     // should behave the same as on a document with respect to that.
       
   910     // see also clearResources() autotest in qtextdocument
       
   911 
       
   912     // regular resource for QTextDocument
       
   913     QUrl testUrl(":/foobar");
       
   914     QVariant testResource("hello world");
       
   915 
       
   916     ed->document()->addResource(QTextDocument::ImageResource, testUrl, testResource);
       
   917     QVERIFY(ed->document()->resource(QTextDocument::ImageResource, testUrl) == testResource);
       
   918 
       
   919     ed->setPlainText("Blah");
       
   920     QVERIFY(ed->document()->resource(QTextDocument::ImageResource, testUrl) == testResource);
       
   921 
       
   922     ed->setPlainText("<b>Blah</b>");
       
   923     QVERIFY(ed->document()->resource(QTextDocument::ImageResource, testUrl) == testResource);
       
   924 
       
   925     ed->clear();
       
   926     QVERIFY(!ed->document()->resource(QTextDocument::ImageResource, testUrl).isValid());
       
   927     QVERIFY(ed->toPlainText().isEmpty());
       
   928 }
       
   929 
       
   930 #ifndef QT_NO_CLIPBOARD
       
   931 void tst_QPlainTextEdit::copyAvailable_data()
       
   932 {
       
   933     QTest::addColumn<pairListType>("keystrokes");
       
   934     QTest::addColumn<QList<bool> >("copyAvailable");
       
   935     QTest::addColumn<QString>("function");
       
   936 
       
   937     pairListType keystrokes;
       
   938     QList<bool> copyAvailable;
       
   939 
       
   940     keystrokes << qMakePair(Qt::Key_B, Qt::NoModifier) <<  qMakePair(Qt::Key_B, Qt::NoModifier)
       
   941                << qMakePair(Qt::Key_Left, Qt::ShiftModifier);
       
   942     copyAvailable << true ;
       
   943     QTest::newRow(QString("Case1 B,B, <- + shift | signals: true").toLatin1())
       
   944         << keystrokes << copyAvailable << QString();
       
   945 
       
   946     keystrokes.clear();
       
   947     copyAvailable.clear();
       
   948 
       
   949     keystrokes << qMakePair(Qt::Key_T, Qt::NoModifier) << qMakePair(Qt::Key_A, Qt::NoModifier)
       
   950                <<  qMakePair(Qt::Key_A, Qt::NoModifier) << qMakePair(Qt::Key_Left, Qt::ShiftModifier);
       
   951     copyAvailable << true << false;
       
   952     QTest::newRow(QString("Case2 T,A,A, <- + shift, cut() | signals: true, false").toLatin1())
       
   953         << keystrokes << copyAvailable << QString("cut");
       
   954 
       
   955     keystrokes.clear();
       
   956     copyAvailable.clear();
       
   957 
       
   958     keystrokes << qMakePair(Qt::Key_T, Qt::NoModifier) << qMakePair(Qt::Key_A, Qt::NoModifier)
       
   959                <<  qMakePair(Qt::Key_A, Qt::NoModifier) << qMakePair(Qt::Key_Left, Qt::ShiftModifier)
       
   960                << qMakePair(Qt::Key_Left, Qt::ShiftModifier)  << qMakePair(Qt::Key_Left, Qt::ShiftModifier);
       
   961     copyAvailable << true;
       
   962     QTest::newRow(QString("Case3 T,A,A, <- + shift, <- + shift, <- + shift, copy() | signals: true").toLatin1())
       
   963         << keystrokes << copyAvailable << QString("copy");
       
   964 
       
   965     keystrokes.clear();
       
   966     copyAvailable.clear();
       
   967 
       
   968     keystrokes << qMakePair(Qt::Key_T, Qt::NoModifier) << qMakePair(Qt::Key_A, Qt::NoModifier)
       
   969                <<  qMakePair(Qt::Key_A, Qt::NoModifier) << qMakePair(Qt::Key_Left, Qt::ShiftModifier)
       
   970                << qMakePair(Qt::Key_Left, Qt::ShiftModifier)  << qMakePair(Qt::Key_Left, Qt::ShiftModifier)
       
   971                << qMakePair(Qt::Key_X, Qt::ControlModifier);
       
   972     copyAvailable << true << false;
       
   973     QTest::newRow(QString("Case4 T,A,A, <- + shift, <- + shift, <- + shift, ctrl + x, paste() | signals: true, false").toLatin1())
       
   974         << keystrokes << copyAvailable << QString("paste");
       
   975 
       
   976     keystrokes.clear();
       
   977     copyAvailable.clear();
       
   978 
       
   979     keystrokes << qMakePair(Qt::Key_B, Qt::NoModifier) <<  qMakePair(Qt::Key_B, Qt::NoModifier)
       
   980                << qMakePair(Qt::Key_Left, Qt::ShiftModifier) << qMakePair(Qt::Key_Left, Qt::NoModifier);
       
   981     copyAvailable << true << false;
       
   982     QTest::newRow(QString("Case5 B,B, <- + shift, <- | signals: true, false").toLatin1())
       
   983         << keystrokes << copyAvailable << QString();
       
   984 
       
   985     keystrokes.clear();
       
   986     copyAvailable.clear();
       
   987 
       
   988     keystrokes << qMakePair(Qt::Key_B, Qt::NoModifier) <<  qMakePair(Qt::Key_A, Qt::NoModifier)
       
   989                << qMakePair(Qt::Key_Left, Qt::ShiftModifier) << qMakePair(Qt::Key_Left, Qt::NoModifier)
       
   990                << qMakePair(Qt::Key_Right, Qt::ShiftModifier);
       
   991     copyAvailable << true << false << true << false;
       
   992     QTest::newRow(QString("Case6 B,A, <- + shift, ->, <- + shift | signals: true, false, true, false").toLatin1())
       
   993         << keystrokes << copyAvailable << QString("cut");
       
   994 
       
   995     keystrokes.clear();
       
   996     copyAvailable.clear();
       
   997 
       
   998     keystrokes << qMakePair(Qt::Key_T, Qt::NoModifier) << qMakePair(Qt::Key_A, Qt::NoModifier)
       
   999                <<  qMakePair(Qt::Key_A, Qt::NoModifier) << qMakePair(Qt::Key_Left, Qt::ShiftModifier)
       
  1000                << qMakePair(Qt::Key_Left, Qt::ShiftModifier)  << qMakePair(Qt::Key_Left, Qt::ShiftModifier)
       
  1001                << qMakePair(Qt::Key_X, Qt::ControlModifier);
       
  1002     copyAvailable << true << false << true;
       
  1003     QTest::newRow(QString("Case7 T,A,A, <- + shift, <- + shift, <- + shift, ctrl + x, undo() | signals: true, false, true").toLatin1())
       
  1004         << keystrokes << copyAvailable << QString("undo");
       
  1005 }
       
  1006 
       
  1007 //Tests the copyAvailable slot for several cases
       
  1008 void tst_QPlainTextEdit::copyAvailable()
       
  1009 {
       
  1010     QFETCH(pairListType,keystrokes);
       
  1011     QFETCH(QList<bool>, copyAvailable);
       
  1012     QFETCH(QString, function);
       
  1013 
       
  1014 #ifdef Q_WS_MAC
       
  1015     QSKIP("copyAvailable has never passed on Mac, task to fix is 132482", SkipAll);
       
  1016 #endif
       
  1017     ed->clear();
       
  1018     QApplication::clipboard()->clear();
       
  1019     QVERIFY(!ed->canPaste());
       
  1020     QSignalSpy spyCopyAvailabe(ed, SIGNAL(copyAvailable(bool)));
       
  1021 
       
  1022     //Execute Keystrokes
       
  1023     foreach(keyPairType keyPair, keystrokes) {
       
  1024         QTest::keyClick(ed, keyPair.first, keyPair.second );
       
  1025     }
       
  1026 
       
  1027     //Execute ed->"function"
       
  1028     if (function == "cut")
       
  1029         ed->cut();
       
  1030     else if (function == "copy")
       
  1031         ed->copy();
       
  1032     else if (function == "paste")
       
  1033         ed->paste();
       
  1034     else if (function == "undo")
       
  1035         ed->paste();
       
  1036     else if (function == "redo")
       
  1037         ed->paste();
       
  1038 
       
  1039     //Compare spied signals
       
  1040     QEXPECT_FAIL("Case7 T,A,A, <- + shift, <- + shift, <- + shift, ctrl + x, undo() | signals: true, false, true",
       
  1041         "Wrong undo selection behaviour. Should be fixed in some future release. (See task: 132482)", Abort);
       
  1042     QCOMPARE(spyCopyAvailabe.count(), copyAvailable.count());
       
  1043     for (int i=0;i<spyCopyAvailabe.count(); i++) {
       
  1044         QVariant variantSpyCopyAvailable = spyCopyAvailabe.at(i).at(0);
       
  1045         QVERIFY2(variantSpyCopyAvailable.toBool() == copyAvailable.at(i), QString("Spied singnal: %1").arg(i).toLatin1());
       
  1046     }
       
  1047 }
       
  1048 #endif
       
  1049 
       
  1050 void tst_QPlainTextEdit::undoRedoAfterSetContent()
       
  1051 {
       
  1052     QVERIFY(!ed->document()->isUndoAvailable());
       
  1053     QVERIFY(!ed->document()->isRedoAvailable());
       
  1054     ed->setPlainText("Foobar");
       
  1055     QVERIFY(!ed->document()->isUndoAvailable());
       
  1056     QVERIFY(!ed->document()->isRedoAvailable());
       
  1057     ed->setPlainText("<p>bleh</p>");
       
  1058     QVERIFY(!ed->document()->isUndoAvailable());
       
  1059     QVERIFY(!ed->document()->isRedoAvailable());
       
  1060 }
       
  1061 
       
  1062 void tst_QPlainTextEdit::numPadKeyNavigation()
       
  1063 {
       
  1064     ed->setPlainText("Hello World");
       
  1065     QCOMPARE(ed->textCursor().position(), 0);
       
  1066     QTest::keyClick(ed, Qt::Key_Right, Qt::KeypadModifier);
       
  1067     QCOMPARE(ed->textCursor().position(), 1);
       
  1068 }
       
  1069 
       
  1070 void tst_QPlainTextEdit::moveCursor()
       
  1071 {
       
  1072     ed->setPlainText("Test");
       
  1073 
       
  1074     QSignalSpy cursorMovedSpy(ed, SIGNAL(cursorPositionChanged()));
       
  1075 
       
  1076     QCOMPARE(ed->textCursor().position(), 0);
       
  1077     ed->moveCursor(QTextCursor::NextCharacter);
       
  1078     QCOMPARE(ed->textCursor().position(), 1);
       
  1079     QCOMPARE(cursorMovedSpy.count(), 1);
       
  1080     ed->moveCursor(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
       
  1081     QCOMPARE(ed->textCursor().position(), 2);
       
  1082     QCOMPARE(cursorMovedSpy.count(), 2);
       
  1083     QCOMPARE(ed->textCursor().selectedText(), QString("e"));
       
  1084 }
       
  1085 
       
  1086 class MyTextEdit : public QPlainTextEdit
       
  1087 {
       
  1088 public:
       
  1089     inline MyTextEdit()
       
  1090         : createMimeDataCallCount(0),
       
  1091           canInsertCallCount(0),
       
  1092           insertCallCount(0)
       
  1093     {}
       
  1094 
       
  1095     mutable int createMimeDataCallCount;
       
  1096     mutable int canInsertCallCount;
       
  1097     mutable int insertCallCount;
       
  1098 
       
  1099     virtual QMimeData *createMimeDataFromSelection() const {
       
  1100         createMimeDataCallCount++;
       
  1101         return QPlainTextEdit::createMimeDataFromSelection();
       
  1102     }
       
  1103     virtual bool canInsertFromMimeData(const QMimeData *source) const {
       
  1104         canInsertCallCount++;
       
  1105         return QPlainTextEdit::canInsertFromMimeData(source);
       
  1106     }
       
  1107     virtual void insertFromMimeData(const QMimeData *source) {
       
  1108         insertCallCount++;
       
  1109         QPlainTextEdit::insertFromMimeData(source);
       
  1110     }
       
  1111 
       
  1112 };
       
  1113 
       
  1114 #ifndef QT_NO_CLIPBOARD
       
  1115 void tst_QPlainTextEdit::mimeDataReimplementations()
       
  1116 {
       
  1117     MyTextEdit ed;
       
  1118     ed.setPlainText("Hello World");
       
  1119 
       
  1120     QCOMPARE(ed.createMimeDataCallCount, 0);
       
  1121     QCOMPARE(ed.canInsertCallCount, 0);
       
  1122     QCOMPARE(ed.insertCallCount, 0);
       
  1123 
       
  1124     ed.selectAll();
       
  1125 
       
  1126     QCOMPARE(ed.createMimeDataCallCount, 0);
       
  1127     QCOMPARE(ed.canInsertCallCount, 0);
       
  1128     QCOMPARE(ed.insertCallCount, 0);
       
  1129 
       
  1130     ed.copy();
       
  1131 
       
  1132     QCOMPARE(ed.createMimeDataCallCount, 1);
       
  1133     QCOMPARE(ed.canInsertCallCount, 0);
       
  1134     QCOMPARE(ed.insertCallCount, 0);
       
  1135 
       
  1136 #ifdef QT_BUILD_INTERNAL
       
  1137     QTextControl *control = qFindChild<QTextControl *>(&ed);
       
  1138     QVERIFY(control);
       
  1139 
       
  1140     control->canInsertFromMimeData(QApplication::clipboard()->mimeData());
       
  1141 
       
  1142     QCOMPARE(ed.createMimeDataCallCount, 1);
       
  1143     QCOMPARE(ed.canInsertCallCount, 1);
       
  1144     QCOMPARE(ed.insertCallCount, 0);
       
  1145 
       
  1146     ed.paste();
       
  1147 
       
  1148     QCOMPARE(ed.createMimeDataCallCount, 1);
       
  1149     QCOMPARE(ed.canInsertCallCount, 1);
       
  1150     QCOMPARE(ed.insertCallCount, 1);
       
  1151 #endif
       
  1152 }
       
  1153 #endif
       
  1154 
       
  1155 void tst_QPlainTextEdit::shiftEnterShouldInsertLineSeparator()
       
  1156 {
       
  1157     QTest::keyClick(ed, Qt::Key_A);
       
  1158     QTest::keyClick(ed, Qt::Key_Enter, Qt::ShiftModifier);
       
  1159     QTest::keyClick(ed, Qt::Key_B);
       
  1160     QString expected;
       
  1161     expected += 'a';
       
  1162     expected += QChar::LineSeparator;
       
  1163     expected += 'b';
       
  1164     QCOMPARE(ed->textCursor().block().text(), expected);
       
  1165 }
       
  1166 
       
  1167 void tst_QPlainTextEdit::selectWordsFromStringsContainingSeparators_data()
       
  1168 {
       
  1169     QTest::addColumn<QString>("testString");
       
  1170     QTest::addColumn<QString>("selectedWord");
       
  1171 
       
  1172     QStringList wordSeparators;
       
  1173     wordSeparators << "." << "," << "?" << "!" << ":" << ";" << "-" << "<" << ">" << "["
       
  1174                    << "]" << "(" << ")" << "{" << "}" << "=" << "\t"<< QString(QChar::Nbsp);
       
  1175 
       
  1176     foreach (QString s, wordSeparators)
       
  1177         QTest::newRow(QString("separator: " + s).toLocal8Bit()) << QString("foo") + s + QString("bar") << QString("foo");
       
  1178 }
       
  1179 
       
  1180 void tst_QPlainTextEdit::selectWordsFromStringsContainingSeparators()
       
  1181 {
       
  1182     QFETCH(QString, testString);
       
  1183     QFETCH(QString, selectedWord);
       
  1184     ed->setPlainText(testString);
       
  1185     QTextCursor cursor = ed->textCursor();
       
  1186     cursor.movePosition(QTextCursor::StartOfLine);
       
  1187     cursor.select(QTextCursor::WordUnderCursor);
       
  1188     QVERIFY(cursor.hasSelection());
       
  1189     QCOMPARE(cursor.selection().toPlainText(), selectedWord);
       
  1190     cursor.clearSelection();
       
  1191 }
       
  1192 
       
  1193 #ifndef QT_NO_CLIPBOARD
       
  1194 void tst_QPlainTextEdit::canPaste()
       
  1195 {
       
  1196     if (!nativeClipboardWorking())
       
  1197         QSKIP("Clipboard not working with cron-started unit tests", SkipAll);
       
  1198 
       
  1199     QApplication::clipboard()->setText(QString());
       
  1200     QVERIFY(!ed->canPaste());
       
  1201     QApplication::clipboard()->setText("Test");
       
  1202     QVERIFY(ed->canPaste());
       
  1203     ed->setTextInteractionFlags(Qt::NoTextInteraction);
       
  1204     QVERIFY(!ed->canPaste());
       
  1205 }
       
  1206 #endif
       
  1207 
       
  1208 void tst_QPlainTextEdit::ensureCursorVisibleOnInitialShow()
       
  1209 {
       
  1210     QString manyPagesOfPlainText;
       
  1211     for (int i = 0; i < 800; ++i)
       
  1212         manyPagesOfPlainText += QLatin1String("Blah blah blah blah blah blah\n");
       
  1213 
       
  1214     ed->setPlainText(manyPagesOfPlainText);
       
  1215     QCOMPARE(ed->textCursor().position(), 0);
       
  1216 
       
  1217     ed->moveCursor(QTextCursor::End);
       
  1218     ed->show();
       
  1219     QVERIFY(ed->verticalScrollBar()->value() > 10);
       
  1220 
       
  1221     ed->moveCursor(QTextCursor::Start);
       
  1222     QVERIFY(ed->verticalScrollBar()->value() < 10);
       
  1223     ed->hide();
       
  1224     ed->verticalScrollBar()->setValue(ed->verticalScrollBar()->maximum());
       
  1225     ed->show();
       
  1226     QCOMPARE(ed->verticalScrollBar()->value(), ed->verticalScrollBar()->maximum());
       
  1227 }
       
  1228 
       
  1229 class TestEdit : public QPlainTextEdit
       
  1230 {
       
  1231 public:
       
  1232     TestEdit() : resizeEventCalled(false) {}
       
  1233 
       
  1234     bool resizeEventCalled;
       
  1235 
       
  1236 protected:
       
  1237     virtual void resizeEvent(QResizeEvent *e)
       
  1238     {
       
  1239         QPlainTextEdit::resizeEvent(e);
       
  1240         setPlainText("<img src=qtextbrowser-resizeevent.png width=" + QString::number(size().width()) + "><br>Size is " + QString::number(size().width()) + " x " + QString::number(size().height()));
       
  1241         resizeEventCalled = true;
       
  1242     }
       
  1243 };
       
  1244 
       
  1245 void tst_QPlainTextEdit::setTextInsideResizeEvent()
       
  1246 {
       
  1247     TestEdit edit;
       
  1248     edit.show();
       
  1249     edit.resize(800, 600);
       
  1250     QVERIFY(edit.resizeEventCalled);
       
  1251 }
       
  1252 
       
  1253 void tst_QPlainTextEdit::colorfulAppend()
       
  1254 {
       
  1255     QTextCharFormat fmt;
       
  1256 
       
  1257     fmt.setForeground(QBrush(Qt::red));
       
  1258     ed->mergeCurrentCharFormat(fmt);
       
  1259     ed->appendPlainText("Red");
       
  1260     fmt.setForeground(QBrush(Qt::blue));
       
  1261     ed->mergeCurrentCharFormat(fmt);
       
  1262     ed->appendPlainText("Blue");
       
  1263     fmt.setForeground(QBrush(Qt::green));
       
  1264     ed->mergeCurrentCharFormat(fmt);
       
  1265     ed->appendPlainText("Green");
       
  1266 
       
  1267     QCOMPARE(ed->document()->blockCount(), 3);
       
  1268     QTextBlock block = ed->document()->begin();
       
  1269     QCOMPARE(block.begin().fragment().text(), QString("Red"));
       
  1270     QVERIFY(block.begin().fragment().charFormat().foreground().color() == Qt::red);
       
  1271     block = block.next();
       
  1272     QCOMPARE(block.begin().fragment().text(), QString("Blue"));
       
  1273     QVERIFY(block.begin().fragment().charFormat().foreground().color() == Qt::blue);
       
  1274     block = block.next();
       
  1275     QCOMPARE(block.begin().fragment().text(), QString("Green"));
       
  1276     QVERIFY(block.begin().fragment().charFormat().foreground().color() == Qt::green);
       
  1277 }
       
  1278 
       
  1279 void tst_QPlainTextEdit::ensureVisibleWithRtl()
       
  1280 {
       
  1281     ed->setLayoutDirection(Qt::RightToLeft);
       
  1282     ed->setLineWrapMode(QPlainTextEdit::NoWrap);
       
  1283     QString txt(500, QChar(QLatin1Char('a')));
       
  1284     QCOMPARE(txt.length(), 500);
       
  1285     ed->setPlainText(txt);
       
  1286     ed->resize(100, 100);
       
  1287     ed->show();
       
  1288 
       
  1289     qApp->processEvents();
       
  1290 
       
  1291     QVERIFY(ed->horizontalScrollBar()->maximum() > 0);
       
  1292 
       
  1293     ed->moveCursor(QTextCursor::Start);
       
  1294     QCOMPARE(ed->horizontalScrollBar()->value(), ed->horizontalScrollBar()->maximum());
       
  1295     ed->moveCursor(QTextCursor::End);
       
  1296     QCOMPARE(ed->horizontalScrollBar()->value(), 0);
       
  1297     ed->moveCursor(QTextCursor::Start);
       
  1298     QCOMPARE(ed->horizontalScrollBar()->value(), ed->horizontalScrollBar()->maximum());
       
  1299     ed->moveCursor(QTextCursor::End);
       
  1300     QCOMPARE(ed->horizontalScrollBar()->value(), 0);
       
  1301 }
       
  1302 
       
  1303 void tst_QPlainTextEdit::preserveCharFormatAfterSetPlainText()
       
  1304 {
       
  1305     QTextCharFormat fmt;
       
  1306     fmt.setForeground(QBrush(Qt::blue));
       
  1307     ed->mergeCurrentCharFormat(fmt);
       
  1308     ed->setPlainText("This is blue");
       
  1309     ed->appendPlainText("This should still be blue");
       
  1310     QTextBlock block = ed->document()->begin();
       
  1311     block = block.next();
       
  1312     QCOMPARE(block.text(), QString("This should still be blue"));
       
  1313     QVERIFY(block.begin().fragment().charFormat().foreground().color() == QColor(Qt::blue));
       
  1314 }
       
  1315 
       
  1316 void tst_QPlainTextEdit::extraSelections()
       
  1317 {
       
  1318     ed->setPlainText("Hello World");
       
  1319 
       
  1320     QTextCursor c = ed->textCursor();
       
  1321     c.movePosition(QTextCursor::Start);
       
  1322     c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
       
  1323     const int endPos = c.position();
       
  1324 
       
  1325     QTextEdit::ExtraSelection sel;
       
  1326     sel.cursor = c;
       
  1327     ed->setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
       
  1328 
       
  1329     c.movePosition(QTextCursor::Start);
       
  1330     c.movePosition(QTextCursor::NextWord);
       
  1331     const int wordPos = c.position();
       
  1332     c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
       
  1333     sel.cursor = c;
       
  1334     ed->setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
       
  1335 
       
  1336     QList<QTextEdit::ExtraSelection> selections = ed->extraSelections();
       
  1337     QCOMPARE(selections.count(), 1);
       
  1338     QCOMPARE(selections.at(0).cursor.position(), endPos);
       
  1339     QCOMPARE(selections.at(0).cursor.anchor(), wordPos);
       
  1340 }
       
  1341 
       
  1342 void tst_QPlainTextEdit::adjustScrollbars()
       
  1343 {
       
  1344 // For some reason ff is defined to be << on Mac Panther / gcc 3.3
       
  1345 #undef ff
       
  1346     QFont ff(ed->font());
       
  1347     ff.setFamily("Tahoma");
       
  1348     ff.setPointSize(11);
       
  1349     ed->setFont(ff);
       
  1350     ed->setMinimumSize(140, 100);
       
  1351     ed->setMaximumSize(140, 100);
       
  1352     ed->show();
       
  1353     QLatin1String txt("\nabc def ghi jkl mno pqr stu vwx");
       
  1354     ed->setPlainText(txt + txt + txt + txt);
       
  1355 
       
  1356     QVERIFY(ed->verticalScrollBar()->maximum() > 0);
       
  1357 
       
  1358     ed->moveCursor(QTextCursor::End);
       
  1359     int oldMaximum = ed->verticalScrollBar()->maximum();
       
  1360     QTextCursor cursor = ed->textCursor();
       
  1361     cursor.insertText(QLatin1String("\n"));
       
  1362     cursor.deletePreviousChar();
       
  1363     QCOMPARE(ed->verticalScrollBar()->maximum(), oldMaximum);
       
  1364 }
       
  1365 
       
  1366 class SignalReceiver : public QObject
       
  1367 {
       
  1368     Q_OBJECT
       
  1369 public:
       
  1370     SignalReceiver() : received(0) {}
       
  1371 
       
  1372     int receivedSignals() const { return received; }
       
  1373     QTextCharFormat charFormat() const { return format; }
       
  1374 
       
  1375 public slots:
       
  1376     void charFormatChanged(const QTextCharFormat &tcf) { ++received; format = tcf; }
       
  1377 
       
  1378 private:
       
  1379     QTextCharFormat format;
       
  1380     int received;
       
  1381 };
       
  1382 
       
  1383 void tst_QPlainTextEdit::textObscuredByScrollbars()
       
  1384 {
       
  1385     ed->textCursor().insertText(
       
  1386             "ab cab cab c abca kjsdf lka sjd lfk jsal df j kasdf abc ab abc "
       
  1387             "a b c d e f g h i j k l m n o p q r s t u v w x y z "
       
  1388             "abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc "
       
  1389             "ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab"
       
  1390             "abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc "
       
  1391             "ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab"
       
  1392             "abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc "
       
  1393             "ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab"
       
  1394             "abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc "
       
  1395             "ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab"
       
  1396             "abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc "
       
  1397             "ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab"
       
  1398     );
       
  1399     ed->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1400     ed->show();
       
  1401 
       
  1402     QSize documentSize = ed->document()->documentLayout()->documentSize().toSize();
       
  1403     QSize viewportSize = ed->viewport()->size();
       
  1404 
       
  1405     QVERIFY(documentSize.width() <= viewportSize.width());
       
  1406 }
       
  1407 
       
  1408 void tst_QPlainTextEdit::setTextPreservesUndoRedoEnabled()
       
  1409 {
       
  1410     QVERIFY(ed->isUndoRedoEnabled());
       
  1411 
       
  1412     ed->setPlainText("Test");
       
  1413 
       
  1414     QVERIFY(ed->isUndoRedoEnabled());
       
  1415 
       
  1416     ed->setUndoRedoEnabled(false);
       
  1417     QVERIFY(!ed->isUndoRedoEnabled());
       
  1418     ed->setPlainText("Test2");
       
  1419     QVERIFY(!ed->isUndoRedoEnabled());
       
  1420 
       
  1421     ed->setPlainText("<p>hello");
       
  1422     QVERIFY(!ed->isUndoRedoEnabled());
       
  1423 }
       
  1424 
       
  1425 void tst_QPlainTextEdit::wordWrapProperty()
       
  1426 {
       
  1427     {
       
  1428         QPlainTextEdit edit;
       
  1429         QTextDocument *doc = new QTextDocument(&edit);
       
  1430         doc->setDocumentLayout(new QPlainTextDocumentLayout(doc));
       
  1431         edit.setDocument(doc);
       
  1432         edit.setWordWrapMode(QTextOption::NoWrap);
       
  1433         QVERIFY(doc->defaultTextOption().wrapMode() == QTextOption::NoWrap);
       
  1434     }
       
  1435     {
       
  1436         QPlainTextEdit edit;
       
  1437         QTextDocument *doc = new QTextDocument(&edit);
       
  1438         doc->setDocumentLayout(new QPlainTextDocumentLayout(doc));
       
  1439         edit.setWordWrapMode(QTextOption::NoWrap);
       
  1440         edit.setDocument(doc);
       
  1441         QVERIFY(doc->defaultTextOption().wrapMode() == QTextOption::NoWrap);
       
  1442     }
       
  1443 }
       
  1444 
       
  1445 void tst_QPlainTextEdit::lineWrapProperty()
       
  1446 {
       
  1447     QVERIFY(ed->wordWrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere);
       
  1448     QVERIFY(ed->lineWrapMode() == QPlainTextEdit::WidgetWidth);
       
  1449     ed->setLineWrapMode(QPlainTextEdit::NoWrap);
       
  1450     QVERIFY(ed->lineWrapMode() == QPlainTextEdit::NoWrap);
       
  1451     QVERIFY(ed->wordWrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere);
       
  1452     QVERIFY(ed->document()->defaultTextOption().wrapMode() == QTextOption::NoWrap);
       
  1453 }
       
  1454 
       
  1455 void tst_QPlainTextEdit::selectionChanged()
       
  1456 {
       
  1457     ed->setPlainText("Hello World");
       
  1458 
       
  1459     ed->moveCursor(QTextCursor::Start);
       
  1460 
       
  1461     QSignalSpy selectionChangedSpy(ed, SIGNAL(selectionChanged()));
       
  1462 
       
  1463     QTest::keyClick(ed, Qt::Key_Right);
       
  1464     QCOMPARE(ed->textCursor().position(), 1);
       
  1465     QCOMPARE(selectionChangedSpy.count(), 0);
       
  1466 
       
  1467     QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
       
  1468     QCOMPARE(ed->textCursor().position(), 2);
       
  1469     QCOMPARE(selectionChangedSpy.count(), 1);
       
  1470 
       
  1471     QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
       
  1472     QCOMPARE(ed->textCursor().position(), 3);
       
  1473     QCOMPARE(selectionChangedSpy.count(), 2);
       
  1474 
       
  1475     QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
       
  1476     QCOMPARE(ed->textCursor().position(), 4);
       
  1477     QCOMPARE(selectionChangedSpy.count(), 3);
       
  1478 
       
  1479     QTest::keyClick(ed, Qt::Key_Right);
       
  1480     QCOMPARE(ed->textCursor().position(), 5);
       
  1481     QCOMPARE(selectionChangedSpy.count(), 4);
       
  1482 
       
  1483     QTest::keyClick(ed, Qt::Key_Right);
       
  1484     QCOMPARE(ed->textCursor().position(), 6);
       
  1485     QCOMPARE(selectionChangedSpy.count(), 4);
       
  1486 }
       
  1487 
       
  1488 void tst_QPlainTextEdit::blockCountChanged()
       
  1489 {
       
  1490     QSignalSpy blockCountCpangedSpy(ed, SIGNAL(blockCountChanged(int)));
       
  1491     ed->setPlainText("Hello");
       
  1492     QCOMPARE(blockCountCpangedSpy.count(), 0);
       
  1493     ed->setPlainText("Hello World");
       
  1494     QCOMPARE(blockCountCpangedSpy.count(), 0);
       
  1495     ed->setPlainText("Hello \n World \n this \n has \n more \n blocks \n than \n just \n one");
       
  1496     QCOMPARE(blockCountCpangedSpy.count(), 1);
       
  1497     ed->setPlainText("One");
       
  1498     QCOMPARE(blockCountCpangedSpy.count(), 2);
       
  1499     ed->setPlainText("One \n Two");
       
  1500     QCOMPARE(blockCountCpangedSpy.count(), 3);
       
  1501     ed->setPlainText("Three \n Four");
       
  1502     QCOMPARE(blockCountCpangedSpy.count(), 3);
       
  1503 }
       
  1504 
       
  1505 
       
  1506 QTEST_MAIN(tst_QPlainTextEdit)
       
  1507 #include "tst_qplaintextedit.moc"