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