summaryrefslogtreecommitdiffstats
path: root/tests/auto/qlineedit/tst_qlineedit.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:34:13 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:34:13 (GMT)
commit67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch)
tree1dbf50b3dff8d5ca7e9344733968c72704eb15ff /tests/auto/qlineedit/tst_qlineedit.cpp
downloadQt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2
Long live Qt!
Diffstat (limited to 'tests/auto/qlineedit/tst_qlineedit.cpp')
-rw-r--r--tests/auto/qlineedit/tst_qlineedit.cpp3491
1 files changed, 3491 insertions, 0 deletions
diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp
new file mode 100644
index 0000000..87e966f
--- /dev/null
+++ b/tests/auto/qlineedit/tst_qlineedit.cpp
@@ -0,0 +1,3491 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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 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();
+
+ void cut();
+ void copy();
+ void paste();
+
+ 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();
+
+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();
+#ifdef Q_WS_X11
+ // to be safe and avoid failing setFocus with window managers
+ qt_x11_wait_for_window_manager(testWidget);
+#endif
+
+ 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()
+{
+#if (QT_VERSION-0 >= 0x030303)
+ QFETCH( QString, insertString );
+ testWidget->setInputMask( "#" );
+ testWidget->setText( insertString );
+ QCOMPARE( testWidget->text(), insertString );
+#else
+ QSKIP( "This test function tests a problem with masks that was fixed in 3.3", SkipAll);
+#endif
+}
+
+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();
+ QTest::qWait(250);
+ QVERIFY(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();
+
+ 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::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);
+}
+
+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");
+}
+
+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();
+ QTest::qWait(200);
+ mw.activateWindow();
+
+ QSignalSpy editingFinishedSpy(le1, SIGNAL(editingFinished()));
+
+ le1->setFocus();
+ QTest::qWait(200);
+ QVERIFY(le1->hasFocus());
+ QCOMPARE(editingFinishedSpy.count(), 0);
+
+ le2->setFocus();
+ QTest::qWait(200);
+ QVERIFY(le2->hasFocus());
+ QCOMPARE(editingFinishedSpy.count(), 1);
+ editingFinishedSpy.clear();
+
+ le1->setFocus();
+ QTest::qWait(200);
+ QVERIFY(le1->hasFocus());
+
+ QMenu *testMenu1 = new QMenu(le1);
+ testMenu1->addAction("foo");
+ testMenu1->addAction("bar");
+ testMenu1->show();
+ QTest::qWait(200);
+ mw.activateWindow();
+ delete testMenu1;
+ QCOMPARE(editingFinishedSpy.count(), 0);
+ QVERIFY(le1->hasFocus());
+
+ QMenu *testMenu2 = new QMenu(le2);
+ testMenu2->addAction("foo2");
+ testMenu2->addAction("bar2");
+ testMenu2->show();
+ QTest::qWait(200);
+ 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();
+ QTest::qWait(200);
+ 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();
+ QTest::qWait(250);
+
+ 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);
+}
+
+QTEST_MAIN(tst_QLineEdit)
+#include "tst_qlineedit.moc"