tests/auto/qlineedit/tst_qlineedit.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/auto/qlineedit/tst_qlineedit.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,3536 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include "../../shared/util.h"
+
+#include "qlineedit.h"
+#include "qapplication.h"
+#include "qstringlist.h"
+#include "qstyle.h"
+#include "qvalidator.h"
+#include "qcompleter.h"
+#include "qstandarditemmodel.h"
+
+#ifdef Q_WS_MAC
+#include <Carbon/Carbon.h> // For the random function.
+#include <cstdlib> // For the random function.
+#endif
+
+#include <qlineedit.h>
+#include <qmenu.h>
+#include <qlayout.h>
+#include <qspinbox.h>
+#include <qdebug.h>
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#include "qcommonstyle.h"
+#include "qstyleoption.h"
+
+QT_BEGIN_NAMESPACE
+class QPainter;
+QT_END_NAMESPACE
+
+class StyleOptionTestStyle : public QCommonStyle
+{
+private:
+    bool readOnly;
+
+public:
+    inline StyleOptionTestStyle() : QCommonStyle(), readOnly(false)
+    {
+    }
+
+    inline void setReadOnly(bool readOnly)
+    {
+        this->readOnly = readOnly;
+    }
+
+    inline void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *,
+                                 const QWidget *) const
+    {
+        switch (pe) {
+            case PE_PanelLineEdit:
+            if (readOnly)
+                QVERIFY(opt->state & QStyle::State_ReadOnly);
+            else
+                QVERIFY(!(opt->state & QStyle::State_ReadOnly));
+            break;
+
+            default:
+            break;
+        }
+    }
+};
+
+class tst_QLineEdit : public QObject
+{
+Q_OBJECT
+
+public:
+    enum EventStates { Press, Release, Click };
+
+    tst_QLineEdit();
+    virtual ~tst_QLineEdit();
+
+public slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void init();
+    void cleanup();
+private slots:
+    void getSetCheck();
+    void experimental();
+
+    void upperAndLowercase();
+
+    void setInputMask_data();
+    void setInputMask();
+
+    void inputMask_data();
+    void inputMask();
+
+    void clearInputMask();
+
+    void keypress_inputMask_data();
+    void keypress_inputMask();
+
+    void inputMaskAndValidator_data();
+    void inputMaskAndValidator();
+
+    void hasAcceptableInputMask_data();
+    void hasAcceptableInputMask();
+
+    void hasAcceptableInputValidator();
+
+
+    void redo_data();
+    void redo();
+    void isRedoAvailable();
+
+    void undo_data();
+    void undo();
+    void isUndoAvailable();
+
+    void undo_keypressevents_data();
+    void undo_keypressevents();
+
+    void clear();
+
+    void text_data();
+    void text();
+    void textMask_data();
+    void textMask();
+    void maskCharacter();
+    void maskCharacter_data();
+    void setText();
+
+    void displayText_data();
+    void displayText();
+    void setEchoMode();
+    void echoMode();
+    void passwordEchoOnEdit();
+
+    void maxLength_mask_data();
+    void maxLength_mask();
+
+    void maxLength_data();
+    void maxLength();
+    void setMaxLength();
+
+    void isReadOnly();
+    void setReadOnly();
+
+    void cursorPosition();
+
+    void cursorPositionChanged_data();
+    void cursorPositionChanged();
+
+    void selectedText();
+    void hasSelectedText();
+    void deleteSelectedText();
+
+    void textChangedAndTextEdited();
+    void returnPressed();
+    void returnPressed_maskvalidator_data();
+    void returnPressed_maskvalidator();
+
+    void setValidator();
+    void validator();
+    void clearValidator();
+
+    void setValidator_QIntValidator_data();
+    void setValidator_QIntValidator();
+
+    void frame_data();
+    void frame();
+
+    void leftKeyOnSelectedText();
+
+    void setAlignment_data();
+    void setAlignment();
+    void alignment();
+
+    void isModified();
+    void edited();
+    void setEdited();
+
+    void insert();
+    void setSelection_data();
+    void setSelection();
+
+#ifndef QT_NO_CLIPBOARD
+    void cut();
+    void copy();
+    void paste();
+#endif
+    void maxLengthAndInputMask();
+    void returnPressedKeyEvent();
+
+    void keepSelectionOnTabFocusIn();
+
+    void readOnlyStyleOption();
+
+    void validateOnFocusOut();
+
+    void editInvalidText();
+
+    void charWithAltOrCtrlModifier();
+
+    void inlineCompletion();
+
+    void noTextEditedOnClear();
+
+    void cursor();
+
+    void textMargin_data();
+    void textMargin();
+
+    // task-specific tests:
+    void task180999_focus();
+    void task174640_editingFinished();
+#ifndef QT_NO_COMPLETER
+    void task198789_currentCompletion();
+    void task210502_caseInsensitiveInlineCompletion();
+#endif
+    void task229938_dontEmitChangedWhenTextIsNotChanged();
+    void task233101_cursorPosAfterInputMethod_data();
+    void task233101_cursorPosAfterInputMethod();
+    void task241436_passwordEchoOnEditRestoreEchoMode();
+    void task248948_redoRemovedSelection();
+
+protected slots:
+#ifdef QT3_SUPPORT
+    void lostFocus();
+#endif
+    void editingFinished();
+
+    void onTextChanged( const QString &newString );
+    void onTextEdited( const QString &newString );
+    void onReturnPressed();
+    void onSelectionChanged();
+    void onCursorPositionChanged(int oldpos, int newpos);
+
+private:
+    // keyClicks(..) is moved to QtTestCase
+    void psKeyClick(QWidget *target, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
+    void psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
+
+    bool validInput;
+    QString changed_string;
+    int changed_count;
+    int edited_count;
+    int return_count;
+    int selection_count;
+    int lastCursorPos;
+    int newCursorPos;
+    QLineEdit *testWidget;
+};
+
+typedef QList<int> IntList;
+Q_DECLARE_METATYPE(IntList)
+Q_DECLARE_METATYPE(QLineEdit::EchoMode)
+
+// Testing get/set functions
+void tst_QLineEdit::getSetCheck()
+{
+    QLineEdit obj1;
+    // const QValidator * QLineEdit::validator()
+    // void QLineEdit::setValidator(const QValidator *)
+    QIntValidator *var1 = new QIntValidator(0);
+    obj1.setValidator(var1);
+    QCOMPARE((const QValidator *)var1, obj1.validator());
+    obj1.setValidator((QValidator *)0);
+    QCOMPARE((const QValidator *)0, obj1.validator());
+    delete var1;
+
+    // bool QLineEdit::dragEnabled()
+    // void QLineEdit::setDragEnabled(bool)
+    obj1.setDragEnabled(false);
+    QCOMPARE(false, obj1.dragEnabled());
+    obj1.setDragEnabled(true);
+    QCOMPARE(true, obj1.dragEnabled());
+}
+
+tst_QLineEdit::tst_QLineEdit()
+{
+    validInput = false;
+}
+
+tst_QLineEdit::~tst_QLineEdit()
+{
+}
+
+void tst_QLineEdit::initTestCase()
+{
+    testWidget = new QLineEdit(0);
+    testWidget->setObjectName("testWidget");
+    connect(testWidget, SIGNAL(cursorPositionChanged(int, int)), this, SLOT(onCursorPositionChanged(int, int)));
+    connect(testWidget, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
+    connect(testWidget, SIGNAL(textEdited(const QString&)), this, SLOT(onTextEdited(const QString&)));
+    connect(testWidget, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
+    connect(testWidget, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
+    connect(testWidget, SIGNAL(editingFinished()), this, SLOT(editingFinished()));
+#ifdef QT3_SUPPORT
+    connect(testWidget, SIGNAL(lostFocus()), this, SLOT(lostFocus()));
+#endif
+
+    testWidget->resize(200,50);
+    testWidget->show();
+    QApplication::setActiveWindow(testWidget);
+#ifdef Q_WS_X11
+    // to be safe and avoid failing setFocus with window managers
+    qt_x11_wait_for_window_manager(testWidget);
+#endif
+    QTRY_VERIFY(testWidget->hasFocus());
+
+    changed_count = 0;
+    edited_count = 0;
+    selection_count = 0;
+}
+
+void tst_QLineEdit::cleanupTestCase()
+{
+    delete testWidget;
+}
+
+void tst_QLineEdit::init()
+{
+    return_count = 0;
+    testWidget->clear();
+    testWidget->setEchoMode(QLineEdit::Normal);
+    testWidget->setMaxLength(32767);
+    testWidget->setReadOnly(false);
+    testWidget->setText("");
+    testWidget->setInputMask("");
+    testWidget->setFrame(true);
+    testWidget->setValidator(0);
+    testWidget->setDragEnabled(true);
+}
+
+void tst_QLineEdit::cleanup()
+{
+}
+
+void tst_QLineEdit::experimental()
+{
+    QIntValidator intValidator(3, 7, 0);
+    testWidget->setValidator(&intValidator);
+    testWidget->setText("");
+
+
+    // test the order of setting these
+    testWidget->setInputMask("");
+    testWidget->setText("abc123");
+    testWidget->setInputMask("000.000.000.000");
+    QCOMPARE(testWidget->text(), QString("123..."));
+    testWidget->setText("");
+
+
+}
+
+void tst_QLineEdit::upperAndLowercase()
+{
+    testWidget->setInputMask("");
+    testWidget->setText("");
+
+    QTest::keyClicks(testWidget, "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?");
+    qApp->processEvents();
+    QCOMPARE(testWidget->text(), QString("aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?"));
+}
+
+void tst_QLineEdit::setInputMask_data()
+{
+    QTest::addColumn<QString>("mask");
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<QString>("expectedText");
+    QTest::addColumn<QString>("expectedDisplay");
+    QTest::addColumn<bool>("insert_text");
+
+    // both keyboard and insert()
+    for (int i=0; i<2; i++) {
+        bool insert_text = i==0 ? false : true;
+        QString insert_mode = "keys ";
+        if (insert_text)
+            insert_mode = "insert ";
+
+        QTest::newRow(QString(insert_mode + "ip_localhost").toLatin1())
+            << QString("000.000.000.000")
+            << QString("127.0.0.1")
+            << QString("127.0.0.1")
+            << QString("127.0  .0  .1  ")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "mac").toLatin1())
+            << QString("HH:HH:HH:HH:HH:HH;#")
+            << QString("00:E0:81:21:9E:8E")
+            << QString("00:E0:81:21:9E:8E")
+            << QString("00:E0:81:21:9E:8E")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "mac2").toLatin1())
+            << QString("<HH:>HH:!HH:HH:HH:HH;#")
+            << QString("AAe081219E8E")
+            << QString("aa:E0:81:21:9E:8E")
+            << QString("aa:E0:81:21:9E:8E")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "byte").toLatin1())
+            << QString("BBBBBBBB;0")
+            << QString("11011001")
+            << QString("11111")
+            << QString("11011001")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "halfbytes").toLatin1())
+            << QString("bbbb.bbbb;-")
+            << QString("110. 0001")
+            << QString("110.0001")
+            << QString("110-.0001")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "blank char same type as content").toLatin1())
+            << QString("000.000.000.000;0")
+            << QString("127.0.0.1")
+            << QString("127...1")
+            << QString("127.000.000.100")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "parts of ip_localhost").toLatin1())
+            << QString("000.000.000.000")
+            << QString(".0.0.1")
+            << QString(".0.0.1")
+            << QString("   .0  .0  .1  ")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "ip_null").toLatin1())
+            << QString("000.000.000.000")
+            << QString()
+            << QString("...")
+            << QString("   .   .   .   ")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "ip_null_hash").toLatin1())
+            << QString("000.000.000.000;#")
+            << QString()
+            << QString("...")
+            << QString("###.###.###.###")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "ip_overflow").toLatin1())
+            << QString("000.000.000.000")
+            << QString("1234123412341234")
+            << QString("123.412.341.234")
+            << QString("123.412.341.234")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "uppercase").toLatin1())
+            << QString(">AAAA")
+            << QString("AbCd")
+            << QString("ABCD")
+            << QString("ABCD")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "lowercase").toLatin1())
+            << QString("<AAAA")
+            << QString("AbCd")
+            << QString("abcd")
+            << QString("abcd")
+            << bool(insert_text);
+
+        QTest::newRow(QString(insert_mode + "nocase").toLatin1())
+            << QString("!AAAA")
+            << QString("AbCd")
+            << QString("AbCd")
+            << QString("AbCd")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "nocase1").toLatin1())
+            << QString("!A!A!A!A")
+            << QString("AbCd")
+            << QString("AbCd")
+            << QString("AbCd")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "nocase2").toLatin1())
+            << QString("AAAA")
+            << QString("AbCd")
+            << QString("AbCd")
+            << QString("AbCd")
+            << bool(insert_text);
+
+        QTest::newRow(QString(insert_mode + "reserved").toLatin1())
+            << QString("{n}[0]")
+            << QString("A9")
+            << QString("A9")
+            << QString("A9")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "escape01").toLatin1())
+            << QString("\\N\\n00")
+            << QString("9")
+            << QString("Nn9")
+            << QString("Nn9 ")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "escape02").toLatin1())
+            << QString("\\\\00")
+            << QString("0")
+            << QString("\\0")
+            << QString("\\0 ")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "escape03").toLatin1())
+            << QString("\\(00\\)")
+            << QString("0")
+            << QString("(0)")
+            << QString("(0 )")
+            << bool(insert_text);
+
+        QTest::newRow(QString(insert_mode + "upper_lower_nocase1").toLatin1())
+            << QString(">AAAA<AAAA!AAAA")
+            << QString("AbCdEfGhIjKl")
+            << QString("ABCDefghIjKl")
+            << QString("ABCDefghIjKl")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "upper_lower_nocase2").toLatin1())
+            << QString(">aaaa<aaaa!aaaa")
+            << QString("AbCdEfGhIjKl")
+            << QString("ABCDefghIjKl")
+            << QString("ABCDefghIjKl")
+            << bool(insert_text);
+
+        QTest::newRow(QString(insert_mode + "exact_case1").toLatin1())
+            << QString(">A<A<A>A>A<A!A!A")
+            << QString("AbCdEFGH")
+            << QString("AbcDEfGH")
+            << QString("AbcDEfGH")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "exact_case2").toLatin1())
+            << QString(">A<A<A>A>A<A!A!A")
+            << QString("aBcDefgh")
+            << QString("AbcDEfgh")
+            << QString("AbcDEfgh")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "exact_case3").toLatin1())
+            << QString(">a<a<a>a>a<a!a!a")
+            << QString("AbCdEFGH")
+            << QString("AbcDEfGH")
+            << QString("AbcDEfGH")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "exact_case4").toLatin1())
+            << QString(">a<a<a>a>a<a!a!a")
+            << QString("aBcDefgh")
+            << QString("AbcDEfgh")
+            << QString("AbcDEfgh")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "exact_case5").toLatin1())
+            << QString(">H<H<H>H>H<H!H!H")
+            << QString("aBcDef01")
+            << QString("AbcDEf01")
+            << QString("AbcDEf01")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "exact_case6").toLatin1())
+            << QString(">h<h<h>h>h<h!h!h")
+            << QString("aBcDef92")
+            << QString("AbcDEf92")
+            << QString("AbcDEf92")
+            << bool(insert_text);
+
+        QTest::newRow(QString(insert_mode + "illegal_keys1").toLatin1())
+            << QString("AAAAAAAA")
+            << QString("A2#a;.0!")
+            << QString("Aa")
+            << QString("Aa      ")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "illegal_keys2").toLatin1())
+            << QString("AAAA")
+            << QString("f4f4f4f4")
+            << QString("ffff")
+            << QString("ffff")
+            << bool(insert_text);
+        QTest::newRow(QString(insert_mode + "blank=input").toLatin1())
+            << QString("9999;0")
+            << QString("2004")
+            << QString("2004")
+            << QString("2004")
+            << bool(insert_text);
+    }
+}
+
+void tst_QLineEdit::setInputMask()
+{
+    QFETCH(QString, mask);
+    QFETCH(QString, input);
+    QFETCH(QString, expectedText);
+    QFETCH(QString, expectedDisplay);
+    QFETCH(bool, insert_text);
+
+    QEXPECT_FAIL( "keys blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
+    QEXPECT_FAIL( "insert blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
+
+    // First set the input mask
+    testWidget->setInputMask(mask);
+
+    // then either insert using insert() or keyboard
+    if (insert_text) {
+        testWidget->insert(input);
+    } else {
+        psKeyClick(testWidget, Qt::Key_Home);
+        for (int i=0; i<input.length(); i++)
+            QTest::keyClick(testWidget, input.at(i).toLatin1());
+    }
+
+    QCOMPARE(testWidget->text(), expectedText);
+    QCOMPARE(testWidget->displayText(), expectedDisplay);
+}
+
+void tst_QLineEdit::inputMask_data()
+{
+    QTest::addColumn<QString>("mask");
+    QTest::addColumn<QString>("expectedMask");
+
+    // if no mask is set a nul string should be returned
+    QTest::newRow("") << QString("") << QString();
+    QTest::newRow("") << QString() << QString();
+
+    // try different masks
+    QTest::newRow("") << QString("000.000.000.000") << QString("000.000.000.000; ");
+    QTest::newRow("") << QString("000.000.000.000;#") << QString("000.000.000.000;#");
+    QTest::newRow("") << QString("AAA.aa.999.###;") << QString("AAA.aa.999.###; ");
+    QTest::newRow("") << QString(">abcdef<GHIJK") << QString(">abcdef<GHIJK; ");
+//    QTest::newRow("") << QString() << QString();
+
+    // set an invalid input mask...
+    // the current behaviour is that this exact (faulty) string is returned.
+    QTest::newRow("") << QString("ABCDEFGHIKLMNOP;") << QString("ABCDEFGHIKLMNOP; ");
+
+    // verify that we can unset the mask again
+    QTest::newRow("") << QString("") << QString();
+}
+
+void tst_QLineEdit::inputMask()
+{
+    QFETCH(QString, mask);
+    QFETCH(QString, expectedMask);
+
+    testWidget->setInputMask(mask);
+    QCOMPARE(testWidget->inputMask(), expectedMask);
+}
+
+void tst_QLineEdit::clearInputMask()
+{
+    testWidget->setInputMask("000.000.000.000");
+    QVERIFY(testWidget->inputMask() != QString::null);
+    testWidget->setInputMask(QString::null);
+    QCOMPARE(testWidget->inputMask(), QString());
+}
+
+void tst_QLineEdit::keypress_inputMask_data()
+{
+    QTest::addColumn<QString>("mask");
+    QTest::addColumn<QTestEventList>("keys");
+    QTest::addColumn<QString>("expectedText");
+    QTest::addColumn<QString>("expectedDisplayText");
+
+    {
+        QTestEventList keys;
+        // inserting 'A1.2B'
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_A);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_Period);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_B);
+        QTest::newRow("jumping on period(separator)") << QString("000.000;_") << keys << QString("1.2") << QString("1__.2__");
+    }
+    {
+        QTestEventList keys;
+        // inserting 'A1.2B'
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_0);
+        keys.addKeyClick(Qt::Key_Exclam);
+        keys.addKeyClick('P');
+        keys.addKeyClick(Qt::Key_3);
+        QTest::newRow("jumping on input") << QString("D0.AA.XX.AA.00;_") << keys << QString("0..!P..3") << QString("_0.__.!P.__.3_");
+    }
+    {
+        QTestEventList keys;
+        // pressing delete
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_Delete);
+        QTest::newRow("delete") << QString("000.000;_") << keys << QString(".") << QString("___.___");
+    }
+    {
+        QTestEventList keys;
+        // selecting all and delete
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_End, Qt::ShiftModifier);
+        keys.addKeyClick(Qt::Key_Delete);
+        QTest::newRow("deleting all") << QString("000.000;_") << keys << QString(".") << QString("___.___");
+    }
+    {
+        QTestEventList keys;
+        // inserting '12.12' then two backspaces
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_Period);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_Backspace);
+        keys.addKeyClick(Qt::Key_Backspace);
+        QTest::newRow("backspace") << QString("000.000;_") << keys << QString("12.") << QString("12_.___");
+    }
+    {
+        QTestEventList keys;
+        // inserting '12ab'
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_A);
+        keys.addKeyClick(Qt::Key_B);
+        QTest::newRow("uppercase") << QString("9999 >AA;_") << keys << QString("12 AB") << QString("12__ AB");
+    }
+}
+
+void tst_QLineEdit::keypress_inputMask()
+{
+    QFETCH(QString, mask);
+    QFETCH(QTestEventList, keys);
+    QFETCH(QString, expectedText);
+    QFETCH(QString, expectedDisplayText);
+
+    testWidget->setInputMask(mask);
+    keys.simulate(testWidget);
+
+    QCOMPARE(testWidget->text(), expectedText);
+    QCOMPARE(testWidget->displayText(), expectedDisplayText);
+}
+
+
+void tst_QLineEdit::hasAcceptableInputMask_data()
+{
+    QTest::addColumn<QString>("optionalMask");
+    QTest::addColumn<QString>("requiredMask");
+    QTest::addColumn<QString>("invalid");
+    QTest::addColumn<QString>("valid");
+
+    QTest::newRow("Alphabetic optional and required")
+        << QString("aaaa") << QString("AAAA") << QString("ab") << QString("abcd");
+    QTest::newRow("Alphanumeric optional and require")
+        << QString("nnnn") << QString("NNNN") << QString("R2") << QString("R2D2");
+    QTest::newRow("Any optional and required")
+        << QString("xxxx") << QString("XXXX") << QString("+-") << QString("+-*/");
+    QTest::newRow("Numeric (0-9) required")
+        << QString("0000") << QString("9999") << QString("11") << QString("1138");
+    QTest::newRow("Numeric (1-9) optional and required")
+        << QString("dddd") << QString("DDDD") << QString("12") << QString("1234");
+}
+
+void tst_QLineEdit::hasAcceptableInputMask()
+{
+    QFocusEvent lostFocus(QEvent::FocusOut);
+    QFETCH(QString, optionalMask);
+    QFETCH(QString, requiredMask);
+    QFETCH(QString, invalid);
+    QFETCH(QString, valid);
+
+    // test that invalid input (for required) work for optionalMask
+    testWidget->setInputMask(optionalMask);
+    validInput = false;
+    testWidget->setText(invalid);
+    qApp->sendEvent(testWidget, &lostFocus);
+    QVERIFY(validInput);
+
+    // at the moment we don't strip the blank character if it is valid input, this makes the test between x vs X useless
+    QEXPECT_FAIL( "Any optional and required", "To eat blanks or not? Known issue. Task 43172", Abort);
+
+    // test requiredMask
+    testWidget->setInputMask(requiredMask);
+    validInput = true;
+    testWidget->setText(invalid);
+    validInput = testWidget->hasAcceptableInput();
+    QVERIFY(!validInput);
+
+    validInput = false;
+    testWidget->setText(valid);
+    qApp->sendEvent(testWidget, &lostFocus);
+    QVERIFY(validInput);
+}
+
+static const int chars = 8;
+class ValidatorWithFixup : public QValidator
+{
+public:
+    ValidatorWithFixup(QWidget *parent = 0)
+        : QValidator(parent)
+    {}
+
+    QValidator::State validate(QString &str, int &) const
+    {
+        const int s = str.size();
+        if (s < chars) {
+            return Intermediate;
+        } else if (s > chars) {
+            return Invalid;
+        }
+        return Acceptable;
+    }
+
+    void fixup(QString &str) const
+    {
+        str = str.leftJustified(chars, 'X', true);
+    }
+};
+
+
+
+void tst_QLineEdit::hasAcceptableInputValidator()
+{
+    QFocusEvent lostFocus(QEvent::FocusOut);
+    ValidatorWithFixup val;
+    testWidget->setValidator(&val);
+    testWidget->setText("foobar");
+    qApp->sendEvent(testWidget, &lostFocus);
+    QVERIFY(testWidget->hasAcceptableInput());
+}
+
+
+
+void tst_QLineEdit::maskCharacter_data()
+{
+    QTest::addColumn<QString>("mask");
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<bool>("expectedValid");
+
+    QTest::newRow("Hex") << QString("H")
+                         << QString("0123456789abcdefABCDEF") << true;
+    QTest::newRow("hex") << QString("h")
+                         << QString("0123456789abcdefABCDEF") << true;
+    QTest::newRow("HexInvalid") << QString("H")
+                                << QString("ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ")
+                                << false;
+    QTest::newRow("hexInvalid") << QString("h")
+                                << QString("ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ")
+                                << false;
+    QTest::newRow("Bin") << QString("B")
+                         << QString("01") << true;
+    QTest::newRow("bin") << QString("b")
+                         << QString("01") << true;
+    QTest::newRow("BinInvalid") << QString("B")
+                                << QString("23456789qwertyuiopasdfghjklzxcvbnm")
+                                << false;
+    QTest::newRow("binInvalid") << QString("b")
+                                << QString("23456789qwertyuiopasdfghjklzxcvbnm")
+                                << false;
+}
+
+void tst_QLineEdit::maskCharacter()
+{
+    QFETCH(QString, mask);
+    QFETCH(QString, input);
+    QFETCH(bool, expectedValid);
+
+    QFocusEvent lostFocus(QEvent::FocusOut);
+
+    testWidget->setInputMask(mask);
+    for (int i = 0; i < input.size(); ++i) {
+        QString in = QString(input.at(i));
+        QString expected = expectedValid ? in : QString();
+        testWidget->setText(QString(input.at(i)));
+        qApp->sendEvent(testWidget, &lostFocus);
+        QCOMPARE(testWidget->text(), expected);
+    }
+}
+
+#define NORMAL 0
+#define REPLACE_UNTIL_END 1
+
+void tst_QLineEdit::undo_data()
+{
+    QTest::addColumn<QStringList>("insertString");
+    QTest::addColumn<IntList>("insertIndex");
+    QTest::addColumn<IntList>("insertMode");
+    QTest::addColumn<QStringList>("expectedString");
+    QTest::addColumn<bool>("use_keys");
+
+    for (int i=0; i<2; i++) {
+        QString keys_str = "keyboard";
+        bool use_keys = true;
+        if (i==0) {
+            keys_str = "insert";
+            use_keys = false;
+        }
+
+        {
+            IntList insertIndex;
+            IntList insertMode;
+            QStringList insertString;
+            QStringList expectedString;
+
+            insertIndex << -1;
+            insertMode << NORMAL;
+            insertString << "1";
+
+            insertIndex << -1;
+            insertMode << NORMAL;
+            insertString << "5";
+
+            insertIndex << 1;
+            insertMode << NORMAL;
+            insertString << "3";
+
+            insertIndex << 1;
+            insertMode << NORMAL;
+            insertString << "2";
+
+            insertIndex << 3;
+            insertMode << NORMAL;
+            insertString << "4";
+
+            expectedString << "12345";
+            expectedString << "1235";
+            expectedString << "135";
+            expectedString << "15";
+            expectedString << "";
+
+            QTest::newRow(QString(keys_str + "_numbers").toLatin1()) <<
+                insertString <<
+                insertIndex <<
+                insertMode <<
+                expectedString <<
+                bool(use_keys);
+        }
+        {
+            IntList insertIndex;
+            IntList insertMode;
+            QStringList insertString;
+            QStringList expectedString;
+
+            insertIndex << -1;
+            insertMode << NORMAL;
+            insertString << "World"; // World
+
+            insertIndex << 0;
+            insertMode << NORMAL;
+            insertString << "Hello"; // HelloWorld
+
+            insertIndex << 0;
+            insertMode << NORMAL;
+            insertString << "Well"; // WellHelloWorld
+
+            insertIndex << 9;
+            insertMode << NORMAL;
+            insertString << "There"; // WellHelloThereWorld;
+
+            expectedString << "WellHelloThereWorld";
+            expectedString << "WellHelloWorld";
+            expectedString << "HelloWorld";
+            expectedString << "World";
+            expectedString << "";
+
+            QTest::newRow(QString(keys_str + "_helloworld").toLatin1()) <<
+                insertString <<
+                insertIndex <<
+                insertMode <<
+                expectedString <<
+                bool(use_keys);
+        }
+        {
+            IntList insertIndex;
+            IntList insertMode;
+            QStringList insertString;
+            QStringList expectedString;
+
+            insertIndex << -1;
+            insertMode << NORMAL;
+            insertString << "Ensuring";
+
+            insertIndex << -1;
+            insertMode << NORMAL;
+            insertString << " instan";
+
+            insertIndex << 9;
+            insertMode << NORMAL;
+            insertString << "an ";
+
+            insertIndex << 10;
+            insertMode << REPLACE_UNTIL_END;
+            insertString << " unique instance.";
+
+            expectedString << "Ensuring a unique instance.";
+            expectedString << "Ensuring an instan";
+            expectedString << "Ensuring instan";
+            expectedString << "";
+
+            QTest::newRow(QString(keys_str + "_patterns").toLatin1()) <<
+                insertString <<
+                insertIndex <<
+                insertMode <<
+                expectedString <<
+                bool(use_keys);
+        }
+    }
+}
+
+void tst_QLineEdit::undo()
+{
+    QFETCH(QStringList, insertString);
+    QFETCH(IntList, insertIndex);
+    QFETCH(IntList, insertMode);
+    QFETCH(QStringList, expectedString);
+    QFETCH(bool, use_keys);
+
+    QVERIFY(!testWidget->isUndoAvailable());
+
+    int i;
+
+// STEP 1: First build up an undo history by inserting or typing some strings...
+    for (i=0; i<insertString.size(); ++i) {
+        if (insertIndex[i] > -1)
+            testWidget->setCursorPosition(insertIndex[i]);
+
+ // experimental stuff
+        if (insertMode[i] == REPLACE_UNTIL_END) {
+            testWidget->setSelection(insertIndex[i], 8);
+
+            // This is what I actually want...
+            // QTest::keyClick(testWidget, Qt::Key_End, Qt::ShiftModifier);
+        }
+
+        if (use_keys)
+            QTest::keyClicks(testWidget, insertString[i]);
+        else
+            testWidget->insert(insertString[i]);
+    }
+
+// STEP 2: Next call undo several times and see if we can restore to the previous state
+    for (i=0; i<expectedString.size()-1; ++i) {
+        QCOMPARE(testWidget->text(), expectedString[i]);
+        QVERIFY(testWidget->isUndoAvailable());
+        testWidget->undo();
+    }
+
+// STEP 3: Verify that we have undone everything
+    QVERIFY(!testWidget->isUndoAvailable());
+    QVERIFY(testWidget->text().isEmpty());
+
+#ifdef Q_WS_WIN
+    // Repeat the test using shortcut instead of undo()
+    for (i=0; i<insertString.size(); ++i) {
+        if (insertIndex[i] > -1)
+            testWidget->setCursorPosition(insertIndex[i]);
+        if (insertMode[i] == REPLACE_UNTIL_END) {
+            testWidget->setSelection(insertIndex[i], 8);
+        }
+        if (use_keys)
+            QTest::keyClicks(testWidget, insertString[i]);
+        else
+            testWidget->insert(insertString[i]);
+    }
+    for (i=0; i<expectedString.size()-1; ++i) {
+        QCOMPARE(testWidget->text(), expectedString[i]);
+        QVERIFY(testWidget->isUndoAvailable());
+        QTest::keyClick(testWidget, Qt::Key_Backspace, Qt::AltModifier);
+    }
+#endif
+}
+
+void tst_QLineEdit::isUndoAvailable()
+{
+    DEPENDS_ON("undo");
+}
+
+void tst_QLineEdit::redo_data()
+{
+    QTest::addColumn<QStringList>("insertString");
+    QTest::addColumn<IntList>("insertIndex");
+    QTest::addColumn<QStringList>("expectedString");
+
+    {
+        IntList insertIndex;
+        QStringList insertString;
+        QStringList expectedString;
+
+        insertIndex << -1;
+        insertString << "World"; // World
+        insertIndex << 0;
+        insertString << "Hello"; // HelloWorld
+        insertIndex << 0;
+        insertString << "Well"; // WellHelloWorld
+        insertIndex << 9;
+        insertString << "There"; // WellHelloThereWorld;
+
+        expectedString << "World";
+        expectedString << "HelloWorld";
+        expectedString << "WellHelloWorld";
+        expectedString << "WellHelloThereWorld";
+
+        QTest::newRow("Inserts and setting cursor") << insertString << insertIndex << expectedString;
+    }
+}
+
+void tst_QLineEdit::redo()
+{
+    QFETCH(QStringList, insertString);
+    QFETCH(IntList, insertIndex);
+    QFETCH(QStringList, expectedString);
+
+    QVERIFY(!testWidget->isUndoAvailable());
+    QVERIFY(!testWidget->isRedoAvailable());
+
+    int i;
+    // inserts the diff strings at diff positions
+    for (i=0; i<insertString.size(); ++i) {
+        if (insertIndex[i] > -1)
+            testWidget->setCursorPosition(insertIndex[i]);
+        testWidget->insert(insertString[i]);
+    }
+
+    QVERIFY(!testWidget->isRedoAvailable());
+
+    // undo everything
+    while (!testWidget->text().isEmpty())
+        testWidget->undo();
+
+    for (i=0; i<expectedString.size(); ++i) {
+        QVERIFY(testWidget->isRedoAvailable());
+        testWidget->redo();
+        QCOMPARE(testWidget->text() , expectedString[i]);
+    }
+
+    QVERIFY(!testWidget->isRedoAvailable());
+
+#ifdef Q_WS_WIN
+    // repeat test, this time using shortcuts instead of undo()/redo()
+
+    while (!testWidget->text().isEmpty())
+        QTest::keyClick(testWidget, Qt::Key_Backspace, Qt::AltModifier);
+
+    for (i = 0; i < expectedString.size(); ++i) {
+        QVERIFY(testWidget->isRedoAvailable());
+        QTest::keyClick(testWidget, Qt::Key_Backspace,
+                        Qt::ShiftModifier | Qt::AltModifier);
+        QCOMPARE(testWidget->text() , expectedString[i]);
+    }
+
+    QVERIFY(!testWidget->isRedoAvailable());
+#endif
+}
+
+void tst_QLineEdit::isRedoAvailable()
+{
+    DEPENDS_ON("redo");
+}
+
+void tst_QLineEdit::undo_keypressevents_data()
+{
+    QTest::addColumn<QTestEventList>("keys");
+    QTest::addColumn<QStringList>("expectedString");
+
+    {
+        QTestEventList keys;
+        QStringList expectedString;
+
+        keys.addKeyClick('A');
+        keys.addKeyClick('F');
+        keys.addKeyClick('R');
+        keys.addKeyClick('A');
+        keys.addKeyClick('I');
+        keys.addKeyClick('D');
+        psKeyClick(keys, Qt::Key_Home);
+
+        keys.addKeyClick('V');
+        keys.addKeyClick('E');
+        keys.addKeyClick('R');
+        keys.addKeyClick('Y');
+
+        keys.addKeyClick(Qt::Key_Left);
+        keys.addKeyClick(Qt::Key_Left);
+        keys.addKeyClick(Qt::Key_Left);
+        keys.addKeyClick(Qt::Key_Left);
+
+        keys.addKeyClick('B');
+        keys.addKeyClick('E');
+        psKeyClick(keys, Qt::Key_End);
+
+        keys.addKeyClick(Qt::Key_Exclam);
+
+        expectedString << "BEVERYAFRAID!";
+        expectedString << "BEVERYAFRAID";
+        expectedString << "VERYAFRAID";
+        expectedString << "AFRAID";
+
+        QTest::newRow("Inserts and moving cursor") << keys << expectedString;
+    }
+
+    {
+        QTestEventList keys;
+        QStringList expectedString;
+
+        // inserting '1234'
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_3);
+        keys.addKeyClick(Qt::Key_4);
+        psKeyClick(keys, Qt::Key_Home);
+
+        // skipping '12'
+        keys.addKeyClick(Qt::Key_Right);
+        keys.addKeyClick(Qt::Key_Right);
+
+        // selecting '34'
+        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
+        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
+
+        // deleting '34'
+        keys.addKeyClick(Qt::Key_Delete);
+
+        expectedString << "12";
+        expectedString << "1234";
+
+        QTest::newRow("Inserts,moving,selection and delete") << keys << expectedString;
+    }
+
+    {
+        QTestEventList keys;
+        QStringList expectedString;
+
+        // inserting 'AB12'
+        keys.addKeyClick('A');
+        keys.addKeyClick('B');
+
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+
+        psKeyClick(keys, Qt::Key_Home);
+
+        // selecting 'AB'
+        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
+        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
+
+        // deleting 'AB'
+        keys.addKeyClick(Qt::Key_Delete);
+
+        // undoing deletion of 'AB'
+        keys.addKeyClick(Qt::Key_Z, Qt::ControlModifier);
+
+        // unselect any current selection
+        keys.addKeyClick(Qt::Key_Right);
+#ifdef Q_WS_WIN //Mac has a specialcase to handle jumping to the end of a selection
+        keys.addKeyClick(Qt::Key_Left);
+#endif
+
+        // selecting '12'
+        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
+        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
+
+        // deleting '12'
+        keys.addKeyClick(Qt::Key_Delete);
+
+        expectedString << "AB";
+        expectedString << "AB12";
+
+        QTest::newRow("Inserts,moving,selection, delete and undo") << keys << expectedString;
+    }
+
+    {
+        QTestEventList keys;
+        QStringList expectedString;
+
+        // inserting 'ABCD'
+        keys.addKeyClick(Qt::Key_A);
+        keys.addKeyClick(Qt::Key_B);
+        keys.addKeyClick(Qt::Key_C);
+        keys.addKeyClick(Qt::Key_D);
+
+        //move left two
+        keys.addKeyClick(Qt::Key_Left);
+        keys.addKeyClick(Qt::Key_Left);
+
+        // inserting '1234'
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_3);
+        keys.addKeyClick(Qt::Key_4);
+
+        // selecting '1234'
+        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
+        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
+        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
+        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
+
+        // overwriting '1234' with '5'
+        keys.addKeyClick(Qt::Key_5);
+
+        // undoing deletion of 'AB'
+        keys.addKeyClick(Qt::Key_Z, Qt::ControlModifier);
+
+        // overwriting '1234' with '6'
+        keys.addKeyClick(Qt::Key_6);
+
+        expectedString << "ab6cd";
+        // for versions previous to 3.2 we overwrite needed two undo operations
+        expectedString << "ab1234cd";
+        expectedString << "abcd";
+
+        QTest::newRow("Inserts,moving,selection and undo, removing selection") << keys << expectedString;
+    }
+
+    {
+        QTestEventList keys;
+        QStringList expectedString;
+
+        // inserting 'ABC'
+        keys.addKeyClick('A');
+        keys.addKeyClick('B');
+        keys.addKeyClick('C');
+
+        // removes 'C'
+        keys.addKeyClick(Qt::Key_Backspace);
+
+        expectedString << "AB";
+        expectedString << "ABC";
+
+        QTest::newRow("Inserts,backspace") << keys << expectedString;
+    }
+
+    {
+        QTestEventList keys;
+        QStringList expectedString;
+
+        // inserting 'ABC'
+        keys.addKeyClick('A');
+        keys.addKeyClick('B');
+        keys.addKeyClick('C');
+
+        // removes 'C'
+        keys.addKeyClick(Qt::Key_Backspace);
+
+        // inserting 'Z'
+        keys.addKeyClick('Z');
+
+        expectedString << "ABZ";
+        expectedString << "AB";
+        expectedString << "ABC";
+
+        QTest::newRow("Inserts,backspace,inserts") << keys << expectedString;
+    }
+
+
+    {
+        QTestEventList keys;
+        QStringList expectedString;
+
+        // inserting '123'
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_3);
+        psKeyClick(keys, Qt::Key_Home);
+
+        // selecting '123'
+        psKeyClick(keys, Qt::Key_End, Qt::ShiftModifier);
+
+        // overwriting '123' with 'ABC'
+        keys.addKeyClick('A');
+        keys.addKeyClick('B');
+        keys.addKeyClick('C');
+
+        expectedString << "ABC";
+        // for versions previous to 3.2 we overwrite needed two undo operations
+        expectedString << "123";
+
+        QTest::newRow("Inserts,moving,selection and overwriting") << keys << expectedString;
+    }
+}
+
+void tst_QLineEdit::undo_keypressevents()
+{
+    QFETCH(QTestEventList, keys);
+    QFETCH(QStringList, expectedString);
+
+    keys.simulate(testWidget);
+
+    for (int i=0; i<expectedString.size(); ++i) {
+        QCOMPARE(testWidget->text() , expectedString[i]);
+        testWidget->undo();
+    }
+    QVERIFY(testWidget->text().isEmpty());
+}
+
+void tst_QLineEdit::clear()
+{
+    // checking that clear of empty/nullstring doesn't add to undo history
+    int max = 5000;
+    while (max > 0 && testWidget->isUndoAvailable()) {
+        max--;
+        testWidget->undo();
+    }
+
+    testWidget->clear();
+//    QVERIFY(!testWidget->isUndoAvailable());
+
+    // checks that clear actually clears
+    testWidget->insert("I am Legend");
+    testWidget->clear();
+    QVERIFY(testWidget->text().isEmpty());
+
+    // checks that clears can be undone
+    testWidget->undo();
+    QCOMPARE(testWidget->text(), QString("I am Legend"));
+}
+
+#ifdef QT3_SUPPORT
+void tst_QLineEdit::lostFocus()
+{
+    editingFinished();
+}
+#endif
+void tst_QLineEdit::editingFinished()
+{
+    if (testWidget->hasAcceptableInput())
+        validInput = true;
+    else
+        validInput = false;
+}
+
+void tst_QLineEdit::text_data()
+{
+    QTest::addColumn<QString>("insertString");
+
+    QTest::newRow("Plain text0") << QString("Hello World");
+    QTest::newRow("Plain text1") << QString("");
+    QTest::newRow("Plain text2") << QString("A");
+    QTest::newRow("Plain text3") << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry");
+    QTest::newRow("Plain text4") << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"");
+    QTest::newRow("Newlines") << QString("A\nB\nC\n");
+    QTest::newRow("Text with nbsp") << QString("Hello") + QChar(0xa0) + "World";
+}
+
+void tst_QLineEdit::text()
+{
+    QFETCH(QString, insertString);
+    testWidget->setText(insertString);
+    QCOMPARE(testWidget->text(), insertString);
+}
+
+void tst_QLineEdit::textMask_data()
+{
+    QTest::addColumn<QString>("insertString");
+
+    QTest::newRow( "Plain text1" ) << QString( "" );
+}
+
+void tst_QLineEdit::textMask()
+{
+    QFETCH( QString, insertString );
+    testWidget->setInputMask( "#" );
+    testWidget->setText( insertString );
+    QCOMPARE( testWidget->text(), insertString );
+}
+
+void tst_QLineEdit::setText()
+{
+    QSignalSpy editedSpy(testWidget, SIGNAL(textEdited(QString)));
+    QSignalSpy changedSpy(testWidget, SIGNAL(textChanged(QString)));
+    testWidget->setText("hello");
+    QCOMPARE(editedSpy.count(), 0);
+    QCOMPARE(changedSpy.value(0).value(0).toString(), QString("hello"));
+}
+
+void tst_QLineEdit::displayText_data()
+{
+    QTest::addColumn<QString>("insertString");
+    QTest::addColumn<QString>("expectedString");
+    QTest::addColumn<QLineEdit::EchoMode>("mode");
+    QTest::addColumn<bool>("use_setText");
+
+    QString s;
+    QLineEdit::EchoMode m;
+
+    for (int i=0; i<2; i++) {
+        QString key_mode_str;
+        bool use_setText;
+        if (i==0) {
+            key_mode_str = "setText_";
+            use_setText = true;
+        } else {
+            key_mode_str = "useKeys_";
+            use_setText = false;
+        }
+        s = key_mode_str + "Normal";
+        m = QLineEdit::Normal;
+        QTest::newRow(QString(s + " text0").toLatin1()) << QString("Hello World") <<
+                      QString("Hello World") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
+                      QString("") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") <<
+                      QString("A") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text3").toLatin1()) << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
+                      QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text4").toLatin1()) << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
+                      QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text with nbsp").toLatin1()) << QString("Hello") + QChar(0xa0) + "World" <<
+                      QString("Hello") + QChar(0xa0) + "World" <<
+                      m << bool(use_setText);
+        s = key_mode_str + "NoEcho";
+        m = QLineEdit::NoEcho;
+        QTest::newRow(QString(s + " text0").toLatin1()) << QString("Hello World") <<
+                      QString("") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
+                      QString("") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") <<
+                      QString("") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text3").toLatin1()) << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
+                      QString("") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text4").toLatin1()) << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
+                      QString("") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text with nbsp").toLatin1()) << QString("Hello") + QChar(0xa0) + "World" <<
+                      QString("") <<
+                      m << bool(use_setText);
+        s = key_mode_str + "Password";
+        m = QLineEdit::Password;
+        QChar passChar = qApp->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, 0, testWidget);
+        QString input;
+        QString pass;
+        input = "Hello World";
+        pass.resize(input.length());
+        pass.fill(passChar);
+        QTest::newRow(QString(s + " text0").toLatin1()) << input << pass << m << bool(use_setText);
+        QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
+                      QString("") <<
+                      m << bool(use_setText);
+        QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") << QString(passChar) << m << bool(use_setText);
+        input = QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry");
+        pass.resize(input.length());
+        pass.fill(passChar);
+        QTest::newRow(QString(s + " text3").toLatin1()) << input << pass << m << bool(use_setText);
+        input = QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"");
+        pass.fill(passChar, input.length());
+        QTest::newRow(QString(s + " text4").toLatin1()) << input << pass << m << bool(use_setText);
+        input = QString("Hello") + QChar(0xa0) + "World";
+        pass.resize(input.length());
+        pass.fill(passChar);
+        QTest::newRow(QString(s + " text with nbsp").toLatin1()) << input << pass << m << bool(use_setText);
+    }
+}
+
+void tst_QLineEdit::displayText()
+{
+    QFETCH(QString, insertString);
+    QFETCH(QString, expectedString);
+    QFETCH(QLineEdit::EchoMode, mode);
+    //QFETCH(bool, use_setText);  Currently unused.
+
+    testWidget->setEchoMode(mode);
+    testWidget->setText(insertString);
+    QCOMPARE(testWidget->displayText(), expectedString);
+    QVERIFY(testWidget->echoMode() == mode);
+}
+
+void tst_QLineEdit::setEchoMode()
+{
+    DEPENDS_ON("displayText");
+}
+
+void tst_QLineEdit::echoMode()
+{
+    DEPENDS_ON("displayText");
+}
+
+void tst_QLineEdit::passwordEchoOnEdit()
+{
+    QStyleOptionFrameV2 opt;
+    QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
+
+    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
+    testWidget->setFocus();
+    testWidget->raise();
+    QTRY_VERIFY(testWidget->hasFocus());
+
+    QTest::keyPress(testWidget, '0');
+    QTest::keyPress(testWidget, '1');
+    QTest::keyPress(testWidget, '2');
+    QTest::keyPress(testWidget, '3');
+    QTest::keyPress(testWidget, '4');
+    QCOMPARE(testWidget->displayText(), QString("01234"));
+    testWidget->clearFocus();
+    QVERIFY(!testWidget->hasFocus());
+    QCOMPARE(testWidget->displayText(), QString(5, fillChar));
+    testWidget->setFocus();
+    QTRY_VERIFY(testWidget->hasFocus());
+
+    QCOMPARE(testWidget->displayText(), QString(5, fillChar));
+    QTest::keyPress(testWidget, '0');
+    QCOMPARE(testWidget->displayText(), QString("0"));
+
+    // restore clean state
+    testWidget->setEchoMode(QLineEdit::Normal);
+}
+
+void tst_QLineEdit::maxLength_mask_data()
+{
+    QTest::addColumn<QString>("mask");
+    QTest::addColumn<int>("expectedLength");
+
+    QTest::newRow("mask_case") << QString(">000<>00<000") << 8;
+    QTest::newRow("mask_nocase") << QString("00000000") << 8;
+    QTest::newRow("mask_null") << QString() << 32767;
+    QTest::newRow("mask_escape") << QString("\\A\\aAA") << 4;
+}
+
+void tst_QLineEdit::maxLength_mask()
+{
+    QFETCH(QString, mask);
+    QFETCH(int, expectedLength);
+
+    testWidget->setInputMask(mask);
+
+    QCOMPARE(testWidget->maxLength(), expectedLength);
+}
+
+void tst_QLineEdit::maxLength_data()
+{
+    QTest::addColumn<QString>("insertString");
+    QTest::addColumn<QString>("expectedString");
+    QTest::addColumn<int>("length");
+    QTest::addColumn<bool>("insertBeforeSettingMaxLength");
+    QTest::addColumn<bool>("use_setText");
+
+    QTest::newRow("keyclick before0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(true) << bool(false);
+    QTest::newRow("keyclick before1") << QString("this is a test.") << QString("this is a ") << 10 << bool(true) << bool(false);
+    QTest::newRow("keyclick after0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(false) << bool(false);
+    QTest::newRow("keyclick after1") << QString("this is a test.") << QString("this is a ") << 10 << bool(false) << bool(false);
+    QTest::newRow("settext before0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(true) << bool(true);
+    QTest::newRow("settext before1") << QString("this is a test.") << QString("this is a ") << 10 << bool(true) << bool(true);
+    QTest::newRow("settext after0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(false) << bool(true);
+    QTest::newRow("settext after1") << QString("this is a test.") << QString("this is a ") << 10 << bool(false) << bool(true);
+}
+
+void tst_QLineEdit::maxLength()
+{
+    QFETCH(QString, insertString);
+    QFETCH(QString, expectedString);
+    QFETCH(int, length);
+    QFETCH(bool, insertBeforeSettingMaxLength);
+    QFETCH(bool, use_setText);
+
+    // in some cases we set the maxLength _before_ entering the text.
+    if (!insertBeforeSettingMaxLength)
+        testWidget->setMaxLength(length);
+
+    // I expect MaxLength to work BOTH with entering live characters AND with setting the text.
+    if (use_setText) {
+        // Enter insertString using setText.
+        testWidget->setText(insertString);
+    } else {
+        // Enter insertString as a sequence of keyClicks
+        QTest::keyClicks(testWidget, insertString);
+    }
+
+    // in all other cases we set the maxLength _after_ entering the text.
+    if (insertBeforeSettingMaxLength) {
+        changed_count = 0;
+        testWidget->setMaxLength(length);
+
+        // Make sure that the textChanged is not emitted unless the text is actually changed
+        if (insertString == expectedString) {
+            QVERIFY(changed_count == 0);
+        } else {
+            QVERIFY(changed_count == 1);
+        }
+    }
+
+    // and check if we get the expected string back
+    QCOMPARE(testWidget->text(), expectedString);
+}
+
+void tst_QLineEdit::setMaxLength()
+{
+    DEPENDS_ON("maxLength");
+}
+
+void tst_QLineEdit::isReadOnly()
+{
+    QVERIFY(!testWidget->isReadOnly());
+
+    // start with a basic text
+    QTest::keyClicks(testWidget, "the quick brown fox");
+    QCOMPARE(testWidget->text(), QString("the quick brown fox"));
+
+    // do a quick check to verify that we can indeed edit the text
+    testWidget->home(false);
+    testWidget->cursorForward(false, 10);
+    QTest::keyClicks(testWidget, "dark ");
+    QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
+
+    testWidget->setReadOnly(true);
+    QVERIFY(testWidget->isReadOnly());
+
+    // verify that we cannot edit the text anymore
+    testWidget->home(false);
+    testWidget->cursorForward(false, 10);
+    QTest::keyClick(testWidget, Qt::Key_Delete);
+    QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
+    testWidget->cursorForward(false, 10);
+    QTest::keyClicks(testWidget, "this should not have any effect!! ");
+    QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
+}
+
+void tst_QLineEdit::setReadOnly()
+{
+    DEPENDS_ON("isReadOnly");
+}
+
+static void figureOutProperKey(Qt::Key &key, Qt::KeyboardModifiers &pressState)
+{
+#ifdef Q_WS_MAC
+    static bool tst_lineedit_randomized = false;
+    // Mac has 3 different ways of accomplishing this (same for moving to the back)
+    // So I guess we should just randomly do this for now. Which may get people mad, but if
+    // we fail at one point, it's just a matter of setting roll to the correct value
+    // instead of random.
+
+    if (!tst_lineedit_randomized) {
+        tst_lineedit_randomized = true;
+        ::srandom(ulong(time(0)));
+    }
+    long roll = ::random() % 3;
+    switch (roll) {
+    case 0:
+        key = key == Qt::Key_Home ? Qt::Key_Up : Qt::Key_Down;
+        break;
+    case 1:
+    case 2:
+        key = key == Qt::Key_Home ? Qt::Key_Left : Qt::Key_Right;
+        pressState |= (roll == 1) ? Qt::ControlModifier : Qt::MetaModifier;
+        break;
+    }
+#else
+    // Naively kill the warning.
+    key = key;
+    pressState = pressState;
+#endif
+}
+
+// Platform specific move. Home and End do nothing on the Mac,
+// so do something a bit smarter than tons of #ifdefs
+void tst_QLineEdit::psKeyClick(QWidget *target, Qt::Key key, Qt::KeyboardModifiers pressState)
+{
+    figureOutProperKey(key, pressState);
+    QTest::keyClick(target, key, pressState);
+}
+
+void tst_QLineEdit::psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardModifiers pressState)
+{
+    figureOutProperKey(key, pressState);
+    keys.addKeyClick(key, pressState);
+}
+
+void tst_QLineEdit::cursorPosition()
+{
+    QVERIFY(testWidget->cursorPosition() == 0);
+
+    // start with a basic text
+    QTest::keyClicks(testWidget, "The");
+    QCOMPARE(testWidget->cursorPosition(), 3);
+    QTest::keyClicks(testWidget, " quick");
+    QCOMPARE(testWidget->cursorPosition(), 9);
+    QTest::keyClicks(testWidget, " brown fox jumps over the lazy dog");
+    QCOMPARE(testWidget->cursorPosition(), 43);
+
+    // The text we have now is:
+    //           1         2         3         4         5
+    // 012345678901234567890123456789012345678901234567890
+    // The quick brown fox jumps over the lazy dog
+
+    // next we will check some of the cursor movement functions
+    testWidget->end(false);
+    QCOMPARE(testWidget->cursorPosition() , 43);
+    testWidget->cursorForward(false, -1);
+    QCOMPARE(testWidget->cursorPosition() , 42);
+    testWidget->cursorBackward(false, 1);
+    QCOMPARE(testWidget->cursorPosition() , 41);
+    testWidget->home(false);
+    QCOMPARE(testWidget->cursorPosition() , 0);
+    testWidget->cursorForward(false, 1);
+    QCOMPARE(testWidget->cursorPosition() , 1);
+    testWidget->cursorForward(false, 9);
+    QCOMPARE(testWidget->cursorPosition() , 10);
+    testWidget->cursorWordForward(false); // 'fox'
+    QCOMPARE(testWidget->cursorPosition(), 16);
+    testWidget->cursorWordForward(false); // 'jumps'
+    QCOMPARE(testWidget->cursorPosition(), 20);
+    testWidget->cursorWordBackward(false); // 'fox'
+    QCOMPARE(testWidget->cursorPosition(), 16);
+    testWidget->cursorWordBackward(false); // 'brown'
+    testWidget->cursorWordBackward(false); // 'quick'
+    testWidget->cursorWordBackward(false); // 'The'
+    QCOMPARE(testWidget->cursorPosition(), 0);
+    testWidget->cursorWordBackward(false); // 'The'
+    QCOMPARE(testWidget->cursorPosition(), 0);
+
+    // Cursor position should be 0 here!
+    int i;
+    for (i=0; i<5; i++)
+        QTest::keyClick(testWidget, Qt::Key_Right);
+    QCOMPARE(testWidget->cursorPosition(), 5);
+    psKeyClick(testWidget, Qt::Key_End);
+    QCOMPARE(testWidget->cursorPosition(), 43);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QCOMPARE(testWidget->cursorPosition(), 42);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QCOMPARE(testWidget->cursorPosition(), 41);
+    psKeyClick(testWidget, Qt::Key_Home);
+    QCOMPARE(testWidget->cursorPosition(), 0);
+
+    // cursorposition when maxlength is set
+    int maxLength = 9;
+    testWidget->clear();
+    testWidget->setMaxLength(maxLength);
+    QCOMPARE(testWidget->cursorPosition() , 0);
+    QTest::keyClicks(testWidget, "123ABC123");
+    QCOMPARE(testWidget->cursorPosition() , maxLength);
+    psKeyClick(testWidget, Qt::Key_Home);
+    QCOMPARE(testWidget->cursorPosition() , 0);
+    psKeyClick(testWidget, Qt::Key_End);
+    QCOMPARE(testWidget->cursorPosition() , maxLength);
+}
+
+/* // tested in cursorPosition
+void tst_QLineEdit::cursorLeft()
+void tst_QLineEdit::cursorRight()
+void tst_QLineEdit::cursorForward()
+void tst_QLineEdit::cursorBackward()
+void tst_QLineEdit::cursorWordForward()
+void tst_QLineEdit::cursorWordBackward()
+void tst_QLineEdit::home()
+void tst_QLineEdit::end()
+*/
+
+void tst_QLineEdit::cursorPositionChanged_data()
+{
+    QTest::addColumn<QTestEventList>("input");
+    QTest::addColumn<int>("lastPos");
+    QTest::addColumn<int>("newPos");
+
+    QTestEventList keys;
+    keys.addKeyClick(Qt::Key_A);
+    QTest::newRow("a") << keys << 0 << 1;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    psKeyClick(keys, Qt::Key_Home);
+    QTest::newRow("abc<home>") << keys << 3 << 0;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Left);
+    QTest::newRow("abc<left>") << keys << 3 << 2;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Right);
+    QTest::newRow("abc<right>") << keys << 2 << 3;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    psKeyClick(keys, Qt::Key_Home);
+    keys.addKeyClick(Qt::Key_Right);
+    QTest::newRow("abc<home><right>") << keys << 0 << 1;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Backspace);
+    QTest::newRow("abc<backspace>") << keys << 3 << 2;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Delete);
+    QTest::newRow("abc<delete>") << keys << 2 << 3;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Left);
+    keys.addKeyClick(Qt::Key_Delete);
+    QTest::newRow("abc<left><delete>") << keys << 3 << 2;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    psKeyClick(keys, Qt::Key_Home);
+    psKeyClick(keys, Qt::Key_End);
+    QTest::newRow("abc<home><end>") << keys << 0 << 3;
+    keys.clear();
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Space);
+    keys.addKeyClick(Qt::Key_D);
+    keys.addKeyClick(Qt::Key_E);
+    keys.addKeyClick(Qt::Key_F);
+    keys.addKeyClick(Qt::Key_Home);
+    keys.addKeyClick(Qt::Key_Right, Qt::ControlModifier);
+    QTest::newRow("abc efg<home><ctrl-right>") << keys
+#ifndef Q_WS_MAC
+        << 0 << 4;
+#else
+        << 6 << 7;
+#endif
+    keys.clear();
+
+#ifdef Q_WS_MAC
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Space);
+    keys.addKeyClick(Qt::Key_D);
+    keys.addKeyClick(Qt::Key_E);
+    keys.addKeyClick(Qt::Key_F);
+    keys.addKeyClick(Qt::Key_Up);
+    keys.addKeyClick(Qt::Key_Right, Qt::AltModifier);
+    QTest::newRow("mac equivalent abc efg<up><option-right>") << keys << 0 << 4;
+    keys.clear();
+#endif
+
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Space);
+    keys.addKeyClick(Qt::Key_D);
+    keys.addKeyClick(Qt::Key_E);
+    keys.addKeyClick(Qt::Key_F);
+    keys.addKeyClick(Qt::Key_Left, Qt::ControlModifier);
+    QTest::newRow("abc efg<ctrl-left>") << keys << 7
+#ifndef Q_WS_MAC
+        << 4;
+#else
+        << 0;
+#endif
+    keys.clear();
+#ifdef Q_WS_MAC
+    keys.addKeyClick(Qt::Key_A);
+    keys.addKeyClick(Qt::Key_B);
+    keys.addKeyClick(Qt::Key_C);
+    keys.addKeyClick(Qt::Key_Space);
+    keys.addKeyClick(Qt::Key_D);
+    keys.addKeyClick(Qt::Key_E);
+    keys.addKeyClick(Qt::Key_F);
+    keys.addKeyClick(Qt::Key_Left, Qt::AltModifier);
+    QTest::newRow("mac equivalent abc efg<option-left>") << keys << 7 << 4;
+    keys.clear();
+#endif
+}
+
+
+void tst_QLineEdit::cursorPositionChanged()
+{
+    QFETCH(QTestEventList, input);
+    QFETCH(int, lastPos);
+    QFETCH(int, newPos);
+
+    lastCursorPos = 0;
+    newCursorPos = 0;
+    input.simulate(testWidget);
+    QCOMPARE(lastCursorPos, lastPos);
+    QCOMPARE(newCursorPos, newPos);
+}
+
+void tst_QLineEdit::selectedText()
+{
+    QString testString = "Abc defg hijklmno, p 'qrst' uvw xyz";
+
+    // start with a basic text
+    testWidget->setText(testString);
+    selection_count = 0;
+
+    // The text we have now is:
+    //           1         2         3         4         5
+    // 012345678901234567890123456789012345678901234567890
+    // Abc defg hijklmno, p 'qrst' uvw xyz
+
+    testWidget->home(false);
+    QVERIFY(!testWidget->hasSelectedText());
+    QCOMPARE(testWidget->selectedText(), QString());
+
+    // play a bit with the cursorForward, cursorBackward(), etc
+    testWidget->cursorForward(true, 9);
+    QVERIFY(testWidget->hasSelectedText());
+    QCOMPARE(testWidget->selectedText(), QString("Abc defg "));
+    QVERIFY(selection_count == 1);
+
+    // reset selection
+    testWidget->home(false);
+    QVERIFY(!testWidget->hasSelectedText());
+    QCOMPARE(testWidget->selectedText(), QString());
+    selection_count = 0;
+}
+
+/* // tested in selectedText
+void tst_QLineEdit::backspace()
+void tst_QLineEdit::del()
+void tst_QLineEdit::selectionChanged()
+void tst_QLineEdit::selectAll()
+void tst_QLineEdit::deselect()
+*/
+
+void tst_QLineEdit::onSelectionChanged()
+{
+    selection_count++;
+}
+
+void tst_QLineEdit::hasSelectedText()
+{
+    DEPENDS_ON("selectedText");
+}
+
+void tst_QLineEdit::deleteSelectedText()
+{
+    const QString text = QString::fromLatin1("bar");
+    QLineEdit edit( text );
+    QCOMPARE(edit.text(), text);
+
+    edit.selectAll();
+
+    QTest::keyClick(&edit, Qt::Key_Delete, 0);
+    QVERIFY(edit.text().isEmpty());
+
+    edit.setText(text);
+    edit.selectAll();
+
+    QMenu *menu = edit.createStandardContextMenu();
+    for (int i = 0; i < menu->actions().count(); ++i) {
+        QAction *current = menu->actions().at(i);
+        if (current->text() == QLineEdit::tr("Delete")) {
+            current->trigger(); //this will delete the whole text selected
+            QVERIFY(edit.text().isEmpty());
+        }
+    }
+
+}
+
+
+void tst_QLineEdit::textChangedAndTextEdited()
+{
+    changed_count = 0;
+    edited_count = 0;
+
+    QTest::keyClick(testWidget, Qt::Key_A);
+    QCOMPARE(changed_count, 1);
+    QVERIFY(edited_count == changed_count);
+    QTest::keyClick(testWidget, 'b');
+    QCOMPARE(changed_count, 2);
+    QVERIFY(edited_count == changed_count);
+    QTest::keyClick(testWidget, 'c');
+    QCOMPARE(changed_count, 3);
+    QVERIFY(edited_count == changed_count);
+    QTest::keyClick(testWidget, ' ');
+    QCOMPARE(changed_count, 4);
+    QVERIFY(edited_count == changed_count);
+    QTest::keyClick(testWidget, 'd');
+    QCOMPARE(changed_count, 5);
+    QVERIFY(edited_count == changed_count);
+
+    changed_count = 0;
+    edited_count = 0;
+    changed_string = QString::null;
+
+    testWidget->setText("foo");
+    QCOMPARE(changed_count, 1);
+    QCOMPARE(edited_count, 0);
+    QCOMPARE(changed_string, QString("foo"));
+
+    changed_count = 0;
+    edited_count = 0;
+    changed_string = QString::null;
+
+    testWidget->setText("");
+    QCOMPARE(changed_count, 1);
+    QCOMPARE(edited_count, 0);
+    QVERIFY(changed_string.isEmpty());
+    QVERIFY(!changed_string.isNull());
+}
+
+void tst_QLineEdit::onTextChanged(const QString &text)
+{
+    changed_count++;
+    changed_string = text;
+}
+
+void tst_QLineEdit::onTextEdited(const QString &/*text*/)
+{
+    edited_count++;
+}
+
+
+void tst_QLineEdit::onCursorPositionChanged(int oldPos, int newPos)
+{
+    lastCursorPos = oldPos;
+    newCursorPos = newPos;
+}
+
+void tst_QLineEdit::returnPressed()
+{
+    return_count = 0;
+
+    QTest::keyClick(testWidget, Qt::Key_Return);
+    QVERIFY(return_count == 1);
+    return_count = 0;
+
+    QTest::keyClick(testWidget, 'A');
+    QVERIFY(return_count == 0);
+    QTest::keyClick(testWidget, 'b');
+    QVERIFY(return_count == 0);
+    QTest::keyClick(testWidget, 'c');
+    QVERIFY(return_count == 0);
+    QTest::keyClick(testWidget, ' ');
+    QVERIFY(return_count == 0);
+    QTest::keyClick(testWidget, 'd');
+    QVERIFY(return_count == 0);
+    psKeyClick(testWidget, Qt::Key_Home);
+    QVERIFY(return_count == 0);
+    psKeyClick(testWidget, Qt::Key_End);
+    QVERIFY(return_count == 0);
+    QTest::keyClick(testWidget, Qt::Key_Escape);
+    QVERIFY(return_count == 0);
+    QTest::keyClick(testWidget, Qt::Key_Return);
+    QVERIFY(return_count == 1);
+}
+
+// int validator that fixes all !isNumber to '0'
+class QIntFixValidator : public QIntValidator {
+public:
+    QIntFixValidator(int min, int max, QObject *parent) : QIntValidator(min, max, parent) {}
+    void fixup (QString &input) const {
+        for (int i=0; i<input.length(); ++i)
+            if (!input.at(i).isNumber()) {
+                input[(int)i] = QChar('0');
+            }
+    }
+};
+
+void tst_QLineEdit::returnPressed_maskvalidator_data() {
+    QTest::addColumn<QString>("inputMask");
+    QTest::addColumn<bool>("hasValidator");
+    QTest::addColumn<QTestEventList>("input");
+    QTest::addColumn<QString>("expectedText");
+    QTest::addColumn<bool>("returnPressed");
+
+    {
+        QTestEventList keys;
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_3);
+        keys.addKeyClick(Qt::Key_Return);
+        QTest::newRow("no mask, no validator, input '123<cr>'")
+            << QString()
+            << false
+            << keys
+            << QString("123")
+            << true;
+    }
+    {
+        QTestEventList keys;
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_Return);
+        QTest::newRow("mask '999', no validator, input '12<cr>'")
+            << QString("999")
+            << false
+            << keys
+            << QString("12")
+            << false;
+    }
+    {
+        QTestEventList keys;
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_3);
+        keys.addKeyClick(Qt::Key_Return);
+        QTest::newRow("mask '999', no validator, input '123<cr>'")
+            << QString("999")
+            << false
+            << keys
+            << QString("123")
+            << true;
+    }
+    {
+        QTestEventList keys;
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_3);
+        keys.addKeyClick(Qt::Key_Return);
+        QTest::newRow("no mask, intfix validator(0,999), input '123<cr>'")
+            << QString()
+            << true
+            << keys
+            << QString("123")
+            << true;
+    }
+    {
+        QTestEventList keys;
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_7);
+        keys.addKeyClick(Qt::Key_7);
+        keys.addKeyClick(Qt::Key_7);
+        keys.addKeyClick(Qt::Key_7);
+        keys.addKeyClick(Qt::Key_Return);
+        QTest::newRow("no mask, intfix validator(0,999), input '7777<cr>'")
+            << QString()
+            << true
+            << keys
+            << QString("777")
+            << true;
+    }
+    {
+        QTestEventList keys;
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_1);
+        keys.addKeyClick(Qt::Key_2);
+        keys.addKeyClick(Qt::Key_Return);
+        QTest::newRow("mask '999', intfix validator(0,999), input '12<cr>'")
+            << QString("999")
+            << true
+            << keys
+            << QString("12")
+            << false;
+    }
+    {
+        QTestEventList keys;
+        keys.addKeyClick(Qt::Key_Home);
+        keys.addKeyClick(Qt::Key_Return);
+        QTest::newRow("mask '999', intfix validator(0,999), input '<cr>'")
+            << QString("999")
+            << true
+            << keys
+            << QString("000")
+            << true;
+    }
+}
+
+void tst_QLineEdit::returnPressed_maskvalidator()
+{
+    QFETCH(QString, inputMask);
+    QFETCH(bool, hasValidator);
+    QFETCH(QTestEventList, input);
+    QFETCH(QString, expectedText);
+    QFETCH(bool, returnPressed);
+
+    QEXPECT_FAIL("mask '999', intfix validator(0,999), input '12<cr>'", "QIntValidator has changed behaviour. Does not accept spaces. Task 43082.", Abort);
+
+    testWidget->setInputMask(inputMask);
+    if (hasValidator)
+        testWidget->setValidator(new QIntFixValidator(0, 999, testWidget));
+
+    return_count = 0;
+    input.simulate(testWidget);
+
+    QCOMPARE(testWidget->text(), expectedText);
+    QCOMPARE(return_count , returnPressed ? 1 : 0);
+}
+
+void tst_QLineEdit::onReturnPressed()
+{
+    return_count++;
+}
+
+void tst_QLineEdit::setValidator()
+{
+    // Verify that we can set and re-set a validator.
+    QVERIFY(!testWidget->validator());
+
+    QIntValidator iv1(0);
+    testWidget->setValidator(&iv1);
+    QCOMPARE(testWidget->validator(), static_cast<const QValidator*>(&iv1));
+
+    testWidget->setValidator(0);
+    QVERIFY(testWidget->validator() == 0);
+
+    QIntValidator iv2(0, 99, 0);
+    testWidget->setValidator(&iv2);
+    QCOMPARE(testWidget->validator(), static_cast<const QValidator *>(&iv2));
+
+    testWidget->setValidator(0);
+    QVERIFY(testWidget->validator() == 0);
+}
+
+void tst_QLineEdit::validator()
+{
+    DEPENDS_ON("setValidator");
+}
+
+void tst_QLineEdit::clearValidator()
+{
+    DEPENDS_ON("setValidator");
+}
+
+void tst_QLineEdit::setValidator_QIntValidator_data()
+{
+    QTest::addColumn<int>("mini");
+    QTest::addColumn<int>("maxi");
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<QString>("expectedText");
+    QTest::addColumn<bool>("useKeys");
+    QTest::addColumn<bool>("is_valid");
+
+    for (int i=0; i<2; i++) {
+        bool useKeys = false;
+        QString inputMode = "insert ";
+        if (i!=0) {
+            inputMode = "useKeys ";
+            useKeys = true;
+        }
+
+        // valid data
+        QTest::newRow(QString(inputMode + "range [0,9] valid '1'").toLatin1())
+            << 0
+            << 9
+            << QString("1")
+            << QString("1")
+            << bool(useKeys)
+            << bool(true);
+
+        QTest::newRow(QString(inputMode + "range [3,7] valid '3'").toLatin1())
+            << 3
+            << 7
+            << QString("3")
+            << QString("3")
+            << bool(useKeys)
+            << bool(true);
+
+        QTest::newRow(QString(inputMode + "range [3,7] valid '7'").toLatin1())
+            << 3
+            << 7
+            << QString("7")
+            << QString("7")
+            << bool(useKeys)
+            << bool(true);
+
+        QTest::newRow(QString(inputMode + "range [0,100] valid '9'").toLatin1())
+            << 0
+            << 100
+            << QString("9")
+            << QString("9")
+            << bool(useKeys)
+            << bool(true);
+
+        QTest::newRow(QString(inputMode + "range [0,100] valid '12'").toLatin1())
+            << 0
+            << 100
+            << QString("12")
+            << QString("12")
+            << bool(useKeys)
+            << bool(true);
+
+        QTest::newRow(QString(inputMode + "range [-100,100] valid '-12'").toLatin1())
+            << -100
+            << 100
+            << QString("-12")
+            << QString("-12")
+            << bool(useKeys)
+            << bool(true);
+
+        // invalid data
+        // characters not allowed in QIntValidator
+        QTest::newRow(QString(inputMode + "range [0,9] inv 'a-a'").toLatin1())
+            << 0
+            << 9
+            << QString("a")
+            << QString("")
+            << bool(useKeys)
+            << bool(false);
+
+        QTest::newRow(QString(inputMode + "range [0,9] inv 'A'").toLatin1())
+            << 0
+            << 9
+            << QString("A")
+            << QString("")
+            << bool(useKeys)
+            << bool(false);
+        // minus sign only allowed with a range on the negative side
+        QTest::newRow(QString(inputMode + "range [0,100] inv '-'").toLatin1())
+            << 0
+            << 100
+            << QString("-")
+            << QString("")
+            << bool(useKeys)
+            << bool(false);
+        QTest::newRow(QString(inputMode + "range [0,100] int '153'").toLatin1())
+            << 0
+            << 100
+            << QString("153")
+            << QString(useKeys ? "15" : "")
+            << bool(useKeys)
+            << bool(useKeys ? true : false);
+        QTest::newRow(QString(inputMode + "range [-100,100] int '-153'").toLatin1())
+            << -100
+            << 100
+            << QString("-153")
+            << QString(useKeys ? "-15" : "")
+            << bool(useKeys)
+            << bool(useKeys ? true : false);
+        QTest::newRow(QString(inputMode + "range [3,7] int '2'").toLatin1())
+            << 3
+            << 7
+            << QString("2")
+            << QString("2")
+            << bool(useKeys)
+            << bool(false);
+
+        QTest::newRow(QString(inputMode + "range [3,7] int '8'").toLatin1())
+            << 3
+            << 7
+            << QString("8")
+            << QString("")
+            << bool(useKeys)
+            << bool(false);
+    }
+}
+
+void tst_QLineEdit::setValidator_QIntValidator()
+{
+    QFETCH(int, mini);
+    QFETCH(int, maxi);
+    QFETCH(QString, input);
+    QFETCH(QString, expectedText);
+    QFETCH(bool, useKeys);
+    QFETCH(bool, is_valid);
+
+    QIntValidator intValidator(mini, maxi, 0);
+    testWidget->setValidator(&intValidator);
+    QVERIFY(testWidget->text().isEmpty());
+//qDebug("1 input: '" + input + "' Exp: '" + expectedText + "'");
+
+    // tests valid input
+    if (!useKeys) {
+        testWidget->insert(input);
+    } else {
+        QTest::keyClicks(testWidget, input);
+        return_count = 0;
+        QTest::keyClick(testWidget, Qt::Key_Return);
+        QCOMPARE(return_count, int(is_valid)); // assuming that is_valid = true equals 1
+    }
+//qDebug("2 input: '" + input + "' Exp: '" + expectedText + "'");
+//    QCOMPARE(testWidget->displayText(), expectedText);
+    QCOMPARE(testWidget->text(), expectedText);
+}
+
+#define NO_PIXMAP_TESTS
+
+void tst_QLineEdit::frame_data()
+{
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTest::addColumn<QPixmap>("noFrame");
+    QTest::addColumn<QPixmap>("useFrame");
+
+    QTest::newRow("win");
+//#else
+//    QTest::newRow("x11");
+#endif
+#endif
+}
+
+void tst_QLineEdit::frame()
+{
+    testWidget->setFrame(false);
+    // verify that the editor is shown without a frame
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "noFrame");
+#endif
+#endif
+    QVERIFY(!testWidget->hasFrame());
+
+    testWidget->setFrame(true);
+    // verify that the editor is shown with a frame
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "useFrame");
+#endif
+#endif
+    QVERIFY(testWidget->hasFrame());
+}
+
+void tst_QLineEdit::alignment()
+{
+    DEPENDS_ON("setAlignment");
+}
+
+void tst_QLineEdit::setAlignment_data()
+{
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTest::addColumn<QPixmap>("left");
+    QTest::addColumn<QPixmap>("right");
+    QTest::addColumn<QPixmap>("hcenter");
+    QTest::addColumn<QPixmap>("auto");
+
+    QTest::newRow("win");
+//#else
+//    QTest::newRow("x11");
+#endif
+#endif
+}
+
+void tst_QLineEdit::setAlignment()
+{
+    testWidget->setText("left");
+    testWidget->setAlignment(Qt::AlignLeft);
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "left");
+#endif
+#endif
+    QVERIFY(testWidget->alignment() == Qt::AlignLeft);
+
+#ifdef QT3_SUPPORT
+    testWidget->setText("auto");
+    testWidget->setAlignment(Qt::AlignAuto);
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "auto");
+#endif
+#endif
+#endif
+
+    testWidget->setText("hcenter");
+    testWidget->setAlignment(Qt::AlignHCenter);
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "hcenter");
+#endif
+#endif
+    QVERIFY(testWidget->alignment() == Qt::AlignHCenter);
+
+#ifdef QT3_SUPPORT
+    testWidget->setText("auto");
+    testWidget->setAlignment(Qt::AlignAuto);
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "auto");
+#endif
+#endif
+#endif
+
+    testWidget->setText("right");
+    testWidget->setAlignment(Qt::AlignRight);
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "right");
+#endif
+#endif
+    QVERIFY(testWidget->alignment() == Qt::AlignRight);
+
+#ifdef QT3_SUPPORT
+    testWidget->setText("auto");
+    testWidget->setAlignment(Qt::AlignAuto);
+#ifndef NO_PIXMAP_TESTS
+#if defined Q_WS_WIN
+    QTEST(testWidget, "auto");
+#endif
+#endif
+    QVERIFY(testWidget->alignment() == Qt::AlignAuto);
+#endif
+
+    testWidget->setAlignment(Qt::AlignTop);
+    QVERIFY(testWidget->alignment() == Qt::AlignTop);
+
+    testWidget->setAlignment(Qt::AlignBottom);
+    QVERIFY(testWidget->alignment() == Qt::AlignBottom);
+
+    testWidget->setAlignment(Qt::AlignCenter);
+    QVERIFY(testWidget->alignment() == Qt::AlignCenter);
+}
+
+void tst_QLineEdit::isModified()
+{
+    QVERIFY(!testWidget->isModified());
+    testWidget->setText("bla");
+    QVERIFY(!testWidget->isModified());
+
+    psKeyClick(testWidget, Qt::Key_Home);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Right);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Right);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Right);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QVERIFY(!testWidget->isModified());
+    psKeyClick(testWidget, Qt::Key_End);
+    QVERIFY(!testWidget->isModified());
+
+    QTest::keyClicks(testWidget, "T");
+    QVERIFY(testWidget->isModified());
+    QTest::keyClicks(testWidget, "his is a string");
+    QVERIFY(testWidget->isModified());
+
+    testWidget->setText("");
+    QVERIFY(!testWidget->isModified());
+    testWidget->setText("foo");
+    QVERIFY(!testWidget->isModified());
+}
+
+/*
+    Obsolete function but as long as we provide it, it needs to work.
+*/
+
+void tst_QLineEdit::edited()
+{
+    QVERIFY(!testWidget->isModified());
+    testWidget->setText("bla");
+    QVERIFY(!testWidget->isModified());
+
+    psKeyClick(testWidget, Qt::Key_Home);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Right);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Right);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Right);
+    QVERIFY(!testWidget->isModified());
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QVERIFY(!testWidget->isModified());
+    psKeyClick(testWidget, Qt::Key_End);
+    QVERIFY(!testWidget->isModified());
+
+    QTest::keyClicks(testWidget, "T");
+    QVERIFY(testWidget->isModified());
+    QTest::keyClicks(testWidget, "his is a string");
+    QVERIFY(testWidget->isModified());
+
+    testWidget->setModified(false);
+    QVERIFY(!testWidget->isModified());
+
+    testWidget->setModified(true);
+    QVERIFY(testWidget->isModified());
+}
+
+/*
+    Obsolete function but as long as we provide it, it needs to work.
+*/
+
+void tst_QLineEdit::setEdited()
+{
+    DEPENDS_ON("edited");
+}
+
+void tst_QLineEdit::insert()
+{
+    testWidget->insert("This");
+    testWidget->insert(" is");
+    testWidget->insert(" a");
+    testWidget->insert(" test");
+
+    QCOMPARE(testWidget->text(), QString("This is a test"));
+
+    testWidget->cursorWordBackward(false);
+    testWidget->cursorBackward(false, 1);
+    testWidget->insert(" nice");
+    QCOMPARE(testWidget->text(), QString("This is a nice test"));
+
+    testWidget->setCursorPosition(-1);
+    testWidget->insert("No Crash! ");
+    QCOMPARE(testWidget->text(), QString("No Crash! This is a nice test"));
+}
+
+void tst_QLineEdit::setSelection_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<int>("start");
+    QTest::addColumn<int>("length");
+    QTest::addColumn<int>("expectedCursor");
+    QTest::addColumn<QString>("expectedText");
+    QTest::addColumn<bool>("expectedHasSelectedText");
+
+    QString text = "Abc defg hijklmno, p 'qrst' uvw xyz";
+    int start, length, pos;
+
+    start = 0; length = 1; pos = 1;
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString("A") << true;
+
+    start = 0; length = 2; pos = 2;
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString("Ab") << true;
+
+    start = 0; length = 4; pos = 4;
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString("Abc ") << true;
+
+    start = -1; length = 0; pos = text.length();
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString() << false;
+
+    start = 34; length = 1; pos = 35;
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString("z") << true;
+
+    start = 34; length = 2; pos = 35;
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString("z") << true;
+
+    start = 34; length = -1; pos = 33;
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString("y") << true;
+
+    start = 1; length = -2; pos = 0;
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString("A") << true;
+
+    start = -1; length = -1; pos = text.length();
+    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
+        << text << start << length << pos << QString() << false;
+}
+
+
+void tst_QLineEdit::setSelection()
+{
+    QFETCH(QString, text);
+    QFETCH(int, start);
+    QFETCH(int, length);
+    QFETCH(int, expectedCursor);
+    QFETCH(QString, expectedText);
+    QFETCH(bool, expectedHasSelectedText);
+
+    testWidget->setText(text);
+    testWidget->setSelection(start, length);
+    QCOMPARE(testWidget->hasSelectedText(), expectedHasSelectedText);
+    QCOMPARE(testWidget->selectedText(), expectedText);
+    if (expectedCursor >= 0)
+        QCOMPARE(testWidget->cursorPosition(), expectedCursor);
+}
+
+#ifndef QT_NO_CLIPBOARD
+void tst_QLineEdit::cut()
+{
+#ifdef Q_WS_MAC
+    {
+        PasteboardRef pasteboard;
+        OSStatus status = PasteboardCreate(0, &pasteboard);
+        if (status == noErr)
+            CFRelease(pasteboard);
+        else
+            QSKIP("Autotests run from cron and pasteboard don't get along quite ATM", SkipAll);
+    }
+#endif
+    // test newlines in cut'n'paste
+    testWidget->setText("A\nB\nC\n");
+    testWidget->setSelection(0, 6);
+    testWidget->cut();
+    psKeyClick(testWidget, Qt::Key_Home);
+    testWidget->paste();
+    QCOMPARE(testWidget->text(), QString("A\nB\nC\n"));
+    //                              1         2         3         4
+    //                    01234567890123456789012345678901234567890
+    testWidget->setText("Abc defg hijklmno");
+
+    testWidget->setSelection(0, 3);
+    testWidget->cut();
+    QCOMPARE(testWidget->text(), QString(" defg hijklmno"));
+
+    psKeyClick(testWidget, Qt::Key_End);
+    testWidget->paste();
+    QCOMPARE(testWidget->text(), QString(" defg hijklmnoAbc"));
+
+    psKeyClick(testWidget, Qt::Key_Home);
+    testWidget->del();
+    QCOMPARE(testWidget->text(), QString("defg hijklmnoAbc"));
+
+    testWidget->setSelection(0, 4);
+    testWidget->copy();
+    psKeyClick(testWidget, Qt::Key_End);
+    testWidget->paste();
+    QCOMPARE(testWidget->text(), QString("defg hijklmnoAbcdefg"));
+
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QTest::keyClick(testWidget, Qt::Key_Left);
+    QTest::keyClick(testWidget, ' ');
+    QCOMPARE(testWidget->text(), QString("defg hijklmno Abcdefg"));
+
+    testWidget->setSelection(0, 5);
+    testWidget->del();
+    QCOMPARE(testWidget->text(), QString("hijklmno Abcdefg"));
+
+    testWidget->end(false);
+    QTest::keyClick(testWidget, ' ');
+    testWidget->paste();
+    QCOMPARE(testWidget->text(), QString("hijklmno Abcdefg defg"));
+
+    testWidget->home(false);
+    testWidget->cursorWordForward(true);
+    testWidget->cut();
+    testWidget->end(false);
+    QTest::keyClick(testWidget, ' ');
+    testWidget->paste();
+    testWidget->cursorBackward(true, 1);
+    testWidget->cut();
+    QCOMPARE(testWidget->text(), QString("Abcdefg defg hijklmno"));
+}
+
+void tst_QLineEdit::copy()
+{
+    DEPENDS_ON("cut");
+}
+
+void tst_QLineEdit::paste()
+{
+    DEPENDS_ON("cut");
+}
+#endif
+class InputMaskValidator : public QValidator
+{
+public:
+    InputMaskValidator(QObject *parent, const char *name = 0) : QValidator(parent) { setObjectName(name); }
+    State validate(QString &text, int &pos) const
+    {
+        InputMaskValidator *that = (InputMaskValidator *)this;
+        that->validateText = text;
+        that->validatePos = pos;
+        return Acceptable;
+    }
+    QString validateText;
+    int validatePos;
+};
+
+void tst_QLineEdit::inputMaskAndValidator_data()
+{
+    QTest::addColumn<QString>("inputMask");
+    QTest::addColumn<QTestEventList>("keys");
+    QTest::addColumn<QString>("validateText");
+    QTest::addColumn<int>("validatePos");
+
+    QTestEventList inputKeys;
+    inputKeys.addKeyClick(Qt::Key_1);
+    inputKeys.addKeyClick(Qt::Key_2);
+
+    QTest::newRow("task28291") << "000;_" << inputKeys << "12_" << 2;
+}
+
+void tst_QLineEdit::inputMaskAndValidator()
+{
+    QFETCH(QString, inputMask);
+    QFETCH(QTestEventList, keys);
+    QFETCH(QString, validateText);
+    QFETCH(int, validatePos);
+
+    InputMaskValidator imv(testWidget);
+    testWidget->setValidator(&imv);
+
+    testWidget->setInputMask(inputMask);
+    keys.simulate(testWidget);
+
+    QCOMPARE(imv.validateText, validateText);
+    QCOMPARE(imv.validatePos, validatePos);
+}
+
+void tst_QLineEdit::maxLengthAndInputMask()
+{
+    // Really a test for #30447
+    QVERIFY(testWidget->inputMask().isNull());
+    testWidget->setMaxLength(10);
+    QVERIFY(testWidget->maxLength() == 10);
+    testWidget->setInputMask(QString::null);
+    QVERIFY(testWidget->inputMask().isNull());
+    QVERIFY(testWidget->maxLength() == 10);
+}
+
+
+class LineEdit : public QLineEdit
+{
+public:
+    LineEdit() { state = Other; }
+
+    void keyPressEvent(QKeyEvent *e)
+    {
+        QLineEdit::keyPressEvent(e);
+        if (e->key() == Qt::Key_Enter) {
+            state = e->isAccepted() ? Accepted : Ignored;
+        } else {
+            state = Other;
+        }
+
+    }
+    enum State {
+        Accepted,
+        Ignored,
+        Other
+    };
+
+    State state;
+};
+
+Q_DECLARE_METATYPE(LineEdit::State);
+void tst_QLineEdit::returnPressedKeyEvent()
+{
+    LineEdit lineedit;
+    lineedit.show();
+    QCOMPARE((int)lineedit.state, (int)LineEdit::Other);
+    QTest::keyClick(&lineedit, Qt::Key_Enter);
+    QCOMPARE((int)lineedit.state, (int)LineEdit::Ignored);
+    connect(&lineedit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
+    QTest::keyClick(&lineedit, Qt::Key_Enter);
+    QCOMPARE((int)lineedit.state, (int)LineEdit::Ignored);
+    disconnect(&lineedit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
+    QTest::keyClick(&lineedit, Qt::Key_Enter);
+    QCOMPARE((int)lineedit.state, (int)LineEdit::Ignored);
+    QTest::keyClick(&lineedit, Qt::Key_1);
+    QCOMPARE((int)lineedit.state, (int)LineEdit::Other);
+}
+
+void tst_QLineEdit::keepSelectionOnTabFocusIn()
+{
+    testWidget->setText("hello world");
+    {
+        QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason);
+        QApplication::sendEvent(testWidget, &e);
+    }
+    QCOMPARE(testWidget->selectedText(), QString("hello world"));
+    testWidget->setSelection(0, 5);
+    QCOMPARE(testWidget->selectedText(), QString("hello"));
+    {
+        QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason);
+        QApplication::sendEvent(testWidget, &e);
+    }
+    QCOMPARE(testWidget->selectedText(), QString("hello"));
+}
+
+void tst_QLineEdit::readOnlyStyleOption()
+{
+    bool wasReadOnly = testWidget->isReadOnly();
+    QStyle *oldStyle = testWidget->style();
+
+    StyleOptionTestStyle myStyle;
+    testWidget->setStyle(&myStyle);
+
+    myStyle.setReadOnly(true);
+    testWidget->setReadOnly(true);
+    testWidget->repaint();
+    qApp->processEvents();
+
+    testWidget->setReadOnly(false);
+    myStyle.setReadOnly(false);
+    testWidget->repaint();
+    qApp->processEvents();
+
+    testWidget->setReadOnly(wasReadOnly);
+    testWidget->setStyle(oldStyle);
+}
+
+void tst_QLineEdit::validateOnFocusOut()
+{
+    QSignalSpy editingFinishedSpy(testWidget, SIGNAL(editingFinished()));
+    testWidget->setValidator(new QIntValidator(100, 999, 0));
+    QTest::keyPress(testWidget, '1');
+    QTest::keyPress(testWidget, '0');
+    QCOMPARE(testWidget->text(), QString("10"));
+    testWidget->clearFocus();
+    QCOMPARE(editingFinishedSpy.count(), 0);
+
+    testWidget->setFocus();
+    testWidget->activateWindow();
+    QTRY_VERIFY(testWidget->hasFocus());
+
+    QTest::keyPress(testWidget, '0');
+    QTRY_COMPARE(testWidget->text(), QString("100"));
+
+    testWidget->clearFocus();
+    QCOMPARE(editingFinishedSpy.count(), 1);
+}
+
+void tst_QLineEdit::editInvalidText()
+{
+    testWidget->clear();
+    testWidget->setValidator(new QIntValidator(0, 120, 0));
+    testWidget->setText("1234");
+
+    QVERIFY(!testWidget->hasAcceptableInput());
+    QTest::keyPress(testWidget, Qt::Key_Backspace);
+    QTest::keyPress(testWidget, Qt::Key_Backspace);
+    QTest::keyPress(testWidget, Qt::Key_A);
+    QTest::keyPress(testWidget, Qt::Key_B);
+    QTest::keyPress(testWidget, Qt::Key_C);
+    QTest::keyPress(testWidget, Qt::Key_1);
+    QVERIFY(testWidget->hasAcceptableInput());
+    QCOMPARE(testWidget->text(), QString("12"));
+    testWidget->cursorBackward(false);
+    testWidget->cursorBackward(true, 2);
+    QTest::keyPress(testWidget, Qt::Key_Delete);
+    QVERIFY(testWidget->hasAcceptableInput());
+    QCOMPARE(testWidget->text(), QString("2"));
+    QTest::keyPress(testWidget, Qt::Key_1);
+    QVERIFY(testWidget->hasAcceptableInput());
+    QCOMPARE(testWidget->text(), QString("12"));
+
+    testWidget->setValidator(0);
+}
+
+void tst_QLineEdit::charWithAltOrCtrlModifier()
+{
+    testWidget->clear();
+    QCOMPARE(testWidget->text(), QString(""));
+    QTest::keyPress(testWidget, Qt::Key_Plus);
+    QCOMPARE(testWidget->text(), QString("+"));
+    QTest::keyPress(testWidget, Qt::Key_Plus, Qt::ControlModifier);
+    QCOMPARE(testWidget->text(), QString("++"));
+    QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier);
+    QCOMPARE(testWidget->text(), QString("+++"));
+    QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier | Qt::ControlModifier);
+    QCOMPARE(testWidget->text(), QString("++++"));
+}
+
+void tst_QLineEdit::leftKeyOnSelectedText()
+{
+    testWidget->clear();
+    testWidget->setText("0123");
+    testWidget->setCursorPosition(4);
+    QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier);
+    QCOMPARE(testWidget->cursorPosition(), 3);
+    QCOMPARE(testWidget->selectedText(), QString("3"));
+    QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier);
+    QCOMPARE(testWidget->cursorPosition(), 2);
+    QCOMPARE(testWidget->selectedText(), QString("23"));
+    QTest::keyClick(testWidget, Qt::Key_Left);
+#ifdef Q_OS_WIN
+    QCOMPARE(testWidget->cursorPosition(), 1);
+#else
+    // X11 used to behave like window prior to 4.2. Changes caused by QKeySequence
+    // resulted in an inadvertant change in behavior
+    QCOMPARE(testWidget->cursorPosition(), 2);
+#endif
+}
+
+void tst_QLineEdit::inlineCompletion()
+{
+    testWidget->clear();
+    QStandardItemModel *model = new QStandardItemModel;
+    QStandardItem *root = model->invisibleRootItem();
+    QStandardItem *items[5];
+    for (int i = 0; i < 5; i++) {
+        items[i] = new QStandardItem(QString("item%1").arg(i));
+        if ((i+2)%2 == 0) { // disable 0,2,4
+            items[i]->setFlags(items[i]->flags() & ~Qt::ItemIsEnabled);
+        }
+        root->appendRow(items[i]);
+    }
+    QCompleter *completer = new QCompleter(model);
+    completer->setCompletionMode(QCompleter::InlineCompletion);
+    completer->setCaseSensitivity(Qt::CaseInsensitive);
+    testWidget->setFocus();
+    QTRY_COMPARE(qApp->activeWindow(), (QWidget*)testWidget);
+    testWidget->setCompleter(completer);
+
+    // sanity
+    QTest::keyClick(testWidget, Qt::Key_X);
+    QCOMPARE(testWidget->selectedText(), QString());
+    QCOMPARE(testWidget->text(), QString("x"));
+    QTest::keyClick(testWidget, Qt::Key_Down, Qt::ControlModifier);
+    QCOMPARE(testWidget->selectedText(), QString());
+    QCOMPARE(testWidget->text(), QString("x"));
+    QTest::keyClick(testWidget, Qt::Key_Up, Qt::ControlModifier);
+    QCOMPARE(testWidget->selectedText(), QString());
+    QCOMPARE(testWidget->text(), QString("x"));
+
+    testWidget->clear();
+    QTest::keyClick(testWidget, Qt::Key_I);
+    QCOMPARE(testWidget->selectedText(), QString("tem1"));
+
+    Qt::KeyboardModifiers keyboardModifiers = Qt::ControlModifier;
+#ifdef Q_WS_MAC
+    keyboardModifiers |= Qt::AltModifier;
+#endif
+    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
+    QCOMPARE(testWidget->selectedText(), QString("tem3"));
+
+    // wraps around (Default)
+    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
+    QCOMPARE(testWidget->selectedText(), QString("tem1"));
+
+    QTest::keyClick(testWidget, Qt::Key_Up, keyboardModifiers);
+    QCOMPARE(testWidget->selectedText(), QString("tem3"));
+
+    // should not wrap
+    completer->setWrapAround(false);
+    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
+    QCOMPARE(testWidget->selectedText(), QString("tem3"));
+    QTest::keyClick(testWidget, Qt::Key_Up, keyboardModifiers); // item1
+    QTest::keyClick(testWidget, Qt::Key_Up, keyboardModifiers); // item1
+    QCOMPARE(testWidget->selectedText(), QString("tem1"));
+
+    // trivia :)
+    root->appendRow(new QStandardItem("item11"));
+    root->appendRow(new QStandardItem("item12"));
+    testWidget->clear();
+    QTest::keyClick(testWidget, Qt::Key_I);
+    QCOMPARE(testWidget->selectedText(), QString("tem1"));
+    QTest::keyClick(testWidget, Qt::Key_Delete);
+    QCOMPARE(testWidget->selectedText(), QString());
+    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
+    QCOMPARE(testWidget->selectedText(), QString("tem1")); // neato
+    testWidget->setText("item1");
+    testWidget->setSelection(1, 2);
+    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
+    testWidget->end(false);
+    QCOMPARE(testWidget->text(), QString("item1")); // no effect for selection in "middle"
+    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers); // item1
+    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers); // item11
+    QCOMPARE(testWidget->text(), QString("item11"));
+
+    delete model;
+    delete completer;
+}
+
+void tst_QLineEdit::noTextEditedOnClear()
+{
+    testWidget->setText("Test");
+    QSignalSpy textEditedSpy(testWidget, SIGNAL(textEdited(const QString &)));
+    testWidget->clear();
+    QCOMPARE(textEditedSpy.count(), 0);
+}
+
+void tst_QLineEdit::textMargin_data()
+{
+    QTest::addColumn<int>("left");
+    QTest::addColumn<int>("top");
+    QTest::addColumn<int>("right");
+    QTest::addColumn<int>("bottom");
+
+    QTest::addColumn<QPoint>("mousePressPos");
+    QTest::addColumn<int>("cursorPosition");
+
+    QLineEdit testWidget;
+    QFontMetrics metrics(testWidget.font());
+    const QString s = QLatin1String("MMM MMM MMM");
+
+    // Different styles generate different offsets, so
+    // calculate the width rather than hardcode it.
+    const int pixelWidthOfM = metrics.width(s, 1);
+    const int pixelWidthOfMMM_MM = metrics.width(s, 6);
+
+    QTest::newRow("default-0") << 0 << 0 << 0 << 0 << QPoint(pixelWidthOfMMM_MM, 0) << 6;
+    QTest::newRow("default-1") << 0 << 0 << 0 << 0 << QPoint(1, 1) << 0;
+    QTest::newRow("default-2") << -1 << 0 << -1 << 0 << QPoint(pixelWidthOfMMM_MM, 0) << 6;
+    QTest::newRow("default-3") << 0 << 0 << 0 << 0 << QPoint(pixelWidthOfM, 1) << 1;
+
+    QTest::newRow("hor-0") << 10 << 0 << 10 << 0 << QPoint(1, 1) << 0;
+    QTest::newRow("hor-1") << 10 << 0 << 10 << 0 << QPoint(10, 1) << 0;
+    QTest::newRow("hor-2") << 20 << 0 << 10 << 0 << QPoint(20, 1) << 0;
+
+    if (!qApp->style()->inherits("QMacStyle")) { //MacStyle doesn't support verticals margins.
+        QTest::newRow("default-2-ver") << -1 << -1 << -1 << -1 << QPoint(pixelWidthOfMMM_MM, 0) << 6;
+        QTest::newRow("ver") << 0 << 10 << 0 << 10 << QPoint(1, 1) << 0;
+    }
+}
+
+void tst_QLineEdit::textMargin()
+{
+    QFETCH(int, left);
+    QFETCH(int, top);
+    QFETCH(int, right);
+    QFETCH(int, bottom);
+    QFETCH(QPoint, mousePressPos);
+    QFETCH(int, cursorPosition);
+
+    // Put the line edit into a toplevel window to avoid
+    // resizing by the window system.
+    QWidget tlw;
+    QLineEdit testWidget(&tlw);
+    testWidget.setGeometry(100, 100, 100, 30);
+    testWidget.setText("MMM MMM MMM");
+    testWidget.setCursorPosition(6);
+
+    QSize sizeHint = testWidget.sizeHint();
+    testWidget.setTextMargins(left, top, right, bottom);
+    sizeHint.setWidth(sizeHint.width() + left + right);
+    sizeHint.setHeight(sizeHint.height() + top +bottom);
+    QCOMPARE(testWidget.sizeHint(), sizeHint);
+    testWidget.setFrame(false);
+    tlw.show();
+
+    int l;
+    int t;
+    int r;
+    int b;
+    testWidget.getTextMargins(&l, &t, &r, &b);
+    QCOMPARE(left, l);
+    QCOMPARE(top, t);
+    QCOMPARE(right, r);
+    QCOMPARE(bottom, b);
+
+    QTest::mouseClick(&testWidget, Qt::LeftButton, 0, mousePressPos);
+    QTRY_COMPARE(testWidget.cursorPosition(), cursorPosition);
+}
+
+void tst_QLineEdit::cursor()
+{
+#ifdef QT_NO_CURSOR
+    QSKIP("Qt compiled without cursor support", SkipAll);
+#else
+    testWidget->setReadOnly(false);
+    QCOMPARE(testWidget->cursor().shape(), Qt::IBeamCursor);
+    testWidget->setReadOnly(true);
+    QCOMPARE(testWidget->cursor().shape(), Qt::ArrowCursor);
+    testWidget->setReadOnly(false);
+    QCOMPARE(testWidget->cursor().shape(), Qt::IBeamCursor);
+#endif
+}
+
+class task180999_Widget : public QWidget
+{
+public:
+    task180999_Widget(QWidget *parent = 0) : QWidget(parent)
+    {
+        QHBoxLayout *layout  = new QHBoxLayout(this);
+        lineEdit1.setText("some text 1 ...");
+        lineEdit2.setText("some text 2 ...");
+        layout->addWidget(&lineEdit1);
+        layout->addWidget(&lineEdit2);
+    }
+
+    QLineEdit lineEdit1;
+    QLineEdit lineEdit2;
+};
+
+void tst_QLineEdit::task180999_focus()
+{
+    task180999_Widget widget;
+
+    widget.lineEdit1.setFocus();
+    widget.show();
+
+    widget.lineEdit2.setFocus();
+    widget.lineEdit2.selectAll();
+    widget.hide();
+
+    widget.lineEdit1.setFocus();
+    widget.show();
+    QTest::qWait(200);
+    widget.activateWindow();
+
+    QTRY_VERIFY(!widget.lineEdit2.hasSelectedText());
+}
+
+void tst_QLineEdit::task174640_editingFinished()
+{
+    QWidget mw;
+    QVBoxLayout *layout = new QVBoxLayout(&mw);
+    QLineEdit *le1 = new QLineEdit(&mw);
+    QLineEdit *le2 = new QLineEdit(&mw);
+    layout->addWidget(le1);
+    layout->addWidget(le2);
+
+    mw.show();
+    QApplication::setActiveWindow(&mw);
+    mw.activateWindow();
+    QTest::qWaitForWindowShown(&mw);
+
+    QSignalSpy editingFinishedSpy(le1, SIGNAL(editingFinished()));
+
+    le1->setFocus();
+    QTest::qWait(20);
+    QTRY_VERIFY(le1->hasFocus());
+    QCOMPARE(editingFinishedSpy.count(), 0);
+
+    le2->setFocus();
+    QTest::qWait(20);
+    QTRY_VERIFY(le2->hasFocus());
+    QCOMPARE(editingFinishedSpy.count(), 1);
+    editingFinishedSpy.clear();
+
+    le1->setFocus();
+    QTest::qWait(20);
+    QTRY_VERIFY(le1->hasFocus());
+
+    QMenu *testMenu1 = new QMenu(le1);
+    testMenu1->addAction("foo");
+    testMenu1->addAction("bar");
+    testMenu1->show();
+    QTest::qWaitForWindowShown(testMenu1);
+    QTest::qWait(20);
+    mw.activateWindow();
+
+    delete testMenu1;
+    QCOMPARE(editingFinishedSpy.count(), 0);
+    QTRY_VERIFY(le1->hasFocus());
+
+    QMenu *testMenu2 = new QMenu(le2);
+    testMenu2->addAction("foo2");
+    testMenu2->addAction("bar2");
+    testMenu2->show();
+    QTest::qWaitForWindowShown(testMenu2);
+    QTest::qWait(20);
+    mw.activateWindow();
+    delete testMenu2;
+    QCOMPARE(editingFinishedSpy.count(), 1);
+}
+
+#ifndef QT_NO_COMPLETER
+class task198789_Widget : public QWidget
+{
+    Q_OBJECT
+public:
+    task198789_Widget(QWidget *parent = 0) : QWidget(parent)
+    {
+        QStringList wordList;
+        wordList << "alpha" << "omega" << "omicron" << "zeta";
+
+        lineEdit = new QLineEdit(this);
+        completer = new QCompleter(wordList, this);
+        lineEdit->setCompleter(completer);
+
+        connect(lineEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
+    }
+
+    QLineEdit *lineEdit;
+    QCompleter *completer;
+    QString currentCompletion;
+
+private slots:
+    void textChanged(const QString &)
+    {
+        currentCompletion = completer->currentCompletion();
+    }
+};
+
+void tst_QLineEdit::task198789_currentCompletion()
+{
+    task198789_Widget widget;
+    widget.show();
+    qApp->processEvents();
+    QTest::keyPress(widget.lineEdit, 'o');
+    QTest::keyPress(widget.lineEdit, 'm');
+    QTest::keyPress(widget.lineEdit, 'i');
+    QCOMPARE(widget.currentCompletion, QLatin1String("omicron"));
+}
+
+void tst_QLineEdit::task210502_caseInsensitiveInlineCompletion()
+{
+    QString completion("ABCD");
+    QStringList completions;
+    completions << completion;
+    QLineEdit lineEdit;
+    QCompleter completer(completions);
+    completer.setCaseSensitivity(Qt::CaseInsensitive);
+    completer.setCompletionMode(QCompleter::InlineCompletion);
+    lineEdit.setCompleter(&completer);
+    lineEdit.show();
+#ifdef Q_WS_X11
+    // to be safe and avoid failing setFocus with window managers
+    qt_x11_wait_for_window_manager(&lineEdit);
+#endif
+    lineEdit.setFocus();
+    QTRY_VERIFY(lineEdit.hasFocus());
+    QTest::keyPress(&lineEdit, 'a');
+    QTest::keyPress(&lineEdit, Qt::Key_Return);
+    QCOMPARE(lineEdit.text(), completion);
+}
+
+#endif // QT_NO_COMPLETER
+
+
+void tst_QLineEdit::task229938_dontEmitChangedWhenTextIsNotChanged()
+{
+    QLineEdit lineEdit;
+    lineEdit.setMaxLength(5);
+    lineEdit.show();
+#ifdef Q_WS_X11
+    // to be safe and avoid failing setFocus with window managers
+    qt_x11_wait_for_window_manager(&lineEdit);
+#endif
+    lineEdit.setFocus();
+    QSignalSpy changedSpy(&lineEdit, SIGNAL(textChanged(QString)));
+    QTest::qWait(200);
+    QTest::keyPress(&lineEdit, 'a');
+    QTest::keyPress(&lineEdit, 'b');
+    QTest::keyPress(&lineEdit, 'c');
+    QTest::keyPress(&lineEdit, 'd');
+    QTest::keyPress(&lineEdit, 'e');
+    QTest::keyPress(&lineEdit, 'f');
+    QCOMPARE(changedSpy.count(), 5);
+}
+
+void tst_QLineEdit::task233101_cursorPosAfterInputMethod_data()
+{
+    QTest::addColumn<int>("maxLength");
+    QTest::addColumn<int>("cursorPos");
+    QTest::addColumn<int>("replacementStart");
+    QTest::addColumn<int>("replacementLength");
+    QTest::addColumn<QString>("commitString");
+
+    QTest::newRow("") << 4 << 4 << 0 << 0 << QString("");
+    QTest::newRow("") << 4 << 4 << 0 << 0 << QString("x");
+    QTest::newRow("") << 4 << 4 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("") << 4 << 3 << 0 << 0 << QString("");
+    QTest::newRow("") << 4 << 3 << 0 << 0 << QString("x");
+    QTest::newRow("") << 4 << 3 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("") << 4 << 0 << 0 << 0 << QString("");
+    QTest::newRow("") << 4 << 0 << 0 << 0 << QString("x");
+    QTest::newRow("") << 4 << 0 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
+
+    QTest::newRow("") << 4 << 4 << -4 << 4 << QString("");
+    QTest::newRow("") << 4 << 4 << -4 << 4 << QString("x");
+    QTest::newRow("") << 4 << 4 << -4 << 4 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("") << 4 << 3 << -3 << 4 << QString("");
+    QTest::newRow("") << 4 << 3 << -3 << 4 << QString("x");
+    QTest::newRow("") << 4 << 3 << -3 << 4 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("") << 4 << 0 << 0 << 4 << QString("");
+    QTest::newRow("") << 4 << 0 << 0 << 4 << QString("x");
+    QTest::newRow("") << 4 << 0 << 0 << 4 << QString("xxxxxxxxxxxxxxxx");
+
+    QTest::newRow("") << 4 << 4 << -4 << 0 << QString("");
+    QTest::newRow("") << 4 << 4 << -4 << 0 << QString("x");
+    QTest::newRow("") << 4 << 4 << -4 << 0 << QString("xxxxxxxxxxxxxxxx");
+    QTest::newRow("") << 4 << 3 << -3 << 0 << QString("");
+    QTest::newRow("") << 4 << 3 << -3 << 0 << QString("x");
+    QTest::newRow("") << 4 << 3 << -3 << 0 << QString("xxxxxxxxxxxxxxxx");
+}
+
+void tst_QLineEdit::task233101_cursorPosAfterInputMethod()
+{
+    QFETCH(int, maxLength);
+    QFETCH(int, cursorPos);
+    QFETCH(int, replacementStart);
+    QFETCH(int, replacementLength);
+    QFETCH(QString, commitString);
+
+    QLineEdit lineEdit;
+    lineEdit.setMaxLength(maxLength);
+    lineEdit.insert(QString().fill(QLatin1Char('a'), cursorPos));
+    QCOMPARE(lineEdit.cursorPosition(), cursorPos);
+
+    QInputMethodEvent event;
+    event.setCommitString(QLatin1String("x"), replacementStart, replacementLength);
+    qApp->sendEvent(&lineEdit, &event);
+    QVERIFY(lineEdit.cursorPosition() >= 0);
+    QVERIFY(lineEdit.cursorPosition() <= lineEdit.text().size());
+    QVERIFY(lineEdit.text().size() <= lineEdit.maxLength());
+}
+
+void tst_QLineEdit::task241436_passwordEchoOnEditRestoreEchoMode()
+{
+    QStyleOptionFrameV2 opt;
+    QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
+
+    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
+    testWidget->setFocus();
+    QApplication::setActiveWindow(testWidget);
+    QTRY_VERIFY(testWidget->hasFocus());
+
+    QTest::keyPress(testWidget, '0');
+    QCOMPARE(testWidget->displayText(), QString("0"));
+    testWidget->setEchoMode(QLineEdit::Normal);
+    testWidget->clearFocus();
+    QCOMPARE(testWidget->displayText(), QString("0"));
+
+    testWidget->activateWindow();
+    testWidget->setFocus();
+    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
+    QTest::keyPress(testWidget, '0');
+    QCOMPARE(testWidget->displayText(), QString("0"));
+    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
+    QCOMPARE(testWidget->displayText(), QString("0"));
+    testWidget->clearFocus();
+    QCOMPARE(testWidget->displayText(), QString(fillChar));
+
+    // restore clean state
+    testWidget->setEchoMode(QLineEdit::Normal);
+}
+
+void tst_QLineEdit::task248948_redoRemovedSelection()
+{
+    testWidget->setText("a");
+    testWidget->selectAll();
+    QTest::keyPress(testWidget, Qt::Key_Delete);
+    testWidget->undo();
+    testWidget->redo();
+    QTest::keyPress(testWidget, 'a');
+    QTest::keyPress(testWidget, 'b');
+    QCOMPARE(testWidget->text(), QLatin1String("ab"));
+}
+
+QTEST_MAIN(tst_QLineEdit)
+#include "tst_qlineedit.moc"