0f7cba14f6
Bidi input can in some contexts be more intuitive if the cursor works in visual way: pressing left arrow key always make cursor move one character to the left regardless the language of text, pressing right arrow key always make cursor move to the right. It is also the behavior of Mac OS X. Based on the above reason and requests from Symbian we implemented this support for visual movement in BIDI text. 3 public properties are added to QTextDocument, QTextLayout and QLineEdit respectively: - QTextDocument::defaultCursorMoveStyle can be used to control the cursor behavior in all widgets based on QTextDocument, like QTextEdit, QPlainTextEdit, etc. When set to QTextCursor:: Visual, it will enable visual movement for all the cursors in the corresponding text edit. Default is QTextCursor::Logical. - QTextLayout::cursorMoveStyle is used for low-level cursor manipulation. When set to Visual, it will enable visual movement behavior for all the cursor related methods, including cursorToX, xToCursor and drawCursor. Default is Logical. - QLineEdit::cursorMoveStyle is used to control cursor movement behavior in QLineEdit. Default is Logical.: Task-number: QTBUG-13859 Reviewed-by: Eskil (cherry picked from commit c480dd641f5d22d1ee72cb27bf39e24c6df65658)
3901 lines
118 KiB
C++
3901 lines
118 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$
|
|
** No Commercial Usage
|
|
** This file contains pre-release code and may not be distributed.
|
|
** You may use this file in accordance with the terms and conditions
|
|
** contained in the Technology Preview License Agreement accompanying
|
|
** this package.
|
|
**
|
|
** GNU Lesser General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
** General Public License version 2.1 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
** packaging of this file. Please review the following information to
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
**
|
|
** In addition, as a special exception, Nokia gives you certain additional
|
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
**
|
|
** If you have questions regarding the use of this file, please contact
|
|
** Nokia at qt-info@nokia.com.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
|
|
#include <QtTest/QtTest>
|
|
#include "../../shared/util.h"
|
|
|
|
#include "qlineedit.h"
|
|
#include "qapplication.h"
|
|
#include "qstringlist.h"
|
|
#include "qstyle.h"
|
|
#include "qvalidator.h"
|
|
#include "qcompleter.h"
|
|
#include "qstandarditemmodel.h"
|
|
|
|
#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();
|
|
|
|
#ifdef QT3_SUPPORT
|
|
void validateAndSet_data();
|
|
void validateAndSet();
|
|
#endif
|
|
|
|
void bidiVisualMovement_data();
|
|
void bidiVisualMovement();
|
|
|
|
void bidiLogicalMovement_data();
|
|
void bidiLogicalMovement();
|
|
|
|
protected slots:
|
|
#ifdef QT3_SUPPORT
|
|
void lostFocus();
|
|
#endif
|
|
void editingFinished();
|
|
|
|
void onTextChanged( const QString &newString );
|
|
void onTextEdited( const QString &newString );
|
|
void onReturnPressed();
|
|
void onSelectionChanged();
|
|
void onCursorPositionChanged(int oldpos, int newpos);
|
|
|
|
private:
|
|
// keyClicks(..) is moved to QtTestCase
|
|
void psKeyClick(QWidget *target, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
|
|
void psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
|
|
|
|
bool validInput;
|
|
QString changed_string;
|
|
int changed_count;
|
|
int edited_count;
|
|
int return_count;
|
|
int selection_count;
|
|
int lastCursorPos;
|
|
int newCursorPos;
|
|
QLineEdit *testWidget;
|
|
};
|
|
|
|
typedef QList<int> IntList;
|
|
Q_DECLARE_METATYPE(IntList)
|
|
Q_DECLARE_METATYPE(QLineEdit::EchoMode)
|
|
|
|
// Testing get/set functions
|
|
void tst_QLineEdit::getSetCheck()
|
|
{
|
|
QLineEdit obj1;
|
|
// const QValidator * QLineEdit::validator()
|
|
// void QLineEdit::setValidator(const QValidator *)
|
|
QIntValidator *var1 = new QIntValidator(0);
|
|
obj1.setValidator(var1);
|
|
QCOMPARE((const QValidator *)var1, obj1.validator());
|
|
obj1.setValidator((QValidator *)0);
|
|
QCOMPARE((const QValidator *)0, obj1.validator());
|
|
delete var1;
|
|
|
|
// bool QLineEdit::dragEnabled()
|
|
// void QLineEdit::setDragEnabled(bool)
|
|
obj1.setDragEnabled(false);
|
|
QCOMPARE(false, obj1.dragEnabled());
|
|
obj1.setDragEnabled(true);
|
|
QCOMPARE(true, obj1.dragEnabled());
|
|
}
|
|
|
|
tst_QLineEdit::tst_QLineEdit()
|
|
{
|
|
validInput = false;
|
|
}
|
|
|
|
tst_QLineEdit::~tst_QLineEdit()
|
|
{
|
|
}
|
|
|
|
void tst_QLineEdit::initTestCase()
|
|
{
|
|
testWidget = new QLineEdit(0);
|
|
testWidget->setObjectName("testWidget");
|
|
connect(testWidget, SIGNAL(cursorPositionChanged(int, int)), this, SLOT(onCursorPositionChanged(int, int)));
|
|
connect(testWidget, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
|
|
connect(testWidget, SIGNAL(textEdited(const QString&)), this, SLOT(onTextEdited(const QString&)));
|
|
connect(testWidget, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
|
|
connect(testWidget, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
|
|
connect(testWidget, SIGNAL(editingFinished()), this, SLOT(editingFinished()));
|
|
#ifdef QT3_SUPPORT
|
|
connect(testWidget, SIGNAL(lostFocus()), this, SLOT(lostFocus()));
|
|
#endif
|
|
|
|
testWidget->resize(200,50);
|
|
testWidget->show();
|
|
QApplication::setActiveWindow(testWidget);
|
|
#ifdef Q_WS_X11
|
|
// to be safe and avoid failing setFocus with window managers
|
|
qt_x11_wait_for_window_manager(testWidget);
|
|
#endif
|
|
QTRY_VERIFY(testWidget->hasFocus());
|
|
|
|
changed_count = 0;
|
|
edited_count = 0;
|
|
selection_count = 0;
|
|
}
|
|
|
|
void tst_QLineEdit::cleanupTestCase()
|
|
{
|
|
delete testWidget;
|
|
}
|
|
|
|
void tst_QLineEdit::init()
|
|
{
|
|
return_count = 0;
|
|
testWidget->clear();
|
|
testWidget->setEchoMode(QLineEdit::Normal);
|
|
testWidget->setMaxLength(32767);
|
|
testWidget->setReadOnly(false);
|
|
testWidget->setText("");
|
|
testWidget->setInputMask("");
|
|
testWidget->setFrame(true);
|
|
testWidget->setValidator(0);
|
|
testWidget->setDragEnabled(true);
|
|
}
|
|
|
|
void tst_QLineEdit::cleanup()
|
|
{
|
|
}
|
|
|
|
void tst_QLineEdit::experimental()
|
|
{
|
|
QIntValidator intValidator(3, 7, 0);
|
|
testWidget->setValidator(&intValidator);
|
|
testWidget->setText("");
|
|
|
|
|
|
// test the order of setting these
|
|
testWidget->setInputMask("");
|
|
testWidget->setText("abc123");
|
|
testWidget->setInputMask("000.000.000.000");
|
|
QCOMPARE(testWidget->text(), QString("123..."));
|
|
testWidget->setText("");
|
|
|
|
|
|
}
|
|
|
|
void tst_QLineEdit::upperAndLowercase()
|
|
{
|
|
testWidget->setInputMask("");
|
|
testWidget->setText("");
|
|
|
|
QTest::keyClicks(testWidget, "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?");
|
|
qApp->processEvents();
|
|
QCOMPARE(testWidget->text(), QString("aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?"));
|
|
}
|
|
|
|
void tst_QLineEdit::setInputMask_data()
|
|
{
|
|
QTest::addColumn<QString>("mask");
|
|
QTest::addColumn<QString>("input");
|
|
QTest::addColumn<QString>("expectedText");
|
|
QTest::addColumn<QString>("expectedDisplay");
|
|
QTest::addColumn<bool>("insert_text");
|
|
|
|
// both keyboard and insert()
|
|
for (int i=0; i<2; i++) {
|
|
bool insert_text = i==0 ? false : true;
|
|
QString insert_mode = "keys ";
|
|
if (insert_text)
|
|
insert_mode = "insert ";
|
|
|
|
QTest::newRow(QString(insert_mode + "ip_localhost").toLatin1())
|
|
<< QString("000.000.000.000")
|
|
<< QString("127.0.0.1")
|
|
<< QString("127.0.0.1")
|
|
<< QString("127.0 .0 .1 ")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "mac").toLatin1())
|
|
<< QString("HH:HH:HH:HH:HH:HH;#")
|
|
<< QString("00:E0:81:21:9E:8E")
|
|
<< QString("00:E0:81:21:9E:8E")
|
|
<< QString("00:E0:81:21:9E:8E")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "mac2").toLatin1())
|
|
<< QString("<HH:>HH:!HH:HH:HH:HH;#")
|
|
<< QString("AAe081219E8E")
|
|
<< QString("aa:E0:81:21:9E:8E")
|
|
<< QString("aa:E0:81:21:9E:8E")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "byte").toLatin1())
|
|
<< QString("BBBBBBBB;0")
|
|
<< QString("11011001")
|
|
<< QString("11111")
|
|
<< QString("11011001")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "halfbytes").toLatin1())
|
|
<< QString("bbbb.bbbb;-")
|
|
<< QString("110. 0001")
|
|
<< QString("110.0001")
|
|
<< QString("110-.0001")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "blank char same type as content").toLatin1())
|
|
<< QString("000.000.000.000;0")
|
|
<< QString("127.0.0.1")
|
|
<< QString("127...1")
|
|
<< QString("127.000.000.100")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "parts of ip_localhost").toLatin1())
|
|
<< QString("000.000.000.000")
|
|
<< QString(".0.0.1")
|
|
<< QString(".0.0.1")
|
|
<< QString(" .0 .0 .1 ")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "ip_null").toLatin1())
|
|
<< QString("000.000.000.000")
|
|
<< QString()
|
|
<< QString("...")
|
|
<< QString(" . . . ")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "ip_null_hash").toLatin1())
|
|
<< QString("000.000.000.000;#")
|
|
<< QString()
|
|
<< QString("...")
|
|
<< QString("###.###.###.###")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "ip_overflow").toLatin1())
|
|
<< QString("000.000.000.000")
|
|
<< QString("1234123412341234")
|
|
<< QString("123.412.341.234")
|
|
<< QString("123.412.341.234")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "uppercase").toLatin1())
|
|
<< QString(">AAAA")
|
|
<< QString("AbCd")
|
|
<< QString("ABCD")
|
|
<< QString("ABCD")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "lowercase").toLatin1())
|
|
<< QString("<AAAA")
|
|
<< QString("AbCd")
|
|
<< QString("abcd")
|
|
<< QString("abcd")
|
|
<< bool(insert_text);
|
|
|
|
QTest::newRow(QString(insert_mode + "nocase").toLatin1())
|
|
<< QString("!AAAA")
|
|
<< QString("AbCd")
|
|
<< QString("AbCd")
|
|
<< QString("AbCd")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "nocase1").toLatin1())
|
|
<< QString("!A!A!A!A")
|
|
<< QString("AbCd")
|
|
<< QString("AbCd")
|
|
<< QString("AbCd")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "nocase2").toLatin1())
|
|
<< QString("AAAA")
|
|
<< QString("AbCd")
|
|
<< QString("AbCd")
|
|
<< QString("AbCd")
|
|
<< bool(insert_text);
|
|
|
|
QTest::newRow(QString(insert_mode + "reserved").toLatin1())
|
|
<< QString("{n}[0]")
|
|
<< QString("A9")
|
|
<< QString("A9")
|
|
<< QString("A9")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "escape01").toLatin1())
|
|
<< QString("\\N\\n00")
|
|
<< QString("9")
|
|
<< QString("Nn9")
|
|
<< QString("Nn9 ")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "escape02").toLatin1())
|
|
<< QString("\\\\00")
|
|
<< QString("0")
|
|
<< QString("\\0")
|
|
<< QString("\\0 ")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "escape03").toLatin1())
|
|
<< QString("\\(00\\)")
|
|
<< QString("0")
|
|
<< QString("(0)")
|
|
<< QString("(0 )")
|
|
<< bool(insert_text);
|
|
|
|
QTest::newRow(QString(insert_mode + "upper_lower_nocase1").toLatin1())
|
|
<< QString(">AAAA<AAAA!AAAA")
|
|
<< QString("AbCdEfGhIjKl")
|
|
<< QString("ABCDefghIjKl")
|
|
<< QString("ABCDefghIjKl")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "upper_lower_nocase2").toLatin1())
|
|
<< QString(">aaaa<aaaa!aaaa")
|
|
<< QString("AbCdEfGhIjKl")
|
|
<< QString("ABCDefghIjKl")
|
|
<< QString("ABCDefghIjKl")
|
|
<< bool(insert_text);
|
|
|
|
QTest::newRow(QString(insert_mode + "exact_case1").toLatin1())
|
|
<< QString(">A<A<A>A>A<A!A!A")
|
|
<< QString("AbCdEFGH")
|
|
<< QString("AbcDEfGH")
|
|
<< QString("AbcDEfGH")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "exact_case2").toLatin1())
|
|
<< QString(">A<A<A>A>A<A!A!A")
|
|
<< QString("aBcDefgh")
|
|
<< QString("AbcDEfgh")
|
|
<< QString("AbcDEfgh")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "exact_case3").toLatin1())
|
|
<< QString(">a<a<a>a>a<a!a!a")
|
|
<< QString("AbCdEFGH")
|
|
<< QString("AbcDEfGH")
|
|
<< QString("AbcDEfGH")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "exact_case4").toLatin1())
|
|
<< QString(">a<a<a>a>a<a!a!a")
|
|
<< QString("aBcDefgh")
|
|
<< QString("AbcDEfgh")
|
|
<< QString("AbcDEfgh")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "exact_case5").toLatin1())
|
|
<< QString(">H<H<H>H>H<H!H!H")
|
|
<< QString("aBcDef01")
|
|
<< QString("AbcDEf01")
|
|
<< QString("AbcDEf01")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "exact_case6").toLatin1())
|
|
<< QString(">h<h<h>h>h<h!h!h")
|
|
<< QString("aBcDef92")
|
|
<< QString("AbcDEf92")
|
|
<< QString("AbcDEf92")
|
|
<< bool(insert_text);
|
|
|
|
QTest::newRow(QString(insert_mode + "illegal_keys1").toLatin1())
|
|
<< QString("AAAAAAAA")
|
|
<< QString("A2#a;.0!")
|
|
<< QString("Aa")
|
|
<< QString("Aa ")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "illegal_keys2").toLatin1())
|
|
<< QString("AAAA")
|
|
<< QString("f4f4f4f4")
|
|
<< QString("ffff")
|
|
<< QString("ffff")
|
|
<< bool(insert_text);
|
|
QTest::newRow(QString(insert_mode + "blank=input").toLatin1())
|
|
<< QString("9999;0")
|
|
<< QString("2004")
|
|
<< QString("2004")
|
|
<< QString("2004")
|
|
<< bool(insert_text);
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::setInputMask()
|
|
{
|
|
QFETCH(QString, mask);
|
|
QFETCH(QString, input);
|
|
QFETCH(QString, expectedText);
|
|
QFETCH(QString, expectedDisplay);
|
|
QFETCH(bool, insert_text);
|
|
|
|
QEXPECT_FAIL( "keys blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
|
|
QEXPECT_FAIL( "insert blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
|
|
|
|
// First set the input mask
|
|
testWidget->setInputMask(mask);
|
|
|
|
// then either insert using insert() or keyboard
|
|
if (insert_text) {
|
|
testWidget->insert(input);
|
|
} else {
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
for (int i=0; i<input.length(); i++)
|
|
QTest::keyClick(testWidget, input.at(i).toLatin1());
|
|
}
|
|
|
|
QCOMPARE(testWidget->text(), expectedText);
|
|
QCOMPARE(testWidget->displayText(), expectedDisplay);
|
|
}
|
|
|
|
void tst_QLineEdit::inputMask_data()
|
|
{
|
|
QTest::addColumn<QString>("mask");
|
|
QTest::addColumn<QString>("expectedMask");
|
|
|
|
// if no mask is set a nul string should be returned
|
|
QTest::newRow("") << QString("") << QString();
|
|
QTest::newRow("") << QString() << QString();
|
|
|
|
// try different masks
|
|
QTest::newRow("") << QString("000.000.000.000") << QString("000.000.000.000; ");
|
|
QTest::newRow("") << QString("000.000.000.000;#") << QString("000.000.000.000;#");
|
|
QTest::newRow("") << QString("AAA.aa.999.###;") << QString("AAA.aa.999.###; ");
|
|
QTest::newRow("") << QString(">abcdef<GHIJK") << QString(">abcdef<GHIJK; ");
|
|
// QTest::newRow("") << QString() << QString();
|
|
|
|
// set an invalid input mask...
|
|
// the current behaviour is that this exact (faulty) string is returned.
|
|
QTest::newRow("") << QString("ABCDEFGHIKLMNOP;") << QString("ABCDEFGHIKLMNOP; ");
|
|
|
|
// verify that we can unset the mask again
|
|
QTest::newRow("") << QString("") << QString();
|
|
}
|
|
|
|
void tst_QLineEdit::inputMask()
|
|
{
|
|
QFETCH(QString, mask);
|
|
QFETCH(QString, expectedMask);
|
|
|
|
testWidget->setInputMask(mask);
|
|
QCOMPARE(testWidget->inputMask(), expectedMask);
|
|
}
|
|
|
|
void tst_QLineEdit::clearInputMask()
|
|
{
|
|
testWidget->setInputMask("000.000.000.000");
|
|
QVERIFY(testWidget->inputMask() != QString::null);
|
|
testWidget->setInputMask(QString::null);
|
|
QCOMPARE(testWidget->inputMask(), QString());
|
|
}
|
|
|
|
void tst_QLineEdit::keypress_inputMask_data()
|
|
{
|
|
QTest::addColumn<QString>("mask");
|
|
QTest::addColumn<QTestEventList>("keys");
|
|
QTest::addColumn<QString>("expectedText");
|
|
QTest::addColumn<QString>("expectedDisplayText");
|
|
|
|
{
|
|
QTestEventList keys;
|
|
// inserting 'A1.2B'
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_Period);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
QTest::newRow("jumping on period(separator)") << QString("000.000;_") << keys << QString("1.2") << QString("1__.2__");
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
// inserting 'A1.2B'
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_0);
|
|
keys.addKeyClick(Qt::Key_Exclam);
|
|
keys.addKeyClick('P');
|
|
keys.addKeyClick(Qt::Key_3);
|
|
QTest::newRow("jumping on input") << QString("D0.AA.XX.AA.00;_") << keys << QString("0..!P..3") << QString("_0.__.!P.__.3_");
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
// pressing delete
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_Delete);
|
|
QTest::newRow("delete") << QString("000.000;_") << keys << QString(".") << QString("___.___");
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
// selecting all and delete
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_End, Qt::ShiftModifier);
|
|
keys.addKeyClick(Qt::Key_Delete);
|
|
QTest::newRow("deleting all") << QString("000.000;_") << keys << QString(".") << QString("___.___");
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
// inserting '12.12' then two backspaces
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_Period);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_Backspace);
|
|
keys.addKeyClick(Qt::Key_Backspace);
|
|
QTest::newRow("backspace") << QString("000.000;_") << keys << QString("12.") << QString("12_.___");
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
// inserting '12ab'
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
QTest::newRow("uppercase") << QString("9999 >AA;_") << keys << QString("12 AB") << QString("12__ AB");
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::keypress_inputMask()
|
|
{
|
|
QFETCH(QString, mask);
|
|
QFETCH(QTestEventList, keys);
|
|
QFETCH(QString, expectedText);
|
|
QFETCH(QString, expectedDisplayText);
|
|
|
|
testWidget->setInputMask(mask);
|
|
keys.simulate(testWidget);
|
|
|
|
QCOMPARE(testWidget->text(), expectedText);
|
|
QCOMPARE(testWidget->displayText(), expectedDisplayText);
|
|
}
|
|
|
|
|
|
void tst_QLineEdit::hasAcceptableInputMask_data()
|
|
{
|
|
QTest::addColumn<QString>("optionalMask");
|
|
QTest::addColumn<QString>("requiredMask");
|
|
QTest::addColumn<QString>("invalid");
|
|
QTest::addColumn<QString>("valid");
|
|
|
|
QTest::newRow("Alphabetic optional and required")
|
|
<< QString("aaaa") << QString("AAAA") << QString("ab") << QString("abcd");
|
|
QTest::newRow("Alphanumeric optional and require")
|
|
<< QString("nnnn") << QString("NNNN") << QString("R2") << QString("R2D2");
|
|
QTest::newRow("Any optional and required")
|
|
<< QString("xxxx") << QString("XXXX") << QString("+-") << QString("+-*/");
|
|
QTest::newRow("Numeric (0-9) required")
|
|
<< QString("0000") << QString("9999") << QString("11") << QString("1138");
|
|
QTest::newRow("Numeric (1-9) optional and required")
|
|
<< QString("dddd") << QString("DDDD") << QString("12") << QString("1234");
|
|
}
|
|
|
|
void tst_QLineEdit::hasAcceptableInputMask()
|
|
{
|
|
QFocusEvent lostFocus(QEvent::FocusOut);
|
|
QFETCH(QString, optionalMask);
|
|
QFETCH(QString, requiredMask);
|
|
QFETCH(QString, invalid);
|
|
QFETCH(QString, valid);
|
|
|
|
// test that invalid input (for required) work for optionalMask
|
|
testWidget->setInputMask(optionalMask);
|
|
validInput = false;
|
|
testWidget->setText(invalid);
|
|
qApp->sendEvent(testWidget, &lostFocus);
|
|
QVERIFY(validInput);
|
|
|
|
// at the moment we don't strip the blank character if it is valid input, this makes the test between x vs X useless
|
|
QEXPECT_FAIL( "Any optional and required", "To eat blanks or not? Known issue. Task 43172", Abort);
|
|
|
|
// test requiredMask
|
|
testWidget->setInputMask(requiredMask);
|
|
validInput = true;
|
|
testWidget->setText(invalid);
|
|
validInput = testWidget->hasAcceptableInput();
|
|
QVERIFY(!validInput);
|
|
|
|
validInput = false;
|
|
testWidget->setText(valid);
|
|
qApp->sendEvent(testWidget, &lostFocus);
|
|
QVERIFY(validInput);
|
|
}
|
|
|
|
static const int chars = 8;
|
|
class ValidatorWithFixup : public QValidator
|
|
{
|
|
public:
|
|
ValidatorWithFixup(QWidget *parent = 0)
|
|
: QValidator(parent)
|
|
{}
|
|
|
|
QValidator::State validate(QString &str, int &) const
|
|
{
|
|
const int s = str.size();
|
|
if (s < chars) {
|
|
return Intermediate;
|
|
} else if (s > chars) {
|
|
return Invalid;
|
|
}
|
|
return Acceptable;
|
|
}
|
|
|
|
void fixup(QString &str) const
|
|
{
|
|
str = str.leftJustified(chars, 'X', true);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
void tst_QLineEdit::hasAcceptableInputValidator()
|
|
{
|
|
QFocusEvent lostFocus(QEvent::FocusOut);
|
|
ValidatorWithFixup val;
|
|
testWidget->setValidator(&val);
|
|
testWidget->setText("foobar");
|
|
qApp->sendEvent(testWidget, &lostFocus);
|
|
QVERIFY(testWidget->hasAcceptableInput());
|
|
}
|
|
|
|
|
|
|
|
void tst_QLineEdit::maskCharacter_data()
|
|
{
|
|
QTest::addColumn<QString>("mask");
|
|
QTest::addColumn<QString>("input");
|
|
QTest::addColumn<bool>("expectedValid");
|
|
|
|
QTest::newRow("Hex") << QString("H")
|
|
<< QString("0123456789abcdefABCDEF") << true;
|
|
QTest::newRow("hex") << QString("h")
|
|
<< QString("0123456789abcdefABCDEF") << true;
|
|
QTest::newRow("HexInvalid") << QString("H")
|
|
<< QString("ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ")
|
|
<< false;
|
|
QTest::newRow("hexInvalid") << QString("h")
|
|
<< QString("ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ")
|
|
<< false;
|
|
QTest::newRow("Bin") << QString("B")
|
|
<< QString("01") << true;
|
|
QTest::newRow("bin") << QString("b")
|
|
<< QString("01") << true;
|
|
QTest::newRow("BinInvalid") << QString("B")
|
|
<< QString("23456789qwertyuiopasdfghjklzxcvbnm")
|
|
<< false;
|
|
QTest::newRow("binInvalid") << QString("b")
|
|
<< QString("23456789qwertyuiopasdfghjklzxcvbnm")
|
|
<< false;
|
|
}
|
|
|
|
void tst_QLineEdit::maskCharacter()
|
|
{
|
|
QFETCH(QString, mask);
|
|
QFETCH(QString, input);
|
|
QFETCH(bool, expectedValid);
|
|
|
|
QFocusEvent lostFocus(QEvent::FocusOut);
|
|
|
|
testWidget->setInputMask(mask);
|
|
for (int i = 0; i < input.size(); ++i) {
|
|
QString in = QString(input.at(i));
|
|
QString expected = expectedValid ? in : QString();
|
|
testWidget->setText(QString(input.at(i)));
|
|
qApp->sendEvent(testWidget, &lostFocus);
|
|
QCOMPARE(testWidget->text(), expected);
|
|
}
|
|
}
|
|
|
|
#define NORMAL 0
|
|
#define REPLACE_UNTIL_END 1
|
|
|
|
void tst_QLineEdit::undo_data()
|
|
{
|
|
QTest::addColumn<QStringList>("insertString");
|
|
QTest::addColumn<IntList>("insertIndex");
|
|
QTest::addColumn<IntList>("insertMode");
|
|
QTest::addColumn<QStringList>("expectedString");
|
|
QTest::addColumn<bool>("use_keys");
|
|
|
|
for (int i=0; i<2; i++) {
|
|
QString keys_str = "keyboard";
|
|
bool use_keys = true;
|
|
if (i==0) {
|
|
keys_str = "insert";
|
|
use_keys = false;
|
|
}
|
|
|
|
{
|
|
IntList insertIndex;
|
|
IntList insertMode;
|
|
QStringList insertString;
|
|
QStringList expectedString;
|
|
|
|
insertIndex << -1;
|
|
insertMode << NORMAL;
|
|
insertString << "1";
|
|
|
|
insertIndex << -1;
|
|
insertMode << NORMAL;
|
|
insertString << "5";
|
|
|
|
insertIndex << 1;
|
|
insertMode << NORMAL;
|
|
insertString << "3";
|
|
|
|
insertIndex << 1;
|
|
insertMode << NORMAL;
|
|
insertString << "2";
|
|
|
|
insertIndex << 3;
|
|
insertMode << NORMAL;
|
|
insertString << "4";
|
|
|
|
expectedString << "12345";
|
|
expectedString << "1235";
|
|
expectedString << "135";
|
|
expectedString << "15";
|
|
expectedString << "";
|
|
|
|
QTest::newRow(QString(keys_str + "_numbers").toLatin1()) <<
|
|
insertString <<
|
|
insertIndex <<
|
|
insertMode <<
|
|
expectedString <<
|
|
bool(use_keys);
|
|
}
|
|
{
|
|
IntList insertIndex;
|
|
IntList insertMode;
|
|
QStringList insertString;
|
|
QStringList expectedString;
|
|
|
|
insertIndex << -1;
|
|
insertMode << NORMAL;
|
|
insertString << "World"; // World
|
|
|
|
insertIndex << 0;
|
|
insertMode << NORMAL;
|
|
insertString << "Hello"; // HelloWorld
|
|
|
|
insertIndex << 0;
|
|
insertMode << NORMAL;
|
|
insertString << "Well"; // WellHelloWorld
|
|
|
|
insertIndex << 9;
|
|
insertMode << NORMAL;
|
|
insertString << "There"; // WellHelloThereWorld;
|
|
|
|
expectedString << "WellHelloThereWorld";
|
|
expectedString << "WellHelloWorld";
|
|
expectedString << "HelloWorld";
|
|
expectedString << "World";
|
|
expectedString << "";
|
|
|
|
QTest::newRow(QString(keys_str + "_helloworld").toLatin1()) <<
|
|
insertString <<
|
|
insertIndex <<
|
|
insertMode <<
|
|
expectedString <<
|
|
bool(use_keys);
|
|
}
|
|
{
|
|
IntList insertIndex;
|
|
IntList insertMode;
|
|
QStringList insertString;
|
|
QStringList expectedString;
|
|
|
|
insertIndex << -1;
|
|
insertMode << NORMAL;
|
|
insertString << "Ensuring";
|
|
|
|
insertIndex << -1;
|
|
insertMode << NORMAL;
|
|
insertString << " instan";
|
|
|
|
insertIndex << 9;
|
|
insertMode << NORMAL;
|
|
insertString << "an ";
|
|
|
|
insertIndex << 10;
|
|
insertMode << REPLACE_UNTIL_END;
|
|
insertString << " unique instance.";
|
|
|
|
expectedString << "Ensuring a unique instance.";
|
|
expectedString << "Ensuring an instan";
|
|
expectedString << "Ensuring instan";
|
|
expectedString << "";
|
|
|
|
QTest::newRow(QString(keys_str + "_patterns").toLatin1()) <<
|
|
insertString <<
|
|
insertIndex <<
|
|
insertMode <<
|
|
expectedString <<
|
|
bool(use_keys);
|
|
}
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::undo()
|
|
{
|
|
QFETCH(QStringList, insertString);
|
|
QFETCH(IntList, insertIndex);
|
|
QFETCH(IntList, insertMode);
|
|
QFETCH(QStringList, expectedString);
|
|
QFETCH(bool, use_keys);
|
|
|
|
QVERIFY(!testWidget->isUndoAvailable());
|
|
|
|
int i;
|
|
|
|
// STEP 1: First build up an undo history by inserting or typing some strings...
|
|
for (i=0; i<insertString.size(); ++i) {
|
|
if (insertIndex[i] > -1)
|
|
testWidget->setCursorPosition(insertIndex[i]);
|
|
|
|
// experimental stuff
|
|
if (insertMode[i] == REPLACE_UNTIL_END) {
|
|
testWidget->setSelection(insertIndex[i], 8);
|
|
|
|
// This is what I actually want...
|
|
// QTest::keyClick(testWidget, Qt::Key_End, Qt::ShiftModifier);
|
|
}
|
|
|
|
if (use_keys)
|
|
QTest::keyClicks(testWidget, insertString[i]);
|
|
else
|
|
testWidget->insert(insertString[i]);
|
|
}
|
|
|
|
// STEP 2: Next call undo several times and see if we can restore to the previous state
|
|
for (i=0; i<expectedString.size()-1; ++i) {
|
|
QCOMPARE(testWidget->text(), expectedString[i]);
|
|
QVERIFY(testWidget->isUndoAvailable());
|
|
testWidget->undo();
|
|
}
|
|
|
|
// STEP 3: Verify that we have undone everything
|
|
QVERIFY(!testWidget->isUndoAvailable());
|
|
QVERIFY(testWidget->text().isEmpty());
|
|
|
|
#ifdef Q_WS_WIN
|
|
// Repeat the test using shortcut instead of undo()
|
|
for (i=0; i<insertString.size(); ++i) {
|
|
if (insertIndex[i] > -1)
|
|
testWidget->setCursorPosition(insertIndex[i]);
|
|
if (insertMode[i] == REPLACE_UNTIL_END) {
|
|
testWidget->setSelection(insertIndex[i], 8);
|
|
}
|
|
if (use_keys)
|
|
QTest::keyClicks(testWidget, insertString[i]);
|
|
else
|
|
testWidget->insert(insertString[i]);
|
|
}
|
|
for (i=0; i<expectedString.size()-1; ++i) {
|
|
QCOMPARE(testWidget->text(), expectedString[i]);
|
|
QVERIFY(testWidget->isUndoAvailable());
|
|
QTest::keyClick(testWidget, Qt::Key_Backspace, Qt::AltModifier);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void tst_QLineEdit::isUndoAvailable()
|
|
{
|
|
DEPENDS_ON("undo");
|
|
}
|
|
|
|
void tst_QLineEdit::redo_data()
|
|
{
|
|
QTest::addColumn<QStringList>("insertString");
|
|
QTest::addColumn<IntList>("insertIndex");
|
|
QTest::addColumn<QStringList>("expectedString");
|
|
|
|
{
|
|
IntList insertIndex;
|
|
QStringList insertString;
|
|
QStringList expectedString;
|
|
|
|
insertIndex << -1;
|
|
insertString << "World"; // World
|
|
insertIndex << 0;
|
|
insertString << "Hello"; // HelloWorld
|
|
insertIndex << 0;
|
|
insertString << "Well"; // WellHelloWorld
|
|
insertIndex << 9;
|
|
insertString << "There"; // WellHelloThereWorld;
|
|
|
|
expectedString << "World";
|
|
expectedString << "HelloWorld";
|
|
expectedString << "WellHelloWorld";
|
|
expectedString << "WellHelloThereWorld";
|
|
|
|
QTest::newRow("Inserts and setting cursor") << insertString << insertIndex << expectedString;
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::redo()
|
|
{
|
|
QFETCH(QStringList, insertString);
|
|
QFETCH(IntList, insertIndex);
|
|
QFETCH(QStringList, expectedString);
|
|
|
|
QVERIFY(!testWidget->isUndoAvailable());
|
|
QVERIFY(!testWidget->isRedoAvailable());
|
|
|
|
int i;
|
|
// inserts the diff strings at diff positions
|
|
for (i=0; i<insertString.size(); ++i) {
|
|
if (insertIndex[i] > -1)
|
|
testWidget->setCursorPosition(insertIndex[i]);
|
|
testWidget->insert(insertString[i]);
|
|
}
|
|
|
|
QVERIFY(!testWidget->isRedoAvailable());
|
|
|
|
// undo everything
|
|
while (!testWidget->text().isEmpty())
|
|
testWidget->undo();
|
|
|
|
for (i=0; i<expectedString.size(); ++i) {
|
|
QVERIFY(testWidget->isRedoAvailable());
|
|
testWidget->redo();
|
|
QCOMPARE(testWidget->text() , expectedString[i]);
|
|
}
|
|
|
|
QVERIFY(!testWidget->isRedoAvailable());
|
|
|
|
#ifdef Q_WS_WIN
|
|
// repeat test, this time using shortcuts instead of undo()/redo()
|
|
|
|
while (!testWidget->text().isEmpty())
|
|
QTest::keyClick(testWidget, Qt::Key_Backspace, Qt::AltModifier);
|
|
|
|
for (i = 0; i < expectedString.size(); ++i) {
|
|
QVERIFY(testWidget->isRedoAvailable());
|
|
QTest::keyClick(testWidget, Qt::Key_Backspace,
|
|
Qt::ShiftModifier | Qt::AltModifier);
|
|
QCOMPARE(testWidget->text() , expectedString[i]);
|
|
}
|
|
|
|
QVERIFY(!testWidget->isRedoAvailable());
|
|
#endif
|
|
}
|
|
|
|
void tst_QLineEdit::isRedoAvailable()
|
|
{
|
|
DEPENDS_ON("redo");
|
|
}
|
|
|
|
void tst_QLineEdit::undo_keypressevents_data()
|
|
{
|
|
QTest::addColumn<QTestEventList>("keys");
|
|
QTest::addColumn<QStringList>("expectedString");
|
|
|
|
{
|
|
QTestEventList keys;
|
|
QStringList expectedString;
|
|
|
|
keys.addKeyClick('A');
|
|
keys.addKeyClick('F');
|
|
keys.addKeyClick('R');
|
|
keys.addKeyClick('A');
|
|
keys.addKeyClick('I');
|
|
keys.addKeyClick('D');
|
|
psKeyClick(keys, Qt::Key_Home);
|
|
|
|
keys.addKeyClick('V');
|
|
keys.addKeyClick('E');
|
|
keys.addKeyClick('R');
|
|
keys.addKeyClick('Y');
|
|
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
|
|
keys.addKeyClick('B');
|
|
keys.addKeyClick('E');
|
|
psKeyClick(keys, Qt::Key_End);
|
|
|
|
keys.addKeyClick(Qt::Key_Exclam);
|
|
|
|
expectedString << "BEVERYAFRAID!";
|
|
expectedString << "BEVERYAFRAID";
|
|
expectedString << "VERYAFRAID";
|
|
expectedString << "AFRAID";
|
|
|
|
QTest::newRow("Inserts and moving cursor") << keys << expectedString;
|
|
}
|
|
|
|
{
|
|
QTestEventList keys;
|
|
QStringList expectedString;
|
|
|
|
// inserting '1234'
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_3);
|
|
keys.addKeyClick(Qt::Key_4);
|
|
psKeyClick(keys, Qt::Key_Home);
|
|
|
|
// skipping '12'
|
|
keys.addKeyClick(Qt::Key_Right);
|
|
keys.addKeyClick(Qt::Key_Right);
|
|
|
|
// selecting '34'
|
|
keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
|
|
keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
|
|
|
|
// deleting '34'
|
|
keys.addKeyClick(Qt::Key_Delete);
|
|
|
|
expectedString << "12";
|
|
expectedString << "1234";
|
|
|
|
QTest::newRow("Inserts,moving,selection and delete") << keys << expectedString;
|
|
}
|
|
|
|
{
|
|
QTestEventList keys;
|
|
QStringList expectedString;
|
|
|
|
// inserting 'AB12'
|
|
keys.addKeyClick('A');
|
|
keys.addKeyClick('B');
|
|
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
|
|
psKeyClick(keys, Qt::Key_Home);
|
|
|
|
// selecting 'AB'
|
|
keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
|
|
keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
|
|
|
|
// deleting 'AB'
|
|
keys.addKeyClick(Qt::Key_Delete);
|
|
|
|
// undoing deletion of 'AB'
|
|
keys.addKeyClick(Qt::Key_Z, Qt::ControlModifier);
|
|
|
|
// unselect any current selection
|
|
keys.addKeyClick(Qt::Key_Right);
|
|
#ifdef Q_WS_WIN //Mac has a specialcase to handle jumping to the end of a selection
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
#endif
|
|
|
|
// selecting '12'
|
|
keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
|
|
keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
|
|
|
|
// deleting '12'
|
|
keys.addKeyClick(Qt::Key_Delete);
|
|
|
|
expectedString << "AB";
|
|
expectedString << "AB12";
|
|
|
|
QTest::newRow("Inserts,moving,selection, delete and undo") << keys << expectedString;
|
|
}
|
|
|
|
{
|
|
QTestEventList keys;
|
|
QStringList expectedString;
|
|
|
|
// inserting 'ABCD'
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_D);
|
|
|
|
//move left two
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
|
|
// inserting '1234'
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_3);
|
|
keys.addKeyClick(Qt::Key_4);
|
|
|
|
// selecting '1234'
|
|
keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
|
|
keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
|
|
keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
|
|
keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
|
|
|
|
// overwriting '1234' with '5'
|
|
keys.addKeyClick(Qt::Key_5);
|
|
|
|
// undoing deletion of 'AB'
|
|
keys.addKeyClick(Qt::Key_Z, Qt::ControlModifier);
|
|
|
|
// overwriting '1234' with '6'
|
|
keys.addKeyClick(Qt::Key_6);
|
|
|
|
expectedString << "ab6cd";
|
|
// for versions previous to 3.2 we overwrite needed two undo operations
|
|
expectedString << "ab1234cd";
|
|
expectedString << "abcd";
|
|
|
|
QTest::newRow("Inserts,moving,selection and undo, removing selection") << keys << expectedString;
|
|
}
|
|
|
|
{
|
|
QTestEventList keys;
|
|
QStringList expectedString;
|
|
|
|
// inserting 'ABC'
|
|
keys.addKeyClick('A');
|
|
keys.addKeyClick('B');
|
|
keys.addKeyClick('C');
|
|
|
|
// removes 'C'
|
|
keys.addKeyClick(Qt::Key_Backspace);
|
|
|
|
expectedString << "AB";
|
|
expectedString << "ABC";
|
|
|
|
QTest::newRow("Inserts,backspace") << keys << expectedString;
|
|
}
|
|
|
|
{
|
|
QTestEventList keys;
|
|
QStringList expectedString;
|
|
|
|
// inserting 'ABC'
|
|
keys.addKeyClick('A');
|
|
keys.addKeyClick('B');
|
|
keys.addKeyClick('C');
|
|
|
|
// removes 'C'
|
|
keys.addKeyClick(Qt::Key_Backspace);
|
|
|
|
// inserting 'Z'
|
|
keys.addKeyClick('Z');
|
|
|
|
expectedString << "ABZ";
|
|
expectedString << "AB";
|
|
expectedString << "ABC";
|
|
|
|
QTest::newRow("Inserts,backspace,inserts") << keys << expectedString;
|
|
}
|
|
|
|
|
|
{
|
|
QTestEventList keys;
|
|
QStringList expectedString;
|
|
|
|
// inserting '123'
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_3);
|
|
psKeyClick(keys, Qt::Key_Home);
|
|
|
|
// selecting '123'
|
|
psKeyClick(keys, Qt::Key_End, Qt::ShiftModifier);
|
|
|
|
// overwriting '123' with 'ABC'
|
|
keys.addKeyClick('A');
|
|
keys.addKeyClick('B');
|
|
keys.addKeyClick('C');
|
|
|
|
expectedString << "ABC";
|
|
// for versions previous to 3.2 we overwrite needed two undo operations
|
|
expectedString << "123";
|
|
|
|
QTest::newRow("Inserts,moving,selection and overwriting") << keys << expectedString;
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::undo_keypressevents()
|
|
{
|
|
QFETCH(QTestEventList, keys);
|
|
QFETCH(QStringList, expectedString);
|
|
|
|
keys.simulate(testWidget);
|
|
|
|
for (int i=0; i<expectedString.size(); ++i) {
|
|
QCOMPARE(testWidget->text() , expectedString[i]);
|
|
testWidget->undo();
|
|
}
|
|
QVERIFY(testWidget->text().isEmpty());
|
|
}
|
|
|
|
#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"));
|
|
}
|
|
|
|
#ifdef QT3_SUPPORT
|
|
void tst_QLineEdit::lostFocus()
|
|
{
|
|
editingFinished();
|
|
}
|
|
|
|
void tst_QLineEdit::validateAndSet_data()
|
|
{
|
|
QTest::addColumn<QString>("newText");
|
|
QTest::addColumn<int>("newPos");
|
|
QTest::addColumn<int>("newMarkAnchor");
|
|
QTest::addColumn<int>("newMarkDrag");
|
|
|
|
QTest::newRow("1") << QString("Hello World") << 3 << 3 << 5;
|
|
QTest::newRow("2") << QString("Hello World") << 5 << 3 << 5;
|
|
}
|
|
|
|
void tst_QLineEdit::validateAndSet()
|
|
{
|
|
QFETCH(QString, newText);
|
|
QFETCH(int, newPos);
|
|
QFETCH(int, newMarkAnchor);
|
|
QFETCH(int, newMarkDrag);
|
|
|
|
QLineEdit e;
|
|
e.validateAndSet(newText, newPos, newMarkAnchor, newMarkDrag);
|
|
QCOMPARE(e.text(), newText);
|
|
QCOMPARE(e.cursorPosition(), newPos);
|
|
QCOMPARE(e.selectedText(), newText.mid(newMarkAnchor, newMarkDrag-newMarkAnchor));
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
void tst_QLineEdit::editingFinished()
|
|
{
|
|
if (testWidget->hasAcceptableInput())
|
|
validInput = true;
|
|
else
|
|
validInput = false;
|
|
}
|
|
|
|
void tst_QLineEdit::text_data()
|
|
{
|
|
QTest::addColumn<QString>("insertString");
|
|
|
|
QTest::newRow("Plain text0") << QString("Hello World");
|
|
QTest::newRow("Plain text1") << QString("");
|
|
QTest::newRow("Plain text2") << QString("A");
|
|
QTest::newRow("Plain text3") << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry");
|
|
QTest::newRow("Plain text4") << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"");
|
|
QTest::newRow("Newlines") << QString("A\nB\nC\n");
|
|
QTest::newRow("Text with nbsp") << QString("Hello") + QChar(0xa0) + "World";
|
|
}
|
|
|
|
void tst_QLineEdit::text()
|
|
{
|
|
QFETCH(QString, insertString);
|
|
testWidget->setText(insertString);
|
|
QCOMPARE(testWidget->text(), insertString);
|
|
}
|
|
|
|
void tst_QLineEdit::textMask_data()
|
|
{
|
|
QTest::addColumn<QString>("insertString");
|
|
|
|
QTest::newRow( "Plain text1" ) << QString( "" );
|
|
}
|
|
|
|
void tst_QLineEdit::textMask()
|
|
{
|
|
QFETCH( QString, insertString );
|
|
testWidget->setInputMask( "#" );
|
|
testWidget->setText( insertString );
|
|
QCOMPARE( testWidget->text(), insertString );
|
|
}
|
|
|
|
void tst_QLineEdit::setText()
|
|
{
|
|
QSignalSpy editedSpy(testWidget, SIGNAL(textEdited(QString)));
|
|
QSignalSpy changedSpy(testWidget, SIGNAL(textChanged(QString)));
|
|
testWidget->setText("hello");
|
|
QCOMPARE(editedSpy.count(), 0);
|
|
QCOMPARE(changedSpy.value(0).value(0).toString(), QString("hello"));
|
|
}
|
|
|
|
void tst_QLineEdit::displayText_data()
|
|
{
|
|
QTest::addColumn<QString>("insertString");
|
|
QTest::addColumn<QString>("expectedString");
|
|
QTest::addColumn<QLineEdit::EchoMode>("mode");
|
|
QTest::addColumn<bool>("use_setText");
|
|
|
|
QString s;
|
|
QLineEdit::EchoMode m;
|
|
|
|
for (int i=0; i<2; i++) {
|
|
QString key_mode_str;
|
|
bool use_setText;
|
|
if (i==0) {
|
|
key_mode_str = "setText_";
|
|
use_setText = true;
|
|
} else {
|
|
key_mode_str = "useKeys_";
|
|
use_setText = false;
|
|
}
|
|
s = key_mode_str + "Normal";
|
|
m = QLineEdit::Normal;
|
|
QTest::newRow(QString(s + " text0").toLatin1()) << QString("Hello World") <<
|
|
QString("Hello World") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") <<
|
|
QString("A") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text3").toLatin1()) << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
|
|
QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text4").toLatin1()) << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
|
|
QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text with nbsp").toLatin1()) << QString("Hello") + QChar(0xa0) + "World" <<
|
|
QString("Hello") + QChar(0xa0) + "World" <<
|
|
m << bool(use_setText);
|
|
s = key_mode_str + "NoEcho";
|
|
m = QLineEdit::NoEcho;
|
|
QTest::newRow(QString(s + " text0").toLatin1()) << QString("Hello World") <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text3").toLatin1()) << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text4").toLatin1()) << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text with nbsp").toLatin1()) << QString("Hello") + QChar(0xa0) + "World" <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
s = key_mode_str + "Password";
|
|
m = QLineEdit::Password;
|
|
QChar passChar = qApp->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, 0, testWidget);
|
|
QString input;
|
|
QString pass;
|
|
input = "Hello World";
|
|
pass.resize(input.length());
|
|
pass.fill(passChar);
|
|
QTest::newRow(QString(s + " text0").toLatin1()) << input << pass << m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
|
|
QString("") <<
|
|
m << bool(use_setText);
|
|
QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") << QString(passChar) << m << bool(use_setText);
|
|
input = QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry");
|
|
pass.resize(input.length());
|
|
pass.fill(passChar);
|
|
QTest::newRow(QString(s + " text3").toLatin1()) << input << pass << m << bool(use_setText);
|
|
input = QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"");
|
|
pass.fill(passChar, input.length());
|
|
QTest::newRow(QString(s + " text4").toLatin1()) << input << pass << m << bool(use_setText);
|
|
input = QString("Hello") + QChar(0xa0) + "World";
|
|
pass.resize(input.length());
|
|
pass.fill(passChar);
|
|
QTest::newRow(QString(s + " text with nbsp").toLatin1()) << input << pass << m << bool(use_setText);
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::displayText()
|
|
{
|
|
QFETCH(QString, insertString);
|
|
QFETCH(QString, expectedString);
|
|
QFETCH(QLineEdit::EchoMode, mode);
|
|
//QFETCH(bool, use_setText); Currently unused.
|
|
|
|
testWidget->setEchoMode(mode);
|
|
testWidget->setText(insertString);
|
|
QCOMPARE(testWidget->displayText(), expectedString);
|
|
QVERIFY(testWidget->echoMode() == mode);
|
|
}
|
|
|
|
void tst_QLineEdit::setEchoMode()
|
|
{
|
|
DEPENDS_ON("displayText");
|
|
}
|
|
|
|
void tst_QLineEdit::echoMode()
|
|
{
|
|
DEPENDS_ON("displayText");
|
|
}
|
|
|
|
void tst_QLineEdit::passwordEchoOnEdit()
|
|
{
|
|
QStyleOptionFrameV2 opt;
|
|
QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
|
|
|
|
testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
|
|
testWidget->setFocus();
|
|
testWidget->raise();
|
|
QTRY_VERIFY(testWidget->hasFocus());
|
|
|
|
QTest::keyPress(testWidget, '0');
|
|
QTest::keyPress(testWidget, '1');
|
|
QTest::keyPress(testWidget, '2');
|
|
QTest::keyPress(testWidget, '3');
|
|
QTest::keyPress(testWidget, '4');
|
|
QCOMPARE(testWidget->displayText(), QString("01234"));
|
|
testWidget->clearFocus();
|
|
QVERIFY(!testWidget->hasFocus());
|
|
QCOMPARE(testWidget->displayText(), QString(5, fillChar));
|
|
testWidget->setFocus();
|
|
QTRY_VERIFY(testWidget->hasFocus());
|
|
|
|
QCOMPARE(testWidget->displayText(), QString(5, fillChar));
|
|
QTest::keyPress(testWidget, '0');
|
|
QCOMPARE(testWidget->displayText(), QString("0"));
|
|
|
|
// restore clean state
|
|
testWidget->setEchoMode(QLineEdit::Normal);
|
|
}
|
|
|
|
void tst_QLineEdit::maxLength_mask_data()
|
|
{
|
|
QTest::addColumn<QString>("mask");
|
|
QTest::addColumn<int>("expectedLength");
|
|
|
|
QTest::newRow("mask_case") << QString(">000<>00<000") << 8;
|
|
QTest::newRow("mask_nocase") << QString("00000000") << 8;
|
|
QTest::newRow("mask_null") << QString() << 32767;
|
|
QTest::newRow("mask_escape") << QString("\\A\\aAA") << 4;
|
|
}
|
|
|
|
void tst_QLineEdit::maxLength_mask()
|
|
{
|
|
QFETCH(QString, mask);
|
|
QFETCH(int, expectedLength);
|
|
|
|
testWidget->setInputMask(mask);
|
|
|
|
QCOMPARE(testWidget->maxLength(), expectedLength);
|
|
}
|
|
|
|
void tst_QLineEdit::maxLength_data()
|
|
{
|
|
QTest::addColumn<QString>("insertString");
|
|
QTest::addColumn<QString>("expectedString");
|
|
QTest::addColumn<int>("length");
|
|
QTest::addColumn<bool>("insertBeforeSettingMaxLength");
|
|
QTest::addColumn<bool>("use_setText");
|
|
|
|
QTest::newRow("keyclick before0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(true) << bool(false);
|
|
QTest::newRow("keyclick before1") << QString("this is a test.") << QString("this is a ") << 10 << bool(true) << bool(false);
|
|
QTest::newRow("keyclick after0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(false) << bool(false);
|
|
QTest::newRow("keyclick after1") << QString("this is a test.") << QString("this is a ") << 10 << bool(false) << bool(false);
|
|
QTest::newRow("settext before0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(true) << bool(true);
|
|
QTest::newRow("settext before1") << QString("this is a test.") << QString("this is a ") << 10 << bool(true) << bool(true);
|
|
QTest::newRow("settext after0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(false) << bool(true);
|
|
QTest::newRow("settext after1") << QString("this is a test.") << QString("this is a ") << 10 << bool(false) << bool(true);
|
|
}
|
|
|
|
void tst_QLineEdit::maxLength()
|
|
{
|
|
QFETCH(QString, insertString);
|
|
QFETCH(QString, expectedString);
|
|
QFETCH(int, length);
|
|
QFETCH(bool, insertBeforeSettingMaxLength);
|
|
QFETCH(bool, use_setText);
|
|
|
|
// in some cases we set the maxLength _before_ entering the text.
|
|
if (!insertBeforeSettingMaxLength)
|
|
testWidget->setMaxLength(length);
|
|
|
|
// I expect MaxLength to work BOTH with entering live characters AND with setting the text.
|
|
if (use_setText) {
|
|
// Enter insertString using setText.
|
|
testWidget->setText(insertString);
|
|
} else {
|
|
// Enter insertString as a sequence of keyClicks
|
|
QTest::keyClicks(testWidget, insertString);
|
|
}
|
|
|
|
// in all other cases we set the maxLength _after_ entering the text.
|
|
if (insertBeforeSettingMaxLength) {
|
|
changed_count = 0;
|
|
testWidget->setMaxLength(length);
|
|
|
|
// Make sure that the textChanged is not emitted unless the text is actually changed
|
|
if (insertString == expectedString) {
|
|
QVERIFY(changed_count == 0);
|
|
} else {
|
|
QVERIFY(changed_count == 1);
|
|
}
|
|
}
|
|
|
|
// and check if we get the expected string back
|
|
QCOMPARE(testWidget->text(), expectedString);
|
|
}
|
|
|
|
void tst_QLineEdit::setMaxLength()
|
|
{
|
|
DEPENDS_ON("maxLength");
|
|
}
|
|
|
|
void tst_QLineEdit::isReadOnly()
|
|
{
|
|
QVERIFY(!testWidget->isReadOnly());
|
|
|
|
// start with a basic text
|
|
QTest::keyClicks(testWidget, "the quick brown fox");
|
|
QCOMPARE(testWidget->text(), QString("the quick brown fox"));
|
|
|
|
// do a quick check to verify that we can indeed edit the text
|
|
testWidget->home(false);
|
|
testWidget->cursorForward(false, 10);
|
|
QTest::keyClicks(testWidget, "dark ");
|
|
QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
|
|
|
|
testWidget->setReadOnly(true);
|
|
QVERIFY(testWidget->isReadOnly());
|
|
|
|
// verify that we cannot edit the text anymore
|
|
testWidget->home(false);
|
|
testWidget->cursorForward(false, 10);
|
|
QTest::keyClick(testWidget, Qt::Key_Delete);
|
|
QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
|
|
testWidget->cursorForward(false, 10);
|
|
QTest::keyClicks(testWidget, "this should not have any effect!! ");
|
|
QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
|
|
}
|
|
|
|
void tst_QLineEdit::setReadOnly()
|
|
{
|
|
DEPENDS_ON("isReadOnly");
|
|
}
|
|
|
|
static void figureOutProperKey(Qt::Key &key, Qt::KeyboardModifiers &pressState)
|
|
{
|
|
#ifdef Q_WS_MAC
|
|
static bool tst_lineedit_randomized = false;
|
|
// Mac has 3 different ways of accomplishing this (same for moving to the back)
|
|
// So I guess we should just randomly do this for now. Which may get people mad, but if
|
|
// we fail at one point, it's just a matter of setting roll to the correct value
|
|
// instead of random.
|
|
|
|
if (!tst_lineedit_randomized) {
|
|
tst_lineedit_randomized = true;
|
|
::srandom(ulong(time(0)));
|
|
}
|
|
long roll = ::random() % 3;
|
|
switch (roll) {
|
|
case 0:
|
|
key = key == Qt::Key_Home ? Qt::Key_Up : Qt::Key_Down;
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
key = key == Qt::Key_Home ? Qt::Key_Left : Qt::Key_Right;
|
|
pressState |= (roll == 1) ? Qt::ControlModifier : Qt::MetaModifier;
|
|
break;
|
|
}
|
|
#else
|
|
// Naively kill the warning.
|
|
key = key;
|
|
pressState = pressState;
|
|
#endif
|
|
}
|
|
|
|
// Platform specific move. Home and End do nothing on the Mac,
|
|
// so do something a bit smarter than tons of #ifdefs
|
|
void tst_QLineEdit::psKeyClick(QWidget *target, Qt::Key key, Qt::KeyboardModifiers pressState)
|
|
{
|
|
figureOutProperKey(key, pressState);
|
|
QTest::keyClick(target, key, pressState);
|
|
}
|
|
|
|
void tst_QLineEdit::psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardModifiers pressState)
|
|
{
|
|
figureOutProperKey(key, pressState);
|
|
keys.addKeyClick(key, pressState);
|
|
}
|
|
|
|
void tst_QLineEdit::cursorPosition()
|
|
{
|
|
QVERIFY(testWidget->cursorPosition() == 0);
|
|
|
|
// start with a basic text
|
|
QTest::keyClicks(testWidget, "The");
|
|
QCOMPARE(testWidget->cursorPosition(), 3);
|
|
QTest::keyClicks(testWidget, " quick");
|
|
QCOMPARE(testWidget->cursorPosition(), 9);
|
|
QTest::keyClicks(testWidget, " brown fox jumps over the lazy dog");
|
|
QCOMPARE(testWidget->cursorPosition(), 43);
|
|
|
|
// The text we have now is:
|
|
// 1 2 3 4 5
|
|
// 012345678901234567890123456789012345678901234567890
|
|
// The quick brown fox jumps over the lazy dog
|
|
|
|
// next we will check some of the cursor movement functions
|
|
testWidget->end(false);
|
|
QCOMPARE(testWidget->cursorPosition() , 43);
|
|
testWidget->cursorForward(false, -1);
|
|
QCOMPARE(testWidget->cursorPosition() , 42);
|
|
testWidget->cursorBackward(false, 1);
|
|
QCOMPARE(testWidget->cursorPosition() , 41);
|
|
testWidget->home(false);
|
|
QCOMPARE(testWidget->cursorPosition() , 0);
|
|
testWidget->cursorForward(false, 1);
|
|
QCOMPARE(testWidget->cursorPosition() , 1);
|
|
testWidget->cursorForward(false, 9);
|
|
QCOMPARE(testWidget->cursorPosition() , 10);
|
|
testWidget->cursorWordForward(false); // 'fox'
|
|
QCOMPARE(testWidget->cursorPosition(), 16);
|
|
testWidget->cursorWordForward(false); // 'jumps'
|
|
QCOMPARE(testWidget->cursorPosition(), 20);
|
|
testWidget->cursorWordBackward(false); // 'fox'
|
|
QCOMPARE(testWidget->cursorPosition(), 16);
|
|
testWidget->cursorWordBackward(false); // 'brown'
|
|
testWidget->cursorWordBackward(false); // 'quick'
|
|
testWidget->cursorWordBackward(false); // 'The'
|
|
QCOMPARE(testWidget->cursorPosition(), 0);
|
|
testWidget->cursorWordBackward(false); // 'The'
|
|
QCOMPARE(testWidget->cursorPosition(), 0);
|
|
|
|
// Cursor position should be 0 here!
|
|
int i;
|
|
for (i=0; i<5; i++)
|
|
QTest::keyClick(testWidget, Qt::Key_Right);
|
|
QCOMPARE(testWidget->cursorPosition(), 5);
|
|
psKeyClick(testWidget, Qt::Key_End);
|
|
QCOMPARE(testWidget->cursorPosition(), 43);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QCOMPARE(testWidget->cursorPosition(), 42);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QCOMPARE(testWidget->cursorPosition(), 41);
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
QCOMPARE(testWidget->cursorPosition(), 0);
|
|
|
|
// cursorposition when maxlength is set
|
|
int maxLength = 9;
|
|
testWidget->clear();
|
|
testWidget->setMaxLength(maxLength);
|
|
QCOMPARE(testWidget->cursorPosition() , 0);
|
|
QTest::keyClicks(testWidget, "123ABC123");
|
|
QCOMPARE(testWidget->cursorPosition() , maxLength);
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
QCOMPARE(testWidget->cursorPosition() , 0);
|
|
psKeyClick(testWidget, Qt::Key_End);
|
|
QCOMPARE(testWidget->cursorPosition() , maxLength);
|
|
}
|
|
|
|
/* // tested in cursorPosition
|
|
void tst_QLineEdit::cursorLeft()
|
|
void tst_QLineEdit::cursorRight()
|
|
void tst_QLineEdit::cursorForward()
|
|
void tst_QLineEdit::cursorBackward()
|
|
void tst_QLineEdit::cursorWordForward()
|
|
void tst_QLineEdit::cursorWordBackward()
|
|
void tst_QLineEdit::home()
|
|
void tst_QLineEdit::end()
|
|
*/
|
|
|
|
void tst_QLineEdit::cursorPositionChanged_data()
|
|
{
|
|
QTest::addColumn<QTestEventList>("input");
|
|
QTest::addColumn<int>("lastPos");
|
|
QTest::addColumn<int>("newPos");
|
|
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_A);
|
|
QTest::newRow("a") << keys << 0 << 1;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
psKeyClick(keys, Qt::Key_Home);
|
|
QTest::newRow("abc<home>") << keys << 3 << 0;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
QTest::newRow("abc<left>") << keys << 3 << 2;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Right);
|
|
QTest::newRow("abc<right>") << keys << 2 << 3;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
psKeyClick(keys, Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_Right);
|
|
QTest::newRow("abc<home><right>") << keys << 0 << 1;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Backspace);
|
|
QTest::newRow("abc<backspace>") << keys << 3 << 2;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Delete);
|
|
QTest::newRow("abc<delete>") << keys << 2 << 3;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Left);
|
|
keys.addKeyClick(Qt::Key_Delete);
|
|
QTest::newRow("abc<left><delete>") << keys << 3 << 2;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
psKeyClick(keys, Qt::Key_Home);
|
|
psKeyClick(keys, Qt::Key_End);
|
|
QTest::newRow("abc<home><end>") << keys << 0 << 3;
|
|
keys.clear();
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Space);
|
|
keys.addKeyClick(Qt::Key_D);
|
|
keys.addKeyClick(Qt::Key_E);
|
|
keys.addKeyClick(Qt::Key_F);
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_Right, Qt::ControlModifier);
|
|
QTest::newRow("abc efg<home><ctrl-right>") << keys
|
|
#ifndef Q_WS_MAC
|
|
<< 0 << 4;
|
|
#else
|
|
<< 6 << 7;
|
|
#endif
|
|
keys.clear();
|
|
|
|
#ifdef Q_WS_MAC
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Space);
|
|
keys.addKeyClick(Qt::Key_D);
|
|
keys.addKeyClick(Qt::Key_E);
|
|
keys.addKeyClick(Qt::Key_F);
|
|
keys.addKeyClick(Qt::Key_Up);
|
|
keys.addKeyClick(Qt::Key_Right, Qt::AltModifier);
|
|
QTest::newRow("mac equivalent abc efg<up><option-right>") << keys << 0 << 4;
|
|
keys.clear();
|
|
#endif
|
|
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Space);
|
|
keys.addKeyClick(Qt::Key_D);
|
|
keys.addKeyClick(Qt::Key_E);
|
|
keys.addKeyClick(Qt::Key_F);
|
|
keys.addKeyClick(Qt::Key_Left, Qt::ControlModifier);
|
|
QTest::newRow("abc efg<ctrl-left>") << keys << 7
|
|
#ifndef Q_WS_MAC
|
|
<< 4;
|
|
#else
|
|
<< 0;
|
|
#endif
|
|
keys.clear();
|
|
#ifdef Q_WS_MAC
|
|
keys.addKeyClick(Qt::Key_A);
|
|
keys.addKeyClick(Qt::Key_B);
|
|
keys.addKeyClick(Qt::Key_C);
|
|
keys.addKeyClick(Qt::Key_Space);
|
|
keys.addKeyClick(Qt::Key_D);
|
|
keys.addKeyClick(Qt::Key_E);
|
|
keys.addKeyClick(Qt::Key_F);
|
|
keys.addKeyClick(Qt::Key_Left, Qt::AltModifier);
|
|
QTest::newRow("mac equivalent abc efg<option-left>") << keys << 7 << 4;
|
|
keys.clear();
|
|
#endif
|
|
}
|
|
|
|
|
|
void tst_QLineEdit::cursorPositionChanged()
|
|
{
|
|
QFETCH(QTestEventList, input);
|
|
QFETCH(int, lastPos);
|
|
QFETCH(int, newPos);
|
|
|
|
lastCursorPos = 0;
|
|
newCursorPos = 0;
|
|
input.simulate(testWidget);
|
|
QCOMPARE(lastCursorPos, lastPos);
|
|
QCOMPARE(newCursorPos, newPos);
|
|
}
|
|
|
|
void tst_QLineEdit::selectedText()
|
|
{
|
|
QString testString = "Abc defg hijklmno, p 'qrst' uvw xyz";
|
|
|
|
// start with a basic text
|
|
testWidget->setText(testString);
|
|
selection_count = 0;
|
|
|
|
// The text we have now is:
|
|
// 1 2 3 4 5
|
|
// 012345678901234567890123456789012345678901234567890
|
|
// Abc defg hijklmno, p 'qrst' uvw xyz
|
|
|
|
testWidget->home(false);
|
|
QVERIFY(!testWidget->hasSelectedText());
|
|
QCOMPARE(testWidget->selectedText(), QString());
|
|
|
|
// play a bit with the cursorForward, cursorBackward(), etc
|
|
testWidget->cursorForward(true, 9);
|
|
QVERIFY(testWidget->hasSelectedText());
|
|
QCOMPARE(testWidget->selectedText(), QString("Abc defg "));
|
|
QVERIFY(selection_count == 1);
|
|
|
|
// reset selection
|
|
testWidget->home(false);
|
|
QVERIFY(!testWidget->hasSelectedText());
|
|
QCOMPARE(testWidget->selectedText(), QString());
|
|
selection_count = 0;
|
|
}
|
|
|
|
/* // tested in selectedText
|
|
void tst_QLineEdit::backspace()
|
|
void tst_QLineEdit::del()
|
|
void tst_QLineEdit::selectionChanged()
|
|
void tst_QLineEdit::selectAll()
|
|
void tst_QLineEdit::deselect()
|
|
*/
|
|
|
|
void tst_QLineEdit::onSelectionChanged()
|
|
{
|
|
selection_count++;
|
|
}
|
|
|
|
void tst_QLineEdit::hasSelectedText()
|
|
{
|
|
DEPENDS_ON("selectedText");
|
|
}
|
|
|
|
void tst_QLineEdit::deleteSelectedText()
|
|
{
|
|
const QString text = QString::fromLatin1("bar");
|
|
QLineEdit edit( text );
|
|
QCOMPARE(edit.text(), text);
|
|
|
|
edit.selectAll();
|
|
|
|
QTest::keyClick(&edit, Qt::Key_Delete, 0);
|
|
QVERIFY(edit.text().isEmpty());
|
|
|
|
edit.setText(text);
|
|
edit.selectAll();
|
|
|
|
QMenu *menu = edit.createStandardContextMenu();
|
|
for (int i = 0; i < menu->actions().count(); ++i) {
|
|
QAction *current = menu->actions().at(i);
|
|
if (current->text() == QLineEdit::tr("Delete")) {
|
|
current->trigger(); //this will delete the whole text selected
|
|
QVERIFY(edit.text().isEmpty());
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void tst_QLineEdit::textChangedAndTextEdited()
|
|
{
|
|
changed_count = 0;
|
|
edited_count = 0;
|
|
|
|
QTest::keyClick(testWidget, Qt::Key_A);
|
|
QCOMPARE(changed_count, 1);
|
|
QVERIFY(edited_count == changed_count);
|
|
QTest::keyClick(testWidget, 'b');
|
|
QCOMPARE(changed_count, 2);
|
|
QVERIFY(edited_count == changed_count);
|
|
QTest::keyClick(testWidget, 'c');
|
|
QCOMPARE(changed_count, 3);
|
|
QVERIFY(edited_count == changed_count);
|
|
QTest::keyClick(testWidget, ' ');
|
|
QCOMPARE(changed_count, 4);
|
|
QVERIFY(edited_count == changed_count);
|
|
QTest::keyClick(testWidget, 'd');
|
|
QCOMPARE(changed_count, 5);
|
|
QVERIFY(edited_count == changed_count);
|
|
|
|
changed_count = 0;
|
|
edited_count = 0;
|
|
changed_string = QString::null;
|
|
|
|
testWidget->setText("foo");
|
|
QCOMPARE(changed_count, 1);
|
|
QCOMPARE(edited_count, 0);
|
|
QCOMPARE(changed_string, QString("foo"));
|
|
|
|
changed_count = 0;
|
|
edited_count = 0;
|
|
changed_string = QString::null;
|
|
|
|
testWidget->setText("");
|
|
QCOMPARE(changed_count, 1);
|
|
QCOMPARE(edited_count, 0);
|
|
QVERIFY(changed_string.isEmpty());
|
|
QVERIFY(!changed_string.isNull());
|
|
}
|
|
|
|
void tst_QLineEdit::onTextChanged(const QString &text)
|
|
{
|
|
changed_count++;
|
|
changed_string = text;
|
|
}
|
|
|
|
void tst_QLineEdit::onTextEdited(const QString &/*text*/)
|
|
{
|
|
edited_count++;
|
|
}
|
|
|
|
|
|
void tst_QLineEdit::onCursorPositionChanged(int oldPos, int newPos)
|
|
{
|
|
lastCursorPos = oldPos;
|
|
newCursorPos = newPos;
|
|
}
|
|
|
|
void tst_QLineEdit::returnPressed()
|
|
{
|
|
return_count = 0;
|
|
|
|
QTest::keyClick(testWidget, Qt::Key_Return);
|
|
QVERIFY(return_count == 1);
|
|
return_count = 0;
|
|
|
|
QTest::keyClick(testWidget, 'A');
|
|
QVERIFY(return_count == 0);
|
|
QTest::keyClick(testWidget, 'b');
|
|
QVERIFY(return_count == 0);
|
|
QTest::keyClick(testWidget, 'c');
|
|
QVERIFY(return_count == 0);
|
|
QTest::keyClick(testWidget, ' ');
|
|
QVERIFY(return_count == 0);
|
|
QTest::keyClick(testWidget, 'd');
|
|
QVERIFY(return_count == 0);
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
QVERIFY(return_count == 0);
|
|
psKeyClick(testWidget, Qt::Key_End);
|
|
QVERIFY(return_count == 0);
|
|
QTest::keyClick(testWidget, Qt::Key_Escape);
|
|
QVERIFY(return_count == 0);
|
|
QTest::keyClick(testWidget, Qt::Key_Return);
|
|
QVERIFY(return_count == 1);
|
|
}
|
|
|
|
// int validator that fixes all !isNumber to '0'
|
|
class QIntFixValidator : public QIntValidator {
|
|
public:
|
|
QIntFixValidator(int min, int max, QObject *parent) : QIntValidator(min, max, parent) {}
|
|
void fixup (QString &input) const {
|
|
for (int i=0; i<input.length(); ++i)
|
|
if (!input.at(i).isNumber()) {
|
|
input[(int)i] = QChar('0');
|
|
}
|
|
}
|
|
};
|
|
|
|
void tst_QLineEdit::returnPressed_maskvalidator_data() {
|
|
QTest::addColumn<QString>("inputMask");
|
|
QTest::addColumn<bool>("hasValidator");
|
|
QTest::addColumn<QTestEventList>("input");
|
|
QTest::addColumn<QString>("expectedText");
|
|
QTest::addColumn<bool>("returnPressed");
|
|
|
|
{
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_3);
|
|
keys.addKeyClick(Qt::Key_Return);
|
|
QTest::newRow("no mask, no validator, input '123<cr>'")
|
|
<< QString()
|
|
<< false
|
|
<< keys
|
|
<< QString("123")
|
|
<< true;
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_Return);
|
|
QTest::newRow("mask '999', no validator, input '12<cr>'")
|
|
<< QString("999")
|
|
<< false
|
|
<< keys
|
|
<< QString("12")
|
|
<< false;
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_3);
|
|
keys.addKeyClick(Qt::Key_Return);
|
|
QTest::newRow("mask '999', no validator, input '123<cr>'")
|
|
<< QString("999")
|
|
<< false
|
|
<< keys
|
|
<< QString("123")
|
|
<< true;
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_3);
|
|
keys.addKeyClick(Qt::Key_Return);
|
|
QTest::newRow("no mask, intfix validator(0,999), input '123<cr>'")
|
|
<< QString()
|
|
<< true
|
|
<< keys
|
|
<< QString("123")
|
|
<< true;
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_7);
|
|
keys.addKeyClick(Qt::Key_7);
|
|
keys.addKeyClick(Qt::Key_7);
|
|
keys.addKeyClick(Qt::Key_7);
|
|
keys.addKeyClick(Qt::Key_Return);
|
|
QTest::newRow("no mask, intfix validator(0,999), input '7777<cr>'")
|
|
<< QString()
|
|
<< true
|
|
<< keys
|
|
<< QString("777")
|
|
<< true;
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_1);
|
|
keys.addKeyClick(Qt::Key_2);
|
|
keys.addKeyClick(Qt::Key_Return);
|
|
QTest::newRow("mask '999', intfix validator(0,999), input '12<cr>'")
|
|
<< QString("999")
|
|
<< true
|
|
<< keys
|
|
<< QString("12")
|
|
<< false;
|
|
}
|
|
{
|
|
QTestEventList keys;
|
|
keys.addKeyClick(Qt::Key_Home);
|
|
keys.addKeyClick(Qt::Key_Return);
|
|
QTest::newRow("mask '999', intfix validator(0,999), input '<cr>'")
|
|
<< QString("999")
|
|
<< true
|
|
<< keys
|
|
<< QString("000")
|
|
<< true;
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::returnPressed_maskvalidator()
|
|
{
|
|
QFETCH(QString, inputMask);
|
|
QFETCH(bool, hasValidator);
|
|
QFETCH(QTestEventList, input);
|
|
QFETCH(QString, expectedText);
|
|
QFETCH(bool, returnPressed);
|
|
|
|
QEXPECT_FAIL("mask '999', intfix validator(0,999), input '12<cr>'", "QIntValidator has changed behaviour. Does not accept spaces. Task 43082.", Abort);
|
|
|
|
testWidget->setInputMask(inputMask);
|
|
if (hasValidator)
|
|
testWidget->setValidator(new QIntFixValidator(0, 999, testWidget));
|
|
|
|
return_count = 0;
|
|
input.simulate(testWidget);
|
|
|
|
QCOMPARE(testWidget->text(), expectedText);
|
|
QCOMPARE(return_count , returnPressed ? 1 : 0);
|
|
}
|
|
|
|
void tst_QLineEdit::onReturnPressed()
|
|
{
|
|
return_count++;
|
|
}
|
|
|
|
void tst_QLineEdit::setValidator()
|
|
{
|
|
// Verify that we can set and re-set a validator.
|
|
QVERIFY(!testWidget->validator());
|
|
|
|
QIntValidator iv1(0);
|
|
testWidget->setValidator(&iv1);
|
|
QCOMPARE(testWidget->validator(), static_cast<const QValidator*>(&iv1));
|
|
|
|
testWidget->setValidator(0);
|
|
QVERIFY(testWidget->validator() == 0);
|
|
|
|
QIntValidator iv2(0, 99, 0);
|
|
testWidget->setValidator(&iv2);
|
|
QCOMPARE(testWidget->validator(), static_cast<const QValidator *>(&iv2));
|
|
|
|
testWidget->setValidator(0);
|
|
QVERIFY(testWidget->validator() == 0);
|
|
}
|
|
|
|
void tst_QLineEdit::validator()
|
|
{
|
|
DEPENDS_ON("setValidator");
|
|
}
|
|
|
|
void tst_QLineEdit::clearValidator()
|
|
{
|
|
DEPENDS_ON("setValidator");
|
|
}
|
|
|
|
void tst_QLineEdit::setValidator_QIntValidator_data()
|
|
{
|
|
QTest::addColumn<int>("mini");
|
|
QTest::addColumn<int>("maxi");
|
|
QTest::addColumn<QString>("input");
|
|
QTest::addColumn<QString>("expectedText");
|
|
QTest::addColumn<bool>("useKeys");
|
|
QTest::addColumn<bool>("is_valid");
|
|
|
|
for (int i=0; i<2; i++) {
|
|
bool useKeys = false;
|
|
QString inputMode = "insert ";
|
|
if (i!=0) {
|
|
inputMode = "useKeys ";
|
|
useKeys = true;
|
|
}
|
|
|
|
// valid data
|
|
QTest::newRow(QString(inputMode + "range [0,9] valid '1'").toLatin1())
|
|
<< 0
|
|
<< 9
|
|
<< QString("1")
|
|
<< QString("1")
|
|
<< bool(useKeys)
|
|
<< bool(true);
|
|
|
|
QTest::newRow(QString(inputMode + "range [3,7] valid '3'").toLatin1())
|
|
<< 3
|
|
<< 7
|
|
<< QString("3")
|
|
<< QString("3")
|
|
<< bool(useKeys)
|
|
<< bool(true);
|
|
|
|
QTest::newRow(QString(inputMode + "range [3,7] valid '7'").toLatin1())
|
|
<< 3
|
|
<< 7
|
|
<< QString("7")
|
|
<< QString("7")
|
|
<< bool(useKeys)
|
|
<< bool(true);
|
|
|
|
QTest::newRow(QString(inputMode + "range [0,100] valid '9'").toLatin1())
|
|
<< 0
|
|
<< 100
|
|
<< QString("9")
|
|
<< QString("9")
|
|
<< bool(useKeys)
|
|
<< bool(true);
|
|
|
|
QTest::newRow(QString(inputMode + "range [0,100] valid '12'").toLatin1())
|
|
<< 0
|
|
<< 100
|
|
<< QString("12")
|
|
<< QString("12")
|
|
<< bool(useKeys)
|
|
<< bool(true);
|
|
|
|
QTest::newRow(QString(inputMode + "range [-100,100] valid '-12'").toLatin1())
|
|
<< -100
|
|
<< 100
|
|
<< QString("-12")
|
|
<< QString("-12")
|
|
<< bool(useKeys)
|
|
<< bool(true);
|
|
|
|
// invalid data
|
|
// characters not allowed in QIntValidator
|
|
QTest::newRow(QString(inputMode + "range [0,9] inv 'a-a'").toLatin1())
|
|
<< 0
|
|
<< 9
|
|
<< QString("a")
|
|
<< QString("")
|
|
<< bool(useKeys)
|
|
<< bool(false);
|
|
|
|
QTest::newRow(QString(inputMode + "range [0,9] inv 'A'").toLatin1())
|
|
<< 0
|
|
<< 9
|
|
<< QString("A")
|
|
<< QString("")
|
|
<< bool(useKeys)
|
|
<< bool(false);
|
|
// minus sign only allowed with a range on the negative side
|
|
QTest::newRow(QString(inputMode + "range [0,100] inv '-'").toLatin1())
|
|
<< 0
|
|
<< 100
|
|
<< QString("-")
|
|
<< QString("")
|
|
<< bool(useKeys)
|
|
<< bool(false);
|
|
QTest::newRow(QString(inputMode + "range [0,100] int '153'").toLatin1())
|
|
<< 0
|
|
<< 100
|
|
<< QString("153")
|
|
<< QString(useKeys ? "15" : "")
|
|
<< bool(useKeys)
|
|
<< bool(useKeys ? true : false);
|
|
QTest::newRow(QString(inputMode + "range [-100,100] int '-153'").toLatin1())
|
|
<< -100
|
|
<< 100
|
|
<< QString("-153")
|
|
<< QString(useKeys ? "-15" : "")
|
|
<< bool(useKeys)
|
|
<< bool(useKeys ? true : false);
|
|
QTest::newRow(QString(inputMode + "range [3,7] int '2'").toLatin1())
|
|
<< 3
|
|
<< 7
|
|
<< QString("2")
|
|
<< QString("2")
|
|
<< bool(useKeys)
|
|
<< bool(false);
|
|
|
|
QTest::newRow(QString(inputMode + "range [3,7] int '8'").toLatin1())
|
|
<< 3
|
|
<< 7
|
|
<< QString("8")
|
|
<< QString("")
|
|
<< bool(useKeys)
|
|
<< bool(false);
|
|
}
|
|
}
|
|
|
|
void tst_QLineEdit::setValidator_QIntValidator()
|
|
{
|
|
QFETCH(int, mini);
|
|
QFETCH(int, maxi);
|
|
QFETCH(QString, input);
|
|
QFETCH(QString, expectedText);
|
|
QFETCH(bool, useKeys);
|
|
QFETCH(bool, is_valid);
|
|
|
|
QIntValidator intValidator(mini, maxi, 0);
|
|
testWidget->setValidator(&intValidator);
|
|
QVERIFY(testWidget->text().isEmpty());
|
|
//qDebug("1 input: '" + input + "' Exp: '" + expectedText + "'");
|
|
|
|
// tests valid input
|
|
if (!useKeys) {
|
|
testWidget->insert(input);
|
|
} else {
|
|
QTest::keyClicks(testWidget, input);
|
|
return_count = 0;
|
|
QTest::keyClick(testWidget, Qt::Key_Return);
|
|
QCOMPARE(return_count, int(is_valid)); // assuming that is_valid = true equals 1
|
|
}
|
|
//qDebug("2 input: '" + input + "' Exp: '" + expectedText + "'");
|
|
// QCOMPARE(testWidget->displayText(), expectedText);
|
|
QCOMPARE(testWidget->text(), expectedText);
|
|
}
|
|
|
|
#define NO_PIXMAP_TESTS
|
|
|
|
void tst_QLineEdit::frame_data()
|
|
{
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTest::addColumn<QPixmap>("noFrame");
|
|
QTest::addColumn<QPixmap>("useFrame");
|
|
|
|
QTest::newRow("win");
|
|
//#else
|
|
// QTest::newRow("x11");
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void tst_QLineEdit::frame()
|
|
{
|
|
testWidget->setFrame(false);
|
|
// verify that the editor is shown without a frame
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "noFrame");
|
|
#endif
|
|
#endif
|
|
QVERIFY(!testWidget->hasFrame());
|
|
|
|
testWidget->setFrame(true);
|
|
// verify that the editor is shown with a frame
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "useFrame");
|
|
#endif
|
|
#endif
|
|
QVERIFY(testWidget->hasFrame());
|
|
}
|
|
|
|
void tst_QLineEdit::alignment()
|
|
{
|
|
DEPENDS_ON("setAlignment");
|
|
}
|
|
|
|
void tst_QLineEdit::setAlignment_data()
|
|
{
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTest::addColumn<QPixmap>("left");
|
|
QTest::addColumn<QPixmap>("right");
|
|
QTest::addColumn<QPixmap>("hcenter");
|
|
QTest::addColumn<QPixmap>("auto");
|
|
|
|
QTest::newRow("win");
|
|
//#else
|
|
// QTest::newRow("x11");
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void tst_QLineEdit::setAlignment()
|
|
{
|
|
testWidget->setText("left");
|
|
testWidget->setAlignment(Qt::AlignLeft);
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "left");
|
|
#endif
|
|
#endif
|
|
QVERIFY(testWidget->alignment() == Qt::AlignLeft);
|
|
|
|
#ifdef QT3_SUPPORT
|
|
testWidget->setText("auto");
|
|
testWidget->setAlignment(Qt::AlignAuto);
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "auto");
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
testWidget->setText("hcenter");
|
|
testWidget->setAlignment(Qt::AlignHCenter);
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "hcenter");
|
|
#endif
|
|
#endif
|
|
QVERIFY(testWidget->alignment() == Qt::AlignHCenter);
|
|
|
|
#ifdef QT3_SUPPORT
|
|
testWidget->setText("auto");
|
|
testWidget->setAlignment(Qt::AlignAuto);
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "auto");
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
testWidget->setText("right");
|
|
testWidget->setAlignment(Qt::AlignRight);
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "right");
|
|
#endif
|
|
#endif
|
|
QVERIFY(testWidget->alignment() == Qt::AlignRight);
|
|
|
|
#ifdef QT3_SUPPORT
|
|
testWidget->setText("auto");
|
|
testWidget->setAlignment(Qt::AlignAuto);
|
|
#ifndef NO_PIXMAP_TESTS
|
|
#if defined Q_WS_WIN
|
|
QTEST(testWidget, "auto");
|
|
#endif
|
|
#endif
|
|
QVERIFY(testWidget->alignment() == Qt::AlignAuto);
|
|
#endif
|
|
|
|
testWidget->setAlignment(Qt::AlignTop);
|
|
QVERIFY(testWidget->alignment() == Qt::AlignTop);
|
|
|
|
testWidget->setAlignment(Qt::AlignBottom);
|
|
QVERIFY(testWidget->alignment() == Qt::AlignBottom);
|
|
|
|
testWidget->setAlignment(Qt::AlignCenter);
|
|
QVERIFY(testWidget->alignment() == Qt::AlignCenter);
|
|
}
|
|
|
|
void tst_QLineEdit::isModified()
|
|
{
|
|
QVERIFY(!testWidget->isModified());
|
|
testWidget->setText("bla");
|
|
QVERIFY(!testWidget->isModified());
|
|
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Right);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Right);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Right);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QVERIFY(!testWidget->isModified());
|
|
psKeyClick(testWidget, Qt::Key_End);
|
|
QVERIFY(!testWidget->isModified());
|
|
|
|
QTest::keyClicks(testWidget, "T");
|
|
QVERIFY(testWidget->isModified());
|
|
QTest::keyClicks(testWidget, "his is a string");
|
|
QVERIFY(testWidget->isModified());
|
|
|
|
testWidget->setText("");
|
|
QVERIFY(!testWidget->isModified());
|
|
testWidget->setText("foo");
|
|
QVERIFY(!testWidget->isModified());
|
|
}
|
|
|
|
/*
|
|
Obsolete function but as long as we provide it, it needs to work.
|
|
*/
|
|
|
|
void tst_QLineEdit::edited()
|
|
{
|
|
QVERIFY(!testWidget->isModified());
|
|
testWidget->setText("bla");
|
|
QVERIFY(!testWidget->isModified());
|
|
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Right);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Right);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Right);
|
|
QVERIFY(!testWidget->isModified());
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QVERIFY(!testWidget->isModified());
|
|
psKeyClick(testWidget, Qt::Key_End);
|
|
QVERIFY(!testWidget->isModified());
|
|
|
|
QTest::keyClicks(testWidget, "T");
|
|
QVERIFY(testWidget->isModified());
|
|
QTest::keyClicks(testWidget, "his is a string");
|
|
QVERIFY(testWidget->isModified());
|
|
|
|
testWidget->setModified(false);
|
|
QVERIFY(!testWidget->isModified());
|
|
|
|
testWidget->setModified(true);
|
|
QVERIFY(testWidget->isModified());
|
|
}
|
|
|
|
/*
|
|
Obsolete function but as long as we provide it, it needs to work.
|
|
*/
|
|
|
|
void tst_QLineEdit::setEdited()
|
|
{
|
|
DEPENDS_ON("edited");
|
|
}
|
|
|
|
void tst_QLineEdit::insert()
|
|
{
|
|
testWidget->insert("This");
|
|
testWidget->insert(" is");
|
|
testWidget->insert(" a");
|
|
testWidget->insert(" test");
|
|
|
|
QCOMPARE(testWidget->text(), QString("This is a test"));
|
|
|
|
testWidget->cursorWordBackward(false);
|
|
testWidget->cursorBackward(false, 1);
|
|
testWidget->insert(" nice");
|
|
QCOMPARE(testWidget->text(), QString("This is a nice test"));
|
|
|
|
testWidget->setCursorPosition(-1);
|
|
testWidget->insert("No Crash! ");
|
|
QCOMPARE(testWidget->text(), QString("No Crash! This is a nice test"));
|
|
}
|
|
|
|
void tst_QLineEdit::setSelection_data()
|
|
{
|
|
QTest::addColumn<QString>("text");
|
|
QTest::addColumn<int>("start");
|
|
QTest::addColumn<int>("length");
|
|
QTest::addColumn<int>("expectedCursor");
|
|
QTest::addColumn<QString>("expectedText");
|
|
QTest::addColumn<bool>("expectedHasSelectedText");
|
|
|
|
QString text = "Abc defg hijklmno, p 'qrst' uvw xyz";
|
|
int start, length, pos;
|
|
|
|
start = 0; length = 1; pos = 1;
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString("A") << true;
|
|
|
|
start = 0; length = 2; pos = 2;
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString("Ab") << true;
|
|
|
|
start = 0; length = 4; pos = 4;
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString("Abc ") << true;
|
|
|
|
start = -1; length = 0; pos = text.length();
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString() << false;
|
|
|
|
start = 34; length = 1; pos = 35;
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString("z") << true;
|
|
|
|
start = 34; length = 2; pos = 35;
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString("z") << true;
|
|
|
|
start = 34; length = -1; pos = 33;
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString("y") << true;
|
|
|
|
start = 1; length = -2; pos = 0;
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString("A") << true;
|
|
|
|
start = -1; length = -1; pos = text.length();
|
|
QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
|
|
<< text << start << length << pos << QString() << false;
|
|
}
|
|
|
|
|
|
void tst_QLineEdit::setSelection()
|
|
{
|
|
QFETCH(QString, text);
|
|
QFETCH(int, start);
|
|
QFETCH(int, length);
|
|
QFETCH(int, expectedCursor);
|
|
QFETCH(QString, expectedText);
|
|
QFETCH(bool, expectedHasSelectedText);
|
|
|
|
testWidget->setText(text);
|
|
testWidget->setSelection(start, length);
|
|
QCOMPARE(testWidget->hasSelectedText(), expectedHasSelectedText);
|
|
QCOMPARE(testWidget->selectedText(), expectedText);
|
|
if (expectedCursor >= 0)
|
|
QCOMPARE(testWidget->cursorPosition(), expectedCursor);
|
|
}
|
|
|
|
#ifndef QT_NO_CLIPBOARD
|
|
void tst_QLineEdit::cut()
|
|
{
|
|
#ifdef Q_WS_MAC
|
|
{
|
|
PasteboardRef pasteboard;
|
|
OSStatus status = PasteboardCreate(0, &pasteboard);
|
|
if (status == noErr)
|
|
CFRelease(pasteboard);
|
|
else
|
|
QSKIP("Autotests run from cron and pasteboard don't get along quite ATM", SkipAll);
|
|
}
|
|
#endif
|
|
// test newlines in cut'n'paste
|
|
testWidget->setText("A\nB\nC\n");
|
|
testWidget->setSelection(0, 6);
|
|
testWidget->cut();
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
testWidget->paste();
|
|
QCOMPARE(testWidget->text(), QString("A\nB\nC\n"));
|
|
// 1 2 3 4
|
|
// 01234567890123456789012345678901234567890
|
|
testWidget->setText("Abc defg hijklmno");
|
|
|
|
testWidget->setSelection(0, 3);
|
|
testWidget->cut();
|
|
QCOMPARE(testWidget->text(), QString(" defg hijklmno"));
|
|
|
|
psKeyClick(testWidget, Qt::Key_End);
|
|
testWidget->paste();
|
|
QCOMPARE(testWidget->text(), QString(" defg hijklmnoAbc"));
|
|
|
|
psKeyClick(testWidget, Qt::Key_Home);
|
|
testWidget->del();
|
|
QCOMPARE(testWidget->text(), QString("defg hijklmnoAbc"));
|
|
|
|
testWidget->setSelection(0, 4);
|
|
testWidget->copy();
|
|
psKeyClick(testWidget, Qt::Key_End);
|
|
testWidget->paste();
|
|
QCOMPARE(testWidget->text(), QString("defg hijklmnoAbcdefg"));
|
|
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QTest::keyClick(testWidget, Qt::Key_Left);
|
|
QTest::keyClick(testWidget, ' ');
|
|
QCOMPARE(testWidget->text(), QString("defg hijklmno Abcdefg"));
|
|
|
|
testWidget->setSelection(0, 5);
|
|
testWidget->del();
|
|
QCOMPARE(testWidget->text(), QString("hijklmno Abcdefg"));
|
|
|
|
testWidget->end(false);
|
|
QTest::keyClick(testWidget, ' ');
|
|
testWidget->paste();
|
|
QCOMPARE(testWidget->text(), QString("hijklmno Abcdefg defg"));
|
|
|
|
testWidget->home(false);
|
|
testWidget->cursorWordForward(true);
|
|
testWidget->cut();
|
|
testWidget->end(false);
|
|
QTest::keyClick(testWidget, ' ');
|
|
testWidget->paste();
|
|
testWidget->cursorBackward(true, 1);
|
|
testWidget->cut();
|
|
QCOMPARE(testWidget->text(), QString("Abcdefg defg hijklmno"));
|
|
}
|
|
|
|
void tst_QLineEdit::copy()
|
|
{
|
|
DEPENDS_ON("cut");
|
|
}
|
|
|
|
void tst_QLineEdit::paste()
|
|
{
|
|
DEPENDS_ON("cut");
|
|
}
|
|
#endif
|
|
class InputMaskValidator : public QValidator
|
|
{
|
|
public:
|
|
InputMaskValidator(QObject *parent, const char *name = 0) : QValidator(parent) { setObjectName(name); }
|
|
State validate(QString &text, int &pos) const
|
|
{
|
|
InputMaskValidator *that = (InputMaskValidator *)this;
|
|
that->validateText = text;
|
|
that->validatePos = pos;
|
|
return Acceptable;
|
|
}
|
|
QString validateText;
|
|
int validatePos;
|
|
};
|
|
|
|
void tst_QLineEdit::inputMaskAndValidator_data()
|
|
{
|
|
QTest::addColumn<QString>("inputMask");
|
|
QTest::addColumn<QTestEventList>("keys");
|
|
QTest::addColumn<QString>("validateText");
|
|
QTest::addColumn<int>("validatePos");
|
|
|
|
QTestEventList inputKeys;
|
|
inputKeys.addKeyClick(Qt::Key_1);
|
|
inputKeys.addKeyClick(Qt::Key_2);
|
|
|
|
QTest::newRow("task28291") << "000;_" << inputKeys << "12_" << 2;
|
|
}
|
|
|
|
void tst_QLineEdit::inputMaskAndValidator()
|
|
{
|
|
QFETCH(QString, inputMask);
|
|
QFETCH(QTestEventList, keys);
|
|
QFETCH(QString, validateText);
|
|
QFETCH(int, validatePos);
|
|
|
|
InputMaskValidator imv(testWidget);
|
|
testWidget->setValidator(&imv);
|
|
|
|
testWidget->setInputMask(inputMask);
|
|
keys.simulate(testWidget);
|
|
|
|
QCOMPARE(imv.validateText, validateText);
|
|
QCOMPARE(imv.validatePos, validatePos);
|
|
}
|
|
|
|
void tst_QLineEdit::maxLengthAndInputMask()
|
|
{
|
|
// Really a test for #30447
|
|
QVERIFY(testWidget->inputMask().isNull());
|
|
testWidget->setMaxLength(10);
|
|
QVERIFY(testWidget->maxLength() == 10);
|
|
testWidget->setInputMask(QString::null);
|
|
QVERIFY(testWidget->inputMask().isNull());
|
|
QVERIFY(testWidget->maxLength() == 10);
|
|
}
|
|
|
|
|
|
class LineEdit : public QLineEdit
|
|
{
|
|
public:
|
|
LineEdit() { state = Other; }
|
|
|
|
void keyPressEvent(QKeyEvent *e)
|
|
{
|
|
QLineEdit::keyPressEvent(e);
|
|
if (e->key() == Qt::Key_Enter) {
|
|
state = e->isAccepted() ? Accepted : Ignored;
|
|
} else {
|
|
state = Other;
|
|
}
|
|
|
|
}
|
|
enum State {
|
|
Accepted,
|
|
Ignored,
|
|
Other
|
|
};
|
|
|
|
State state;
|
|
|
|
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(QTextCursor::Visual);
|
|
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(QTextCursor::Logical);
|
|
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"
|