~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the test suite of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
 
 
43
#include <QtTest/QtTest>
 
44
#include "qlineedit.h"
 
45
#include "qapplication.h"
 
46
#include "qstringlist.h"
 
47
#include "qstyle.h"
 
48
#include "qvalidator.h"
 
49
#include "qcompleter.h"
 
50
#include "qstandarditemmodel.h"
 
51
#include <qpa/qplatformtheme.h>
 
52
#include "qstylehints.h"
 
53
#include <private/qguiapplication_p.h>
 
54
#include "qclipboard.h"
 
55
 
 
56
#ifdef Q_OS_MAC
 
57
#include <cstdlib> // For the random function.
 
58
#endif
 
59
 
 
60
#include <qlineedit.h>
 
61
#include <private/qlineedit_p.h>
 
62
#include <private/qwidgetlinecontrol_p.h>
 
63
#include <qmenu.h>
 
64
#include <qlayout.h>
 
65
#include <qspinbox.h>
 
66
#include <qdebug.h>
 
67
 
 
68
#include "qcommonstyle.h"
 
69
#include "qstyleoption.h"
 
70
 
 
71
#include "qplatformdefs.h"
 
72
 
 
73
#include "../../../shared/platformclipboard.h"
 
74
#include "../../../shared/platforminputcontext.h"
 
75
#include <private/qinputmethod_p.h>
 
76
 
 
77
#include "../../../qtest-config.h"
 
78
 
 
79
QT_BEGIN_NAMESPACE
 
80
class QPainter;
 
81
QT_END_NAMESPACE
 
82
 
 
83
class StyleOptionTestStyle : public QCommonStyle
 
84
{
 
85
private:
 
86
    bool readOnly;
 
87
 
 
88
public:
 
89
    inline StyleOptionTestStyle() : QCommonStyle(), readOnly(false)
 
90
    {
 
91
    }
 
92
 
 
93
    inline void setReadOnly(bool readOnly)
 
94
    {
 
95
        this->readOnly = readOnly;
 
96
    }
 
97
 
 
98
    inline void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *,
 
99
                                 const QWidget *) const
 
100
    {
 
101
        switch (pe) {
 
102
            case PE_PanelLineEdit:
 
103
            if (readOnly)
 
104
                QVERIFY(opt->state & QStyle::State_ReadOnly);
 
105
            else
 
106
                QVERIFY(!(opt->state & QStyle::State_ReadOnly));
 
107
            break;
 
108
 
 
109
            default:
 
110
            break;
 
111
        }
 
112
    }
 
113
};
 
114
 
 
115
class tst_QLineEdit : public QObject
 
116
{
 
117
Q_OBJECT
 
118
 
 
119
public:
 
120
    enum EventStates { Press, Release, Click };
 
121
 
 
122
    tst_QLineEdit();
 
123
    virtual ~tst_QLineEdit();
 
124
 
 
125
public slots:
 
126
    void initTestCase();
 
127
    void cleanupTestCase();
 
128
    void init();
 
129
    void cleanup();
 
130
private slots:
 
131
    void getSetCheck();
 
132
    void experimental();
 
133
 
 
134
    void upperAndLowercase();
 
135
 
 
136
    void setInputMask_data();
 
137
    void setInputMask();
 
138
 
 
139
    void inputMask_data();
 
140
    void inputMask();
 
141
 
 
142
    void clearInputMask();
 
143
 
 
144
    void keypress_inputMask_data();
 
145
    void keypress_inputMask();
 
146
 
 
147
    void inputMaskAndValidator_data();
 
148
    void inputMaskAndValidator();
 
149
 
 
150
    void hasAcceptableInputMask_data();
 
151
    void hasAcceptableInputMask();
 
152
 
 
153
    void hasAcceptableInputValidator();
 
154
 
 
155
 
 
156
    void redo_data();
 
157
    void redo();
 
158
 
 
159
    void undo_data();
 
160
    void undo();
 
161
 
 
162
    void undo_keypressevents_data();
 
163
    void undo_keypressevents();
 
164
 
 
165
#ifndef QT_NO_CLIPBOARD
 
166
    void QTBUG5786_undoPaste();
 
167
#endif
 
168
 
 
169
    void clear();
 
170
 
 
171
    void text_data();
 
172
    void text();
 
173
    void textMask_data();
 
174
    void textMask();
 
175
    void maskCharacter();
 
176
    void maskCharacter_data();
 
177
    void setText();
 
178
 
 
179
    void displayText_data();
 
180
    void displayText();
 
181
    void passwordEchoOnEdit();
 
182
    void passwordEchoDelay();
 
183
 
 
184
    void maxLength_mask_data();
 
185
    void maxLength_mask();
 
186
 
 
187
    void maxLength_data();
 
188
    void maxLength();
 
189
 
 
190
    void isReadOnly();
 
191
 
 
192
    void noCursorBlinkWhenReadOnly();
 
193
 
 
194
    void cursorPosition();
 
195
 
 
196
    void cursorPositionChanged_data();
 
197
    void cursorPositionChanged();
 
198
 
 
199
    void selectedText();
 
200
    void deleteSelectedText();
 
201
 
 
202
    void textChangedAndTextEdited();
 
203
    void returnPressed();
 
204
    void returnPressed_maskvalidator_data();
 
205
    void returnPressed_maskvalidator();
 
206
 
 
207
    void setValidator();
 
208
    void setValidator_QIntValidator_data();
 
209
    void setValidator_QIntValidator();
 
210
 
 
211
    void frame_data();
 
212
    void frame();
 
213
 
 
214
    void leftKeyOnSelectedText();
 
215
 
 
216
    void setAlignment_data();
 
217
    void setAlignment();
 
218
 
 
219
    void isModified();
 
220
    void edited();
 
221
 
 
222
    void insert();
 
223
    void setSelection_data();
 
224
    void setSelection();
 
225
 
 
226
#ifndef QT_NO_CLIPBOARD
 
227
    void cut();
 
228
#endif
 
229
    void maxLengthAndInputMask();
 
230
    void returnPressedKeyEvent();
 
231
 
 
232
    void keepSelectionOnTabFocusIn();
 
233
 
 
234
    void readOnlyStyleOption();
 
235
 
 
236
    void validateOnFocusOut();
 
237
 
 
238
    void editInvalidText();
 
239
 
 
240
    void charWithAltOrCtrlModifier();
 
241
 
 
242
    void inlineCompletion();
 
243
 
 
244
    void noTextEditedOnClear();
 
245
 
 
246
#ifndef QTEST_NO_CURSOR
 
247
    void cursor();
 
248
#endif
 
249
 
 
250
    void textMargin_data();
 
251
    void textMargin();
 
252
 
 
253
    // task-specific tests:
 
254
    void task180999_focus();
 
255
    void task174640_editingFinished();
 
256
#ifndef QT_NO_COMPLETER
 
257
    void task198789_currentCompletion();
 
258
    void task210502_caseInsensitiveInlineCompletion();
 
259
#endif
 
260
    void task229938_dontEmitChangedWhenTextIsNotChanged();
 
261
    void task233101_cursorPosAfterInputMethod_data();
 
262
    void task233101_cursorPosAfterInputMethod();
 
263
    void task241436_passwordEchoOnEditRestoreEchoMode();
 
264
    void task248948_redoRemovedSelection();
 
265
    void taskQTBUG_4401_enterKeyClearsPassword();
 
266
    void taskQTBUG_4679_moveToStartEndOfBlock();
 
267
    void taskQTBUG_4679_selectToStartEndOfBlock();
 
268
#ifndef QT_NO_CONTEXTMENU
 
269
    void taskQTBUG_7902_contextMenuCrash();
 
270
#endif
 
271
    void taskQTBUG_7395_readOnlyShortcut();
 
272
    void QTBUG697_paletteCurrentColorGroup();
 
273
    void QTBUG13520_textNotVisible();
 
274
    void QTBUG7174_inputMaskCursorBlink();
 
275
    void QTBUG16850_setSelection();
 
276
 
 
277
    void bidiVisualMovement_data();
 
278
    void bidiVisualMovement();
 
279
 
 
280
    void bidiLogicalMovement_data();
 
281
    void bidiLogicalMovement();
 
282
 
 
283
    void selectAndCursorPosition();
 
284
    void inputMethod();
 
285
    void inputMethodSelection();
 
286
 
 
287
    void inputMethodQueryImHints_data();
 
288
    void inputMethodQueryImHints();
 
289
 
 
290
    void undoRedoAndEchoModes_data();
 
291
    void undoRedoAndEchoModes();
 
292
 
 
293
protected slots:
 
294
    void editingFinished();
 
295
 
 
296
    void onTextChanged( const QString &newString );
 
297
    void onTextEdited( const QString &newString );
 
298
    void onReturnPressed();
 
299
    void onSelectionChanged();
 
300
    void onCursorPositionChanged(int oldpos, int newpos);
 
301
 
 
302
private:
 
303
    // keyClicks(..) is moved to QtTestCase
 
304
    void psKeyClick(QWidget *target, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
 
305
    void psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
 
306
 
 
307
    bool validInput;
 
308
    QString changed_string;
 
309
    int changed_count;
 
310
    int edited_count;
 
311
    int return_count;
 
312
    int selection_count;
 
313
    int lastCursorPos;
 
314
    int newCursorPos;
 
315
    QLineEdit *testWidget;
 
316
    int m_keyboardScheme;
 
317
    PlatformInputContext m_platformInputContext;
 
318
};
 
319
 
 
320
typedef QList<int> IntList;
 
321
Q_DECLARE_METATYPE(QLineEdit::EchoMode)
 
322
 
 
323
// Testing get/set functions
 
324
void tst_QLineEdit::getSetCheck()
 
325
{
 
326
    QLineEdit obj1;
 
327
    // const QValidator * QLineEdit::validator()
 
328
    // void QLineEdit::setValidator(const QValidator *)
 
329
    QIntValidator *var1 = new QIntValidator(0);
 
330
    obj1.setValidator(var1);
 
331
    QCOMPARE((const QValidator *)var1, obj1.validator());
 
332
    obj1.setValidator((QValidator *)0);
 
333
    QCOMPARE((const QValidator *)0, obj1.validator());
 
334
    delete var1;
 
335
 
 
336
    // bool QLineEdit::dragEnabled()
 
337
    // void QLineEdit::setDragEnabled(bool)
 
338
    obj1.setDragEnabled(false);
 
339
    QCOMPARE(false, obj1.dragEnabled());
 
340
    obj1.setDragEnabled(true);
 
341
    QCOMPARE(true, obj1.dragEnabled());
 
342
}
 
343
 
 
344
tst_QLineEdit::tst_QLineEdit() : validInput(false), m_keyboardScheme(0)
 
345
{
 
346
    if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
 
347
        m_keyboardScheme = theme->themeHint(QPlatformTheme::KeyboardScheme).toInt();
 
348
    // Generalize for X11
 
349
    if (m_keyboardScheme == QPlatformTheme::KdeKeyboardScheme
 
350
            || m_keyboardScheme == QPlatformTheme::GnomeKeyboardScheme
 
351
            || m_keyboardScheme == QPlatformTheme::CdeKeyboardScheme) {
 
352
        m_keyboardScheme = QPlatformTheme::X11KeyboardScheme;
 
353
    }
 
354
}
 
355
 
 
356
tst_QLineEdit::~tst_QLineEdit()
 
357
{
 
358
}
 
359
 
 
360
void tst_QLineEdit::initTestCase()
 
361
{
 
362
    testWidget = new QLineEdit(0);
 
363
    testWidget->setObjectName("testWidget");
 
364
    connect(testWidget, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onCursorPositionChanged(int,int)));
 
365
    connect(testWidget, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
 
366
    connect(testWidget, SIGNAL(textEdited(QString)), this, SLOT(onTextEdited(QString)));
 
367
    connect(testWidget, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
 
368
    connect(testWidget, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
 
369
    connect(testWidget, SIGNAL(editingFinished()), this, SLOT(editingFinished()));
 
370
 
 
371
    testWidget->resize(200,50);
 
372
    testWidget->show();
 
373
    QVERIFY(QTest::qWaitForWindowExposed(testWidget));
 
374
    QApplication::setActiveWindow(testWidget);
 
375
    QTRY_VERIFY(testWidget->hasFocus());
 
376
 
 
377
    changed_count = 0;
 
378
    edited_count = 0;
 
379
    selection_count = 0;
 
380
 
 
381
    QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
 
382
    inputMethodPrivate->testContext = &m_platformInputContext;
 
383
}
 
384
 
 
385
void tst_QLineEdit::cleanupTestCase()
 
386
{
 
387
    delete testWidget;
 
388
    QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
 
389
    inputMethodPrivate->testContext = 0;
 
390
}
 
391
 
 
392
void tst_QLineEdit::init()
 
393
{
 
394
    return_count = 0;
 
395
    testWidget->clear();
 
396
    testWidget->setEchoMode(QLineEdit::Normal);
 
397
    testWidget->setMaxLength(32767);
 
398
    testWidget->setReadOnly(false);
 
399
    testWidget->setText("");
 
400
    testWidget->setInputMask("");
 
401
    testWidget->setFrame(true);
 
402
    testWidget->setValidator(0);
 
403
    testWidget->setDragEnabled(true);
 
404
}
 
405
 
 
406
void tst_QLineEdit::cleanup()
 
407
{
 
408
}
 
409
 
 
410
void tst_QLineEdit::experimental()
 
411
{
 
412
    QIntValidator intValidator(3, 7, 0);
 
413
    testWidget->setValidator(&intValidator);
 
414
    testWidget->setText("");
 
415
 
 
416
 
 
417
    // test the order of setting these
 
418
    testWidget->setInputMask("");
 
419
    testWidget->setText("abc123");
 
420
    testWidget->setInputMask("000.000.000.000");
 
421
    QCOMPARE(testWidget->text(), QString("123..."));
 
422
    testWidget->setText("");
 
423
 
 
424
 
 
425
}
 
426
 
 
427
void tst_QLineEdit::upperAndLowercase()
 
428
{
 
429
    testWidget->setInputMask("");
 
430
    testWidget->setText("");
 
431
 
 
432
    QTest::keyClicks(testWidget, "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?");
 
433
    qApp->processEvents();
 
434
    QCOMPARE(testWidget->text(), QString("aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?"));
 
435
}
 
436
 
 
437
void tst_QLineEdit::setInputMask_data()
 
438
{
 
439
    QTest::addColumn<QString>("mask");
 
440
    QTest::addColumn<QString>("input");
 
441
    QTest::addColumn<QString>("expectedText");
 
442
    QTest::addColumn<QString>("expectedDisplay");
 
443
    QTest::addColumn<bool>("insert_text");
 
444
 
 
445
    // both keyboard and insert()
 
446
    for (int i=0; i<2; i++) {
 
447
        bool insert_text = i==0 ? false : true;
 
448
        QString insert_mode = "keys ";
 
449
        if (insert_text)
 
450
            insert_mode = "insert ";
 
451
 
 
452
        QTest::newRow(QString(insert_mode + "ip_localhost").toLatin1())
 
453
            << QString("000.000.000.000")
 
454
            << QString("127.0.0.1")
 
455
            << QString("127.0.0.1")
 
456
            << QString("127.0  .0  .1  ")
 
457
            << bool(insert_text);
 
458
        QTest::newRow(QString(insert_mode + "mac").toLatin1())
 
459
            << QString("HH:HH:HH:HH:HH:HH;#")
 
460
            << QString("00:E0:81:21:9E:8E")
 
461
            << QString("00:E0:81:21:9E:8E")
 
462
            << QString("00:E0:81:21:9E:8E")
 
463
            << bool(insert_text);
 
464
        QTest::newRow(QString(insert_mode + "mac2").toLatin1())
 
465
            << QString("<HH:>HH:!HH:HH:HH:HH;#")
 
466
            << QString("AAe081219E8E")
 
467
            << QString("aa:E0:81:21:9E:8E")
 
468
            << QString("aa:E0:81:21:9E:8E")
 
469
            << bool(insert_text);
 
470
        QTest::newRow(QString(insert_mode + "byte").toLatin1())
 
471
            << QString("BBBBBBBB;0")
 
472
            << QString("11011001")
 
473
            << QString("11111")
 
474
            << QString("11011001")
 
475
            << bool(insert_text);
 
476
        QTest::newRow(QString(insert_mode + "halfbytes").toLatin1())
 
477
            << QString("bbbb.bbbb;-")
 
478
            << QString("110. 0001")
 
479
            << QString("110.0001")
 
480
            << QString("110-.0001")
 
481
            << bool(insert_text);
 
482
        QTest::newRow(QString(insert_mode + "blank char same type as content").toLatin1())
 
483
            << QString("000.000.000.000;0")
 
484
            << QString("127.0.0.1")
 
485
            << QString("127...1")
 
486
            << QString("127.000.000.100")
 
487
            << bool(insert_text);
 
488
        QTest::newRow(QString(insert_mode + "parts of ip_localhost").toLatin1())
 
489
            << QString("000.000.000.000")
 
490
            << QString(".0.0.1")
 
491
            << QString(".0.0.1")
 
492
            << QString("   .0  .0  .1  ")
 
493
            << bool(insert_text);
 
494
        QTest::newRow(QString(insert_mode + "ip_null").toLatin1())
 
495
            << QString("000.000.000.000")
 
496
            << QString()
 
497
            << QString("...")
 
498
            << QString("   .   .   .   ")
 
499
            << bool(insert_text);
 
500
        QTest::newRow(QString(insert_mode + "ip_null_hash").toLatin1())
 
501
            << QString("000.000.000.000;#")
 
502
            << QString()
 
503
            << QString("...")
 
504
            << QString("###.###.###.###")
 
505
            << bool(insert_text);
 
506
        QTest::newRow(QString(insert_mode + "ip_overflow").toLatin1())
 
507
            << QString("000.000.000.000")
 
508
            << QString("1234123412341234")
 
509
            << QString("123.412.341.234")
 
510
            << QString("123.412.341.234")
 
511
            << bool(insert_text);
 
512
        QTest::newRow(QString(insert_mode + "uppercase").toLatin1())
 
513
            << QString(">AAAA")
 
514
            << QString("AbCd")
 
515
            << QString("ABCD")
 
516
            << QString("ABCD")
 
517
            << bool(insert_text);
 
518
        QTest::newRow(QString(insert_mode + "lowercase").toLatin1())
 
519
            << QString("<AAAA")
 
520
            << QString("AbCd")
 
521
            << QString("abcd")
 
522
            << QString("abcd")
 
523
            << bool(insert_text);
 
524
 
 
525
        QTest::newRow(QString(insert_mode + "nocase").toLatin1())
 
526
            << QString("!AAAA")
 
527
            << QString("AbCd")
 
528
            << QString("AbCd")
 
529
            << QString("AbCd")
 
530
            << bool(insert_text);
 
531
        QTest::newRow(QString(insert_mode + "nocase1").toLatin1())
 
532
            << QString("!A!A!A!A")
 
533
            << QString("AbCd")
 
534
            << QString("AbCd")
 
535
            << QString("AbCd")
 
536
            << bool(insert_text);
 
537
        QTest::newRow(QString(insert_mode + "nocase2").toLatin1())
 
538
            << QString("AAAA")
 
539
            << QString("AbCd")
 
540
            << QString("AbCd")
 
541
            << QString("AbCd")
 
542
            << bool(insert_text);
 
543
 
 
544
        QTest::newRow(QString(insert_mode + "reserved").toLatin1())
 
545
            << QString("{n}[0]")
 
546
            << QString("A9")
 
547
            << QString("A9")
 
548
            << QString("A9")
 
549
            << bool(insert_text);
 
550
        QTest::newRow(QString(insert_mode + "escape01").toLatin1())
 
551
            << QString("\\N\\n00")
 
552
            << QString("9")
 
553
            << QString("Nn9")
 
554
            << QString("Nn9 ")
 
555
            << bool(insert_text);
 
556
        QTest::newRow(QString(insert_mode + "escape02").toLatin1())
 
557
            << QString("\\\\00")
 
558
            << QString("0")
 
559
            << QString("\\0")
 
560
            << QString("\\0 ")
 
561
            << bool(insert_text);
 
562
        QTest::newRow(QString(insert_mode + "escape03").toLatin1())
 
563
            << QString("\\(00\\)")
 
564
            << QString("0")
 
565
            << QString("(0)")
 
566
            << QString("(0 )")
 
567
            << bool(insert_text);
 
568
 
 
569
        QTest::newRow(QString(insert_mode + "upper_lower_nocase1").toLatin1())
 
570
            << QString(">AAAA<AAAA!AAAA")
 
571
            << QString("AbCdEfGhIjKl")
 
572
            << QString("ABCDefghIjKl")
 
573
            << QString("ABCDefghIjKl")
 
574
            << bool(insert_text);
 
575
        QTest::newRow(QString(insert_mode + "upper_lower_nocase2").toLatin1())
 
576
            << QString(">aaaa<aaaa!aaaa")
 
577
            << QString("AbCdEfGhIjKl")
 
578
            << QString("ABCDefghIjKl")
 
579
            << QString("ABCDefghIjKl")
 
580
            << bool(insert_text);
 
581
 
 
582
        QTest::newRow(QString(insert_mode + "exact_case1").toLatin1())
 
583
            << QString(">A<A<A>A>A<A!A!A")
 
584
            << QString("AbCdEFGH")
 
585
            << QString("AbcDEfGH")
 
586
            << QString("AbcDEfGH")
 
587
            << bool(insert_text);
 
588
        QTest::newRow(QString(insert_mode + "exact_case2").toLatin1())
 
589
            << QString(">A<A<A>A>A<A!A!A")
 
590
            << QString("aBcDefgh")
 
591
            << QString("AbcDEfgh")
 
592
            << QString("AbcDEfgh")
 
593
            << bool(insert_text);
 
594
        QTest::newRow(QString(insert_mode + "exact_case3").toLatin1())
 
595
            << QString(">a<a<a>a>a<a!a!a")
 
596
            << QString("AbCdEFGH")
 
597
            << QString("AbcDEfGH")
 
598
            << QString("AbcDEfGH")
 
599
            << bool(insert_text);
 
600
        QTest::newRow(QString(insert_mode + "exact_case4").toLatin1())
 
601
            << QString(">a<a<a>a>a<a!a!a")
 
602
            << QString("aBcDefgh")
 
603
            << QString("AbcDEfgh")
 
604
            << QString("AbcDEfgh")
 
605
            << bool(insert_text);
 
606
        QTest::newRow(QString(insert_mode + "exact_case5").toLatin1())
 
607
            << QString(">H<H<H>H>H<H!H!H")
 
608
            << QString("aBcDef01")
 
609
            << QString("AbcDEf01")
 
610
            << QString("AbcDEf01")
 
611
            << bool(insert_text);
 
612
        QTest::newRow(QString(insert_mode + "exact_case6").toLatin1())
 
613
            << QString(">h<h<h>h>h<h!h!h")
 
614
            << QString("aBcDef92")
 
615
            << QString("AbcDEf92")
 
616
            << QString("AbcDEf92")
 
617
            << bool(insert_text);
 
618
 
 
619
        QTest::newRow(QString(insert_mode + "illegal_keys1").toLatin1())
 
620
            << QString("AAAAAAAA")
 
621
            << QString("A2#a;.0!")
 
622
            << QString("Aa")
 
623
            << QString("Aa      ")
 
624
            << bool(insert_text);
 
625
        QTest::newRow(QString(insert_mode + "illegal_keys2").toLatin1())
 
626
            << QString("AAAA")
 
627
            << QString("f4f4f4f4")
 
628
            << QString("ffff")
 
629
            << QString("ffff")
 
630
            << bool(insert_text);
 
631
        QTest::newRow(QString(insert_mode + "blank=input").toLatin1())
 
632
            << QString("9999;0")
 
633
            << QString("2004")
 
634
            << QString("2004")
 
635
            << QString("2004")
 
636
            << bool(insert_text);
 
637
    }
 
638
}
 
639
 
 
640
void tst_QLineEdit::setInputMask()
 
641
{
 
642
    QFETCH(QString, mask);
 
643
    QFETCH(QString, input);
 
644
    QFETCH(QString, expectedText);
 
645
    QFETCH(QString, expectedDisplay);
 
646
    QFETCH(bool, insert_text);
 
647
 
 
648
    QEXPECT_FAIL( "keys blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
 
649
    QEXPECT_FAIL( "insert blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
 
650
 
 
651
    // First set the input mask
 
652
    testWidget->setInputMask(mask);
 
653
 
 
654
    // then either insert using insert() or keyboard
 
655
    if (insert_text) {
 
656
        testWidget->insert(input);
 
657
    } else {
 
658
        psKeyClick(testWidget, Qt::Key_Home);
 
659
        for (int i=0; i<input.length(); i++)
 
660
            QTest::keyClick(testWidget, input.at(i).toLatin1());
 
661
    }
 
662
 
 
663
    QCOMPARE(testWidget->text(), expectedText);
 
664
    QCOMPARE(testWidget->displayText(), expectedDisplay);
 
665
}
 
666
 
 
667
void tst_QLineEdit::inputMask_data()
 
668
{
 
669
    QTest::addColumn<QString>("mask");
 
670
    QTest::addColumn<QString>("expectedMask");
 
671
 
 
672
    // if no mask is set a nul string should be returned
 
673
    QTest::newRow("nul 1") << QString("") << QString();
 
674
    QTest::newRow("nul 2") << QString() << QString();
 
675
 
 
676
    // try different masks
 
677
    QTest::newRow("mask 1") << QString("000.000.000.000") << QString("000.000.000.000");
 
678
    QTest::newRow("mask 2") << QString("000.000.000.000;#") << QString("000.000.000.000;#");
 
679
    QTest::newRow("mask 3") << QString("AAA.aa.999.###;") << QString("AAA.aa.999.###");
 
680
    QTest::newRow("mask 4") << QString(">abcdef<GHIJK") << QString(">abcdef<GHIJK");
 
681
 
 
682
    // set an invalid input mask...
 
683
    // the current behaviour is that this exact (faulty) string is returned.
 
684
    QTest::newRow("invalid") << QString("ABCDEFGHIKLMNOP;") << QString("ABCDEFGHIKLMNOP");
 
685
 
 
686
    // verify that we can unset the mask again
 
687
    QTest::newRow("unset") << QString("") << QString();
 
688
}
 
689
 
 
690
void tst_QLineEdit::inputMask()
 
691
{
 
692
    QFETCH(QString, mask);
 
693
    QFETCH(QString, expectedMask);
 
694
 
 
695
    testWidget->setInputMask(mask);
 
696
    QCOMPARE(testWidget->inputMask(), expectedMask);
 
697
}
 
698
 
 
699
void tst_QLineEdit::clearInputMask()
 
700
{
 
701
    testWidget->setInputMask("000.000.000.000");
 
702
    QVERIFY(testWidget->inputMask() != QString::null);
 
703
    testWidget->setInputMask(QString::null);
 
704
    QCOMPARE(testWidget->inputMask(), QString());
 
705
}
 
706
 
 
707
void tst_QLineEdit::keypress_inputMask_data()
 
708
{
 
709
    QTest::addColumn<QString>("mask");
 
710
    QTest::addColumn<QTestEventList>("keys");
 
711
    QTest::addColumn<QString>("expectedText");
 
712
    QTest::addColumn<QString>("expectedDisplayText");
 
713
 
 
714
    {
 
715
        QTestEventList keys;
 
716
        // inserting 'A1.2B'
 
717
        keys.addKeyClick(Qt::Key_Home);
 
718
        keys.addKeyClick(Qt::Key_A);
 
719
        keys.addKeyClick(Qt::Key_1);
 
720
        keys.addKeyClick(Qt::Key_Period);
 
721
        keys.addKeyClick(Qt::Key_2);
 
722
        keys.addKeyClick(Qt::Key_B);
 
723
        QTest::newRow("jumping on period(separator)") << QString("000.000;_") << keys << QString("1.2") << QString("1__.2__");
 
724
    }
 
725
    {
 
726
        QTestEventList keys;
 
727
        // inserting 'A1.2B'
 
728
        keys.addKeyClick(Qt::Key_Home);
 
729
        keys.addKeyClick(Qt::Key_0);
 
730
        keys.addKeyClick(Qt::Key_Exclam);
 
731
        keys.addKeyClick('P');
 
732
        keys.addKeyClick(Qt::Key_3);
 
733
        QTest::newRow("jumping on input") << QString("D0.AA.XX.AA.00;_") << keys << QString("0..!P..3") << QString("_0.__.!P.__.3_");
 
734
    }
 
735
    {
 
736
        QTestEventList keys;
 
737
        // pressing delete
 
738
        keys.addKeyClick(Qt::Key_Home);
 
739
        keys.addKeyClick(Qt::Key_Delete);
 
740
        QTest::newRow("delete") << QString("000.000;_") << keys << QString(".") << QString("___.___");
 
741
    }
 
742
    {
 
743
        QTestEventList keys;
 
744
        // selecting all and delete
 
745
        keys.addKeyClick(Qt::Key_Home);
 
746
        keys.addKeyClick(Qt::Key_End, Qt::ShiftModifier);
 
747
        keys.addKeyClick(Qt::Key_Delete);
 
748
        QTest::newRow("deleting all") << QString("000.000;_") << keys << QString(".") << QString("___.___");
 
749
    }
 
750
    {
 
751
        QTestEventList keys;
 
752
        // inserting '12.12' then two backspaces
 
753
        keys.addKeyClick(Qt::Key_Home);
 
754
        keys.addKeyClick(Qt::Key_1);
 
755
        keys.addKeyClick(Qt::Key_2);
 
756
        keys.addKeyClick(Qt::Key_Period);
 
757
        keys.addKeyClick(Qt::Key_1);
 
758
        keys.addKeyClick(Qt::Key_2);
 
759
        keys.addKeyClick(Qt::Key_Backspace);
 
760
        keys.addKeyClick(Qt::Key_Backspace);
 
761
        QTest::newRow("backspace") << QString("000.000;_") << keys << QString("12.") << QString("12_.___");
 
762
    }
 
763
    {
 
764
        QTestEventList keys;
 
765
        // inserting '12ab'
 
766
        keys.addKeyClick(Qt::Key_Home);
 
767
        keys.addKeyClick(Qt::Key_1);
 
768
        keys.addKeyClick(Qt::Key_2);
 
769
        keys.addKeyClick(Qt::Key_A);
 
770
        keys.addKeyClick(Qt::Key_B);
 
771
        QTest::newRow("uppercase") << QString("9999 >AA;_") << keys << QString("12 AB") << QString("12__ AB");
 
772
    }
 
773
}
 
774
 
 
775
void tst_QLineEdit::keypress_inputMask()
 
776
{
 
777
    QFETCH(QString, mask);
 
778
    QFETCH(QTestEventList, keys);
 
779
    QFETCH(QString, expectedText);
 
780
    QFETCH(QString, expectedDisplayText);
 
781
 
 
782
    testWidget->setInputMask(mask);
 
783
    keys.simulate(testWidget);
 
784
 
 
785
    QCOMPARE(testWidget->text(), expectedText);
 
786
    QCOMPARE(testWidget->displayText(), expectedDisplayText);
 
787
}
 
788
 
 
789
 
 
790
void tst_QLineEdit::hasAcceptableInputMask_data()
 
791
{
 
792
    QTest::addColumn<QString>("optionalMask");
 
793
    QTest::addColumn<QString>("requiredMask");
 
794
    QTest::addColumn<QString>("invalid");
 
795
    QTest::addColumn<QString>("valid");
 
796
 
 
797
    QTest::newRow("Alphabetic optional and required")
 
798
        << QString("aaaa") << QString("AAAA") << QString("ab") << QString("abcd");
 
799
    QTest::newRow("Alphanumeric optional and require")
 
800
        << QString("nnnn") << QString("NNNN") << QString("R2") << QString("R2D2");
 
801
    QTest::newRow("Any optional and required")
 
802
        << QString("xxxx") << QString("XXXX") << QString("+-") << QString("+-*/");
 
803
    QTest::newRow("Numeric (0-9) required")
 
804
        << QString("0000") << QString("9999") << QString("11") << QString("1138");
 
805
    QTest::newRow("Numeric (1-9) optional and required")
 
806
        << QString("dddd") << QString("DDDD") << QString("12") << QString("1234");
 
807
}
 
808
 
 
809
void tst_QLineEdit::hasAcceptableInputMask()
 
810
{
 
811
    QFocusEvent lostFocus(QEvent::FocusOut);
 
812
    QFETCH(QString, optionalMask);
 
813
    QFETCH(QString, requiredMask);
 
814
    QFETCH(QString, invalid);
 
815
    QFETCH(QString, valid);
 
816
 
 
817
    // test that invalid input (for required) work for optionalMask
 
818
    testWidget->setInputMask(optionalMask);
 
819
    validInput = false;
 
820
    testWidget->setText(invalid);
 
821
    qApp->sendEvent(testWidget, &lostFocus);
 
822
    QVERIFY(validInput);
 
823
 
 
824
    // at the moment we don't strip the blank character if it is valid input, this makes the test between x vs X useless
 
825
    QEXPECT_FAIL( "Any optional and required", "To eat blanks or not? Known issue. Task 43172", Abort);
 
826
 
 
827
    // test requiredMask
 
828
    testWidget->setInputMask(requiredMask);
 
829
    validInput = true;
 
830
    testWidget->setText(invalid);
 
831
    validInput = testWidget->hasAcceptableInput();
 
832
    QVERIFY(!validInput);
 
833
 
 
834
    validInput = false;
 
835
    testWidget->setText(valid);
 
836
    qApp->sendEvent(testWidget, &lostFocus);
 
837
    QVERIFY(validInput);
 
838
}
 
839
 
 
840
static const int chars = 8;
 
841
class ValidatorWithFixup : public QValidator
 
842
{
 
843
public:
 
844
    ValidatorWithFixup(QWidget *parent = 0)
 
845
        : QValidator(parent)
 
846
    {}
 
847
 
 
848
    QValidator::State validate(QString &str, int &) const
 
849
    {
 
850
        const int s = str.size();
 
851
        if (s < chars) {
 
852
            return Intermediate;
 
853
        } else if (s > chars) {
 
854
            return Invalid;
 
855
        }
 
856
        return Acceptable;
 
857
    }
 
858
 
 
859
    void fixup(QString &str) const
 
860
    {
 
861
        str = str.leftJustified(chars, 'X', true);
 
862
    }
 
863
};
 
864
 
 
865
 
 
866
 
 
867
void tst_QLineEdit::hasAcceptableInputValidator()
 
868
{
 
869
    QFocusEvent lostFocus(QEvent::FocusOut);
 
870
    ValidatorWithFixup val;
 
871
    testWidget->setValidator(&val);
 
872
    testWidget->setText("foobar");
 
873
    qApp->sendEvent(testWidget, &lostFocus);
 
874
    QVERIFY(testWidget->hasAcceptableInput());
 
875
}
 
876
 
 
877
 
 
878
 
 
879
void tst_QLineEdit::maskCharacter_data()
 
880
{
 
881
    QTest::addColumn<QString>("mask");
 
882
    QTest::addColumn<QString>("input");
 
883
    QTest::addColumn<bool>("expectedValid");
 
884
 
 
885
    QTest::newRow("Hex") << QString("H")
 
886
                         << QString("0123456789abcdefABCDEF") << true;
 
887
    QTest::newRow("hex") << QString("h")
 
888
                         << QString("0123456789abcdefABCDEF") << true;
 
889
    QTest::newRow("HexInvalid") << QString("H")
 
890
                                << QString("ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ")
 
891
                                << false;
 
892
    QTest::newRow("hexInvalid") << QString("h")
 
893
                                << QString("ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ")
 
894
                                << false;
 
895
    QTest::newRow("Bin") << QString("B")
 
896
                         << QString("01") << true;
 
897
    QTest::newRow("bin") << QString("b")
 
898
                         << QString("01") << true;
 
899
    QTest::newRow("BinInvalid") << QString("B")
 
900
                                << QString("23456789qwertyuiopasdfghjklzxcvbnm")
 
901
                                << false;
 
902
    QTest::newRow("binInvalid") << QString("b")
 
903
                                << QString("23456789qwertyuiopasdfghjklzxcvbnm")
 
904
                                << false;
 
905
}
 
906
 
 
907
void tst_QLineEdit::maskCharacter()
 
908
{
 
909
    QFETCH(QString, mask);
 
910
    QFETCH(QString, input);
 
911
    QFETCH(bool, expectedValid);
 
912
 
 
913
    QFocusEvent lostFocus(QEvent::FocusOut);
 
914
 
 
915
    testWidget->setInputMask(mask);
 
916
    for (int i = 0; i < input.size(); ++i) {
 
917
        QString in = QString(input.at(i));
 
918
        QString expected = expectedValid ? in : QString();
 
919
        testWidget->setText(QString(input.at(i)));
 
920
        qApp->sendEvent(testWidget, &lostFocus);
 
921
        QCOMPARE(testWidget->text(), expected);
 
922
    }
 
923
}
 
924
 
 
925
#define NORMAL 0
 
926
#define REPLACE_UNTIL_END 1
 
927
 
 
928
void tst_QLineEdit::undo_data()
 
929
{
 
930
    QTest::addColumn<QStringList>("insertString");
 
931
    QTest::addColumn<IntList>("insertIndex");
 
932
    QTest::addColumn<IntList>("insertMode");
 
933
    QTest::addColumn<QStringList>("expectedString");
 
934
    QTest::addColumn<bool>("use_keys");
 
935
 
 
936
    for (int i=0; i<2; i++) {
 
937
        QString keys_str = "keyboard";
 
938
        bool use_keys = true;
 
939
        if (i==0) {
 
940
            keys_str = "insert";
 
941
            use_keys = false;
 
942
        }
 
943
 
 
944
        {
 
945
            IntList insertIndex;
 
946
            IntList insertMode;
 
947
            QStringList insertString;
 
948
            QStringList expectedString;
 
949
 
 
950
            insertIndex << -1;
 
951
            insertMode << NORMAL;
 
952
            insertString << "1";
 
953
 
 
954
            insertIndex << -1;
 
955
            insertMode << NORMAL;
 
956
            insertString << "5";
 
957
 
 
958
            insertIndex << 1;
 
959
            insertMode << NORMAL;
 
960
            insertString << "3";
 
961
 
 
962
            insertIndex << 1;
 
963
            insertMode << NORMAL;
 
964
            insertString << "2";
 
965
 
 
966
            insertIndex << 3;
 
967
            insertMode << NORMAL;
 
968
            insertString << "4";
 
969
 
 
970
            expectedString << "12345";
 
971
            expectedString << "1235";
 
972
            expectedString << "135";
 
973
            expectedString << "15";
 
974
            expectedString << "";
 
975
 
 
976
            QTest::newRow(QString(keys_str + "_numbers").toLatin1()) <<
 
977
                insertString <<
 
978
                insertIndex <<
 
979
                insertMode <<
 
980
                expectedString <<
 
981
                bool(use_keys);
 
982
        }
 
983
        {
 
984
            IntList insertIndex;
 
985
            IntList insertMode;
 
986
            QStringList insertString;
 
987
            QStringList expectedString;
 
988
 
 
989
            insertIndex << -1;
 
990
            insertMode << NORMAL;
 
991
            insertString << "World"; // World
 
992
 
 
993
            insertIndex << 0;
 
994
            insertMode << NORMAL;
 
995
            insertString << "Hello"; // HelloWorld
 
996
 
 
997
            insertIndex << 0;
 
998
            insertMode << NORMAL;
 
999
            insertString << "Well"; // WellHelloWorld
 
1000
 
 
1001
            insertIndex << 9;
 
1002
            insertMode << NORMAL;
 
1003
            insertString << "There"; // WellHelloThereWorld;
 
1004
 
 
1005
            expectedString << "WellHelloThereWorld";
 
1006
            expectedString << "WellHelloWorld";
 
1007
            expectedString << "HelloWorld";
 
1008
            expectedString << "World";
 
1009
            expectedString << "";
 
1010
 
 
1011
            QTest::newRow(QString(keys_str + "_helloworld").toLatin1()) <<
 
1012
                insertString <<
 
1013
                insertIndex <<
 
1014
                insertMode <<
 
1015
                expectedString <<
 
1016
                bool(use_keys);
 
1017
        }
 
1018
        {
 
1019
            IntList insertIndex;
 
1020
            IntList insertMode;
 
1021
            QStringList insertString;
 
1022
            QStringList expectedString;
 
1023
 
 
1024
            insertIndex << -1;
 
1025
            insertMode << NORMAL;
 
1026
            insertString << "Ensuring";
 
1027
 
 
1028
            insertIndex << -1;
 
1029
            insertMode << NORMAL;
 
1030
            insertString << " instan";
 
1031
 
 
1032
            insertIndex << 9;
 
1033
            insertMode << NORMAL;
 
1034
            insertString << "an ";
 
1035
 
 
1036
            insertIndex << 10;
 
1037
            insertMode << REPLACE_UNTIL_END;
 
1038
            insertString << " unique instance.";
 
1039
 
 
1040
            expectedString << "Ensuring a unique instance.";
 
1041
            expectedString << "Ensuring an instan";
 
1042
            expectedString << "Ensuring instan";
 
1043
            expectedString << "";
 
1044
 
 
1045
            QTest::newRow(QString(keys_str + "_patterns").toLatin1()) <<
 
1046
                insertString <<
 
1047
                insertIndex <<
 
1048
                insertMode <<
 
1049
                expectedString <<
 
1050
                bool(use_keys);
 
1051
        }
 
1052
    }
 
1053
}
 
1054
 
 
1055
void tst_QLineEdit::undo()
 
1056
{
 
1057
    QFETCH(QStringList, insertString);
 
1058
    QFETCH(IntList, insertIndex);
 
1059
    QFETCH(IntList, insertMode);
 
1060
    QFETCH(QStringList, expectedString);
 
1061
    QFETCH(bool, use_keys);
 
1062
 
 
1063
    QVERIFY(!testWidget->isUndoAvailable());
 
1064
 
 
1065
    int i;
 
1066
 
 
1067
// STEP 1: First build up an undo history by inserting or typing some strings...
 
1068
    for (i=0; i<insertString.size(); ++i) {
 
1069
        if (insertIndex[i] > -1)
 
1070
            testWidget->setCursorPosition(insertIndex[i]);
 
1071
 
 
1072
 // experimental stuff
 
1073
        if (insertMode[i] == REPLACE_UNTIL_END) {
 
1074
            testWidget->setSelection(insertIndex[i], 8);
 
1075
 
 
1076
            // This is what I actually want...
 
1077
            // QTest::keyClick(testWidget, Qt::Key_End, Qt::ShiftModifier);
 
1078
        }
 
1079
 
 
1080
        if (use_keys)
 
1081
            QTest::keyClicks(testWidget, insertString[i]);
 
1082
        else
 
1083
            testWidget->insert(insertString[i]);
 
1084
    }
 
1085
 
 
1086
// STEP 2: Next call undo several times and see if we can restore to the previous state
 
1087
    for (i=0; i<expectedString.size()-1; ++i) {
 
1088
        QCOMPARE(testWidget->text(), expectedString[i]);
 
1089
        QVERIFY(testWidget->isUndoAvailable());
 
1090
        testWidget->undo();
 
1091
    }
 
1092
 
 
1093
// STEP 3: Verify that we have undone everything
 
1094
    QVERIFY(!testWidget->isUndoAvailable());
 
1095
    QVERIFY(testWidget->text().isEmpty());
 
1096
 
 
1097
 
 
1098
    if (m_keyboardScheme == QPlatformTheme::WindowsKeyboardScheme) {
 
1099
        // Repeat the test using shortcut instead of undo()
 
1100
        for (i=0; i<insertString.size(); ++i) {
 
1101
            if (insertIndex[i] > -1)
 
1102
                testWidget->setCursorPosition(insertIndex[i]);
 
1103
            if (insertMode[i] == REPLACE_UNTIL_END)
 
1104
                testWidget->setSelection(insertIndex[i], 8);
 
1105
            if (use_keys)
 
1106
                QTest::keyClicks(testWidget, insertString[i]);
 
1107
            else
 
1108
                testWidget->insert(insertString[i]);
 
1109
        }
 
1110
        for (i=0; i<expectedString.size()-1; ++i) {
 
1111
            QCOMPARE(testWidget->text(), expectedString[i]);
 
1112
            QVERIFY(testWidget->isUndoAvailable());
 
1113
            QTest::keyClick(testWidget, Qt::Key_Backspace, Qt::AltModifier);
 
1114
        }
 
1115
    }
 
1116
 
 
1117
}
 
1118
 
 
1119
void tst_QLineEdit::redo_data()
 
1120
{
 
1121
    QTest::addColumn<QStringList>("insertString");
 
1122
    QTest::addColumn<IntList>("insertIndex");
 
1123
    QTest::addColumn<QStringList>("expectedString");
 
1124
 
 
1125
    {
 
1126
        IntList insertIndex;
 
1127
        QStringList insertString;
 
1128
        QStringList expectedString;
 
1129
 
 
1130
        insertIndex << -1;
 
1131
        insertString << "World"; // World
 
1132
        insertIndex << 0;
 
1133
        insertString << "Hello"; // HelloWorld
 
1134
        insertIndex << 0;
 
1135
        insertString << "Well"; // WellHelloWorld
 
1136
        insertIndex << 9;
 
1137
        insertString << "There"; // WellHelloThereWorld;
 
1138
 
 
1139
        expectedString << "World";
 
1140
        expectedString << "HelloWorld";
 
1141
        expectedString << "WellHelloWorld";
 
1142
        expectedString << "WellHelloThereWorld";
 
1143
 
 
1144
        QTest::newRow("Inserts and setting cursor") << insertString << insertIndex << expectedString;
 
1145
    }
 
1146
}
 
1147
 
 
1148
void tst_QLineEdit::redo()
 
1149
{
 
1150
    QFETCH(QStringList, insertString);
 
1151
    QFETCH(IntList, insertIndex);
 
1152
    QFETCH(QStringList, expectedString);
 
1153
 
 
1154
    QVERIFY(!testWidget->isUndoAvailable());
 
1155
    QVERIFY(!testWidget->isRedoAvailable());
 
1156
 
 
1157
    int i;
 
1158
    // inserts the diff strings at diff positions
 
1159
    for (i=0; i<insertString.size(); ++i) {
 
1160
        if (insertIndex[i] > -1)
 
1161
            testWidget->setCursorPosition(insertIndex[i]);
 
1162
        testWidget->insert(insertString[i]);
 
1163
    }
 
1164
 
 
1165
    QVERIFY(!testWidget->isRedoAvailable());
 
1166
 
 
1167
    // undo everything
 
1168
    while (!testWidget->text().isEmpty())
 
1169
        testWidget->undo();
 
1170
 
 
1171
    for (i=0; i<expectedString.size(); ++i) {
 
1172
        QVERIFY(testWidget->isRedoAvailable());
 
1173
        testWidget->redo();
 
1174
        QCOMPARE(testWidget->text() , expectedString[i]);
 
1175
    }
 
1176
 
 
1177
    QVERIFY(!testWidget->isRedoAvailable());
 
1178
 
 
1179
 
 
1180
    if (m_keyboardScheme == QPlatformTheme::WindowsKeyboardScheme) {
 
1181
        // repeat test, this time using shortcuts instead of undo()/redo()
 
1182
 
 
1183
        while (!testWidget->text().isEmpty())
 
1184
            QTest::keyClick(testWidget, Qt::Key_Backspace, Qt::AltModifier);
 
1185
 
 
1186
        for (i = 0; i < expectedString.size(); ++i) {
 
1187
            QVERIFY(testWidget->isRedoAvailable());
 
1188
            QTest::keyClick(testWidget, Qt::Key_Backspace,
 
1189
                            Qt::ShiftModifier | Qt::AltModifier);
 
1190
            QCOMPARE(testWidget->text() , expectedString[i]);
 
1191
        }
 
1192
 
 
1193
        QVERIFY(!testWidget->isRedoAvailable());
 
1194
    }
 
1195
}
 
1196
 
 
1197
void tst_QLineEdit::undo_keypressevents_data()
 
1198
{
 
1199
    QTest::addColumn<QTestEventList>("keys");
 
1200
    QTest::addColumn<QStringList>("expectedString");
 
1201
 
 
1202
    {
 
1203
        QTestEventList keys;
 
1204
        QStringList expectedString;
 
1205
 
 
1206
        keys.addKeyClick('A');
 
1207
        keys.addKeyClick('F');
 
1208
        keys.addKeyClick('R');
 
1209
        keys.addKeyClick('A');
 
1210
        keys.addKeyClick('I');
 
1211
        keys.addKeyClick('D');
 
1212
        psKeyClick(keys, Qt::Key_Home);
 
1213
 
 
1214
        keys.addKeyClick('V');
 
1215
        keys.addKeyClick('E');
 
1216
        keys.addKeyClick('R');
 
1217
        keys.addKeyClick('Y');
 
1218
 
 
1219
        keys.addKeyClick(Qt::Key_Left);
 
1220
        keys.addKeyClick(Qt::Key_Left);
 
1221
        keys.addKeyClick(Qt::Key_Left);
 
1222
        keys.addKeyClick(Qt::Key_Left);
 
1223
 
 
1224
        keys.addKeyClick('B');
 
1225
        keys.addKeyClick('E');
 
1226
        psKeyClick(keys, Qt::Key_End);
 
1227
 
 
1228
        keys.addKeyClick(Qt::Key_Exclam);
 
1229
 
 
1230
        expectedString << "BEVERYAFRAID!";
 
1231
        expectedString << "BEVERYAFRAID";
 
1232
        expectedString << "VERYAFRAID";
 
1233
        expectedString << "AFRAID";
 
1234
 
 
1235
        QTest::newRow("Inserts and moving cursor") << keys << expectedString;
 
1236
    }
 
1237
 
 
1238
    {
 
1239
        QTestEventList keys;
 
1240
        QStringList expectedString;
 
1241
 
 
1242
        // inserting '1234'
 
1243
        keys.addKeyClick(Qt::Key_1);
 
1244
        keys.addKeyClick(Qt::Key_2);
 
1245
        keys.addKeyClick(Qt::Key_3);
 
1246
        keys.addKeyClick(Qt::Key_4);
 
1247
        psKeyClick(keys, Qt::Key_Home);
 
1248
 
 
1249
        // skipping '12'
 
1250
        keys.addKeyClick(Qt::Key_Right);
 
1251
        keys.addKeyClick(Qt::Key_Right);
 
1252
 
 
1253
        // selecting '34'
 
1254
        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
 
1255
        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
 
1256
 
 
1257
        // deleting '34'
 
1258
        keys.addKeyClick(Qt::Key_Delete);
 
1259
 
 
1260
        expectedString << "12";
 
1261
        expectedString << "1234";
 
1262
 
 
1263
        QTest::newRow("Inserts,moving,selection and delete") << keys << expectedString;
 
1264
    }
 
1265
 
 
1266
    {
 
1267
        QTestEventList keys;
 
1268
        QStringList expectedString;
 
1269
 
 
1270
        // inserting 'AB12'
 
1271
        keys.addKeyClick('A');
 
1272
        keys.addKeyClick('B');
 
1273
 
 
1274
        keys.addKeyClick(Qt::Key_1);
 
1275
        keys.addKeyClick(Qt::Key_2);
 
1276
 
 
1277
        psKeyClick(keys, Qt::Key_Home);
 
1278
 
 
1279
        // selecting 'AB'
 
1280
        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
 
1281
        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
 
1282
 
 
1283
        // deleting 'AB'
 
1284
        keys.addKeyClick(Qt::Key_Delete);
 
1285
 
 
1286
        // undoing deletion of 'AB'
 
1287
        keys.addKeyClick(Qt::Key_Z, Qt::ControlModifier);
 
1288
 
 
1289
        // unselect any current selection
 
1290
        keys.addKeyClick(Qt::Key_Right);
 
1291
#ifdef Q_OS_WIN //Mac has a specialcase to handle jumping to the end of a selection
 
1292
        keys.addKeyClick(Qt::Key_Left);
 
1293
#endif
 
1294
 
 
1295
        // selecting '12'
 
1296
        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
 
1297
        keys.addKeyClick(Qt::Key_Right, Qt::ShiftModifier);
 
1298
 
 
1299
        // deleting '12'
 
1300
        keys.addKeyClick(Qt::Key_Delete);
 
1301
 
 
1302
        expectedString << "AB";
 
1303
        expectedString << "AB12";
 
1304
 
 
1305
        QTest::newRow("Inserts,moving,selection, delete and undo") << keys << expectedString;
 
1306
    }
 
1307
 
 
1308
    {
 
1309
        QTestEventList keys;
 
1310
        QStringList expectedString;
 
1311
 
 
1312
        // inserting 'ABCD'
 
1313
        keys.addKeyClick(Qt::Key_A);
 
1314
        keys.addKeyClick(Qt::Key_B);
 
1315
        keys.addKeyClick(Qt::Key_C);
 
1316
        keys.addKeyClick(Qt::Key_D);
 
1317
 
 
1318
        //move left two
 
1319
        keys.addKeyClick(Qt::Key_Left);
 
1320
        keys.addKeyClick(Qt::Key_Left);
 
1321
 
 
1322
        // inserting '1234'
 
1323
        keys.addKeyClick(Qt::Key_1);
 
1324
        keys.addKeyClick(Qt::Key_2);
 
1325
        keys.addKeyClick(Qt::Key_3);
 
1326
        keys.addKeyClick(Qt::Key_4);
 
1327
 
 
1328
        // selecting '1234'
 
1329
        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
 
1330
        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
 
1331
        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
 
1332
        keys.addKeyClick(Qt::Key_Left, Qt::ShiftModifier);
 
1333
 
 
1334
        // overwriting '1234' with '5'
 
1335
        keys.addKeyClick(Qt::Key_5);
 
1336
 
 
1337
        // undoing deletion of 'AB'
 
1338
        keys.addKeyClick(Qt::Key_Z, Qt::ControlModifier);
 
1339
 
 
1340
        // overwriting '1234' with '6'
 
1341
        keys.addKeyClick(Qt::Key_6);
 
1342
 
 
1343
        expectedString << "ab6cd";
 
1344
        // for versions previous to 3.2 we overwrite needed two undo operations
 
1345
        expectedString << "ab1234cd";
 
1346
        expectedString << "abcd";
 
1347
 
 
1348
        QTest::newRow("Inserts,moving,selection and undo, removing selection") << keys << expectedString;
 
1349
    }
 
1350
 
 
1351
    {
 
1352
        QTestEventList keys;
 
1353
        QStringList expectedString;
 
1354
 
 
1355
        // inserting 'ABC'
 
1356
        keys.addKeyClick('A');
 
1357
        keys.addKeyClick('B');
 
1358
        keys.addKeyClick('C');
 
1359
 
 
1360
        // removes 'C'
 
1361
        keys.addKeyClick(Qt::Key_Backspace);
 
1362
 
 
1363
        expectedString << "AB";
 
1364
        expectedString << "ABC";
 
1365
 
 
1366
        QTest::newRow("Inserts,backspace") << keys << expectedString;
 
1367
    }
 
1368
 
 
1369
    {
 
1370
        QTestEventList keys;
 
1371
        QStringList expectedString;
 
1372
 
 
1373
        // inserting 'ABC'
 
1374
        keys.addKeyClick('A');
 
1375
        keys.addKeyClick('B');
 
1376
        keys.addKeyClick('C');
 
1377
 
 
1378
        // removes 'C'
 
1379
        keys.addKeyClick(Qt::Key_Backspace);
 
1380
 
 
1381
        // inserting 'Z'
 
1382
        keys.addKeyClick('Z');
 
1383
 
 
1384
        expectedString << "ABZ";
 
1385
        expectedString << "AB";
 
1386
        expectedString << "ABC";
 
1387
 
 
1388
        QTest::newRow("Inserts,backspace,inserts") << keys << expectedString;
 
1389
    }
 
1390
 
 
1391
 
 
1392
    {
 
1393
        QTestEventList keys;
 
1394
        QStringList expectedString;
 
1395
 
 
1396
        // inserting '123'
 
1397
        keys.addKeyClick(Qt::Key_1);
 
1398
        keys.addKeyClick(Qt::Key_2);
 
1399
        keys.addKeyClick(Qt::Key_3);
 
1400
        psKeyClick(keys, Qt::Key_Home);
 
1401
 
 
1402
        // selecting '123'
 
1403
        psKeyClick(keys, Qt::Key_End, Qt::ShiftModifier);
 
1404
 
 
1405
        // overwriting '123' with 'ABC'
 
1406
        keys.addKeyClick('A');
 
1407
        keys.addKeyClick('B');
 
1408
        keys.addKeyClick('C');
 
1409
 
 
1410
        expectedString << "ABC";
 
1411
        // for versions previous to 3.2 we overwrite needed two undo operations
 
1412
        expectedString << "123";
 
1413
 
 
1414
        QTest::newRow("Inserts,moving,selection and overwriting") << keys << expectedString;
 
1415
    }
 
1416
}
 
1417
 
 
1418
void tst_QLineEdit::undo_keypressevents()
 
1419
{
 
1420
    QFETCH(QTestEventList, keys);
 
1421
    QFETCH(QStringList, expectedString);
 
1422
 
 
1423
    keys.simulate(testWidget);
 
1424
 
 
1425
    for (int i=0; i<expectedString.size(); ++i) {
 
1426
        QCOMPARE(testWidget->text() , expectedString[i]);
 
1427
        testWidget->undo();
 
1428
    }
 
1429
    QVERIFY(testWidget->text().isEmpty());
 
1430
}
 
1431
 
 
1432
#ifndef QT_NO_CLIPBOARD
 
1433
void tst_QLineEdit::QTBUG5786_undoPaste()
 
1434
{
 
1435
    if (!PlatformClipboard::isAvailable())
 
1436
           QSKIP("this machine doesn't support the clipboard");
 
1437
    QString initial("initial");
 
1438
    QString string("test");
 
1439
    QString additional("add");
 
1440
    QApplication::clipboard()->setText(string);
 
1441
    QLineEdit edit(initial);
 
1442
    QCOMPARE(edit.text(), initial);
 
1443
    edit.paste();
 
1444
    QCOMPARE(edit.text(), initial + string);
 
1445
    edit.paste();
 
1446
    QCOMPARE(edit.text(), initial + string + string);
 
1447
    edit.insert(additional);
 
1448
    QCOMPARE(edit.text(), initial + string + string + additional);
 
1449
    edit.undo();
 
1450
    QCOMPARE(edit.text(), initial + string + string);
 
1451
    edit.undo();
 
1452
    QCOMPARE(edit.text(), initial + string);
 
1453
    edit.undo();
 
1454
    QCOMPARE(edit.text(), initial);
 
1455
    edit.selectAll();
 
1456
    QApplication::clipboard()->setText(QString());
 
1457
    edit.paste();
 
1458
    QVERIFY(edit.text().isEmpty());
 
1459
 
 
1460
}
 
1461
#endif
 
1462
 
 
1463
 
 
1464
void tst_QLineEdit::clear()
 
1465
{
 
1466
    // checking that clear of empty/nullstring doesn't add to undo history
 
1467
    int max = 5000;
 
1468
    while (max > 0 && testWidget->isUndoAvailable()) {
 
1469
        max--;
 
1470
        testWidget->undo();
 
1471
    }
 
1472
 
 
1473
    testWidget->clear();
 
1474
//    QVERIFY(!testWidget->isUndoAvailable());
 
1475
 
 
1476
    // checks that clear actually clears
 
1477
    testWidget->insert("I am Legend");
 
1478
    testWidget->clear();
 
1479
    QVERIFY(testWidget->text().isEmpty());
 
1480
 
 
1481
    // checks that clears can be undone
 
1482
    testWidget->undo();
 
1483
    QCOMPARE(testWidget->text(), QString("I am Legend"));
 
1484
}
 
1485
 
 
1486
void tst_QLineEdit::editingFinished()
 
1487
{
 
1488
    if (testWidget->hasAcceptableInput())
 
1489
        validInput = true;
 
1490
    else
 
1491
        validInput = false;
 
1492
}
 
1493
 
 
1494
void tst_QLineEdit::text_data()
 
1495
{
 
1496
    QTest::addColumn<QString>("insertString");
 
1497
 
 
1498
    QTest::newRow("Plain text0") << QString("Hello World");
 
1499
    QTest::newRow("Plain text1") << QString("");
 
1500
    QTest::newRow("Plain text2") << QString("A");
 
1501
    QTest::newRow("Plain text3") << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry");
 
1502
    QTest::newRow("Plain text4") << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"");
 
1503
    QTest::newRow("Newlines") << QString("A\nB\nC\n");
 
1504
    QTest::newRow("Text with nbsp") << QString("Hello") + QChar(0xa0) + "World";
 
1505
}
 
1506
 
 
1507
void tst_QLineEdit::text()
 
1508
{
 
1509
    QFETCH(QString, insertString);
 
1510
    testWidget->setText(insertString);
 
1511
    QCOMPARE(testWidget->text(), insertString);
 
1512
}
 
1513
 
 
1514
void tst_QLineEdit::textMask_data()
 
1515
{
 
1516
    QTest::addColumn<QString>("insertString");
 
1517
 
 
1518
    QTest::newRow( "Plain text1" ) << QString( "" );
 
1519
}
 
1520
 
 
1521
void tst_QLineEdit::textMask()
 
1522
{
 
1523
    QFETCH( QString, insertString );
 
1524
    testWidget->setInputMask( "#" );
 
1525
    testWidget->setText( insertString );
 
1526
    QCOMPARE( testWidget->text(), insertString );
 
1527
}
 
1528
 
 
1529
void tst_QLineEdit::setText()
 
1530
{
 
1531
    QSignalSpy editedSpy(testWidget, SIGNAL(textEdited(QString)));
 
1532
    QSignalSpy changedSpy(testWidget, SIGNAL(textChanged(QString)));
 
1533
    testWidget->setText("hello");
 
1534
    QCOMPARE(editedSpy.count(), 0);
 
1535
    QCOMPARE(changedSpy.value(0).value(0).toString(), QString("hello"));
 
1536
}
 
1537
 
 
1538
void tst_QLineEdit::displayText_data()
 
1539
{
 
1540
    QTest::addColumn<QString>("insertString");
 
1541
    QTest::addColumn<QString>("expectedString");
 
1542
    QTest::addColumn<QLineEdit::EchoMode>("mode");
 
1543
    QTest::addColumn<bool>("use_setText");
 
1544
 
 
1545
    QString s;
 
1546
    QLineEdit::EchoMode m;
 
1547
 
 
1548
    for (int i=0; i<2; i++) {
 
1549
        QString key_mode_str;
 
1550
        bool use_setText;
 
1551
        if (i==0) {
 
1552
            key_mode_str = "setText_";
 
1553
            use_setText = true;
 
1554
        } else {
 
1555
            key_mode_str = "useKeys_";
 
1556
            use_setText = false;
 
1557
        }
 
1558
        s = key_mode_str + "Normal";
 
1559
        m = QLineEdit::Normal;
 
1560
        QTest::newRow(QString(s + " text0").toLatin1()) << QString("Hello World") <<
 
1561
                      QString("Hello World") <<
 
1562
                      m << bool(use_setText);
 
1563
        QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
 
1564
                      QString("") <<
 
1565
                      m << bool(use_setText);
 
1566
        QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") <<
 
1567
                      QString("A") <<
 
1568
                      m << bool(use_setText);
 
1569
        QTest::newRow(QString(s + " text3").toLatin1()) << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
 
1570
                      QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
 
1571
                      m << bool(use_setText);
 
1572
        QTest::newRow(QString(s + " text4").toLatin1()) << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
 
1573
                      QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
 
1574
                      m << bool(use_setText);
 
1575
        QTest::newRow(QString(s + " text with nbsp").toLatin1()) << QString("Hello") + QChar(0xa0) + "World" <<
 
1576
                      QString("Hello") + QChar(0xa0) + "World" <<
 
1577
                      m << bool(use_setText);
 
1578
        s = key_mode_str + "NoEcho";
 
1579
        m = QLineEdit::NoEcho;
 
1580
        QTest::newRow(QString(s + " text0").toLatin1()) << QString("Hello World") <<
 
1581
                      QString("") <<
 
1582
                      m << bool(use_setText);
 
1583
        QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
 
1584
                      QString("") <<
 
1585
                      m << bool(use_setText);
 
1586
        QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") <<
 
1587
                      QString("") <<
 
1588
                      m << bool(use_setText);
 
1589
        QTest::newRow(QString(s + " text3").toLatin1()) << QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry") <<
 
1590
                      QString("") <<
 
1591
                      m << bool(use_setText);
 
1592
        QTest::newRow(QString(s + " text4").toLatin1()) << QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"") <<
 
1593
                      QString("") <<
 
1594
                      m << bool(use_setText);
 
1595
        QTest::newRow(QString(s + " text with nbsp").toLatin1()) << QString("Hello") + QChar(0xa0) + "World" <<
 
1596
                      QString("") <<
 
1597
                      m << bool(use_setText);
 
1598
        s = key_mode_str + "Password";
 
1599
        m = QLineEdit::Password;
 
1600
        QChar passChar = qApp->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, 0, testWidget);
 
1601
        QString input;
 
1602
        QString pass;
 
1603
        input = "Hello World";
 
1604
        pass.resize(input.length());
 
1605
        pass.fill(passChar);
 
1606
        QTest::newRow(QString(s + " text0").toLatin1()) << input << pass << m << bool(use_setText);
 
1607
        QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
 
1608
                      QString("") <<
 
1609
                      m << bool(use_setText);
 
1610
        QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") << QString(passChar) << m << bool(use_setText);
 
1611
        input = QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry");
 
1612
        pass.resize(input.length());
 
1613
        pass.fill(passChar);
 
1614
        QTest::newRow(QString(s + " text3").toLatin1()) << input << pass << m << bool(use_setText);
 
1615
        input = QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"");
 
1616
        pass.fill(passChar, input.length());
 
1617
        QTest::newRow(QString(s + " text4").toLatin1()) << input << pass << m << bool(use_setText);
 
1618
        input = QString("Hello") + QChar(0xa0) + "World";
 
1619
        pass.resize(input.length());
 
1620
        pass.fill(passChar);
 
1621
        QTest::newRow(QString(s + " text with nbsp").toLatin1()) << input << pass << m << bool(use_setText);
 
1622
    }
 
1623
}
 
1624
 
 
1625
void tst_QLineEdit::displayText()
 
1626
{
 
1627
    QFETCH(QString, insertString);
 
1628
    QFETCH(QString, expectedString);
 
1629
    QFETCH(QLineEdit::EchoMode, mode);
 
1630
    //QFETCH(bool, use_setText);  Currently unused.
 
1631
 
 
1632
    testWidget->setEchoMode(mode);
 
1633
    testWidget->setText(insertString);
 
1634
    QCOMPARE(testWidget->displayText(), expectedString);
 
1635
    QVERIFY(testWidget->echoMode() == mode);
 
1636
}
 
1637
 
 
1638
void tst_QLineEdit::passwordEchoOnEdit()
 
1639
{
 
1640
    QStyleOptionFrameV2 opt;
 
1641
    QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
 
1642
 
 
1643
    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
 
1644
    testWidget->setFocus();
 
1645
    testWidget->raise();
 
1646
    QTRY_VERIFY(testWidget->hasFocus());
 
1647
 
 
1648
    QTest::keyPress(testWidget, '0');
 
1649
    QTest::keyPress(testWidget, '1');
 
1650
    QTest::keyPress(testWidget, '2');
 
1651
    QTest::keyPress(testWidget, '3');
 
1652
    QTest::keyPress(testWidget, '4');
 
1653
    QCOMPARE(testWidget->displayText(), QString("01234"));
 
1654
    testWidget->clearFocus();
 
1655
    QVERIFY(!testWidget->hasFocus());
 
1656
    QCOMPARE(testWidget->displayText(), QString(5, fillChar));
 
1657
    testWidget->setFocus();
 
1658
    QTRY_VERIFY(testWidget->hasFocus());
 
1659
 
 
1660
    QCOMPARE(testWidget->displayText(), QString(5, fillChar));
 
1661
    QTest::keyPress(testWidget, '0');
 
1662
    QCOMPARE(testWidget->displayText(), QString("0"));
 
1663
 
 
1664
    // restore clean state
 
1665
    testWidget->setEchoMode(QLineEdit::Normal);
 
1666
}
 
1667
 
 
1668
void tst_QLineEdit::passwordEchoDelay()
 
1669
{
 
1670
    int delay = qGuiApp->styleHints()->passwordMaskDelay();
 
1671
#if defined QT_BUILD_INTERNAL
 
1672
    QLineEditPrivate *priv = QLineEditPrivate::get(testWidget);
 
1673
    QWidgetLineControl *control = priv->control;
 
1674
    control->m_passwordMaskDelayOverride = 200;
 
1675
    delay = 200;
 
1676
#endif
 
1677
    if (delay <= 0)
 
1678
        QSKIP("Platform not defining echo delay and overriding only possible in internal build");
 
1679
 
 
1680
    QStyleOptionFrameV2 opt;
 
1681
    QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
 
1682
 
 
1683
    testWidget->setEchoMode(QLineEdit::Password);
 
1684
    testWidget->setFocus();
 
1685
    testWidget->raise();
 
1686
    QTRY_VERIFY(testWidget->hasFocus());
 
1687
 
 
1688
    QTest::keyPress(testWidget, '0');
 
1689
    QTest::keyPress(testWidget, '1');
 
1690
    QTest::keyPress(testWidget, '2');
 
1691
    QCOMPARE(testWidget->displayText(), QString(2, fillChar) + QLatin1Char('2'));
 
1692
    QTest::keyPress(testWidget, '3');
 
1693
    QTest::keyPress(testWidget, '4');
 
1694
    QCOMPARE(testWidget->displayText(), QString(4, fillChar) + QLatin1Char('4'));
 
1695
    QTest::keyPress(testWidget, Qt::Key_Backspace);
 
1696
    QCOMPARE(testWidget->displayText(), QString(4, fillChar));
 
1697
    QTest::keyPress(testWidget, '4');
 
1698
    QCOMPARE(testWidget->displayText(), QString(4, fillChar) + QLatin1Char('4'));
 
1699
    QTest::qWait(delay);
 
1700
    QTRY_COMPARE(testWidget->displayText(), QString(5, fillChar));
 
1701
    QTest::keyPress(testWidget, '5');
 
1702
    QCOMPARE(testWidget->displayText(), QString(5, fillChar) + QLatin1Char('5'));
 
1703
    testWidget->clearFocus();
 
1704
    QVERIFY(!testWidget->hasFocus());
 
1705
    QCOMPARE(testWidget->displayText(), QString(6, fillChar));
 
1706
    testWidget->setFocus();
 
1707
    QTRY_VERIFY(testWidget->hasFocus());
 
1708
    QCOMPARE(testWidget->displayText(), QString(6, fillChar));
 
1709
    QTest::keyPress(testWidget, '6');
 
1710
    QCOMPARE(testWidget->displayText(), QString(6, fillChar) + QLatin1Char('6'));
 
1711
 
 
1712
    QInputMethodEvent ev;
 
1713
    ev.setCommitString(QLatin1String("7"));
 
1714
    QApplication::sendEvent(testWidget, &ev);
 
1715
    QCOMPARE(testWidget->displayText(), QString(7, fillChar) + QLatin1Char('7'));
 
1716
 
 
1717
    testWidget->setCursorPosition(3);
 
1718
    QCOMPARE(testWidget->displayText(), QString(7, fillChar) + QLatin1Char('7'));
 
1719
    QTest::keyPress(testWidget, 'a');
 
1720
    QCOMPARE(testWidget->displayText(), QString(3, fillChar) + QLatin1Char('a') + QString(5, fillChar));
 
1721
    QTest::keyPress(testWidget, Qt::Key_Backspace);
 
1722
    QCOMPARE(testWidget->displayText(), QString(8, fillChar));
 
1723
 
 
1724
    // restore clean state
 
1725
    testWidget->setEchoMode(QLineEdit::Normal);
 
1726
}
 
1727
 
 
1728
void tst_QLineEdit::maxLength_mask_data()
 
1729
{
 
1730
    QTest::addColumn<QString>("mask");
 
1731
    QTest::addColumn<int>("expectedLength");
 
1732
 
 
1733
    QTest::newRow("mask_case") << QString(">000<>00<000") << 8;
 
1734
    QTest::newRow("mask_nocase") << QString("00000000") << 8;
 
1735
    QTest::newRow("mask_null") << QString() << 32767;
 
1736
    QTest::newRow("mask_escape") << QString("\\A\\aAA") << 4;
 
1737
}
 
1738
 
 
1739
void tst_QLineEdit::maxLength_mask()
 
1740
{
 
1741
    QFETCH(QString, mask);
 
1742
    QFETCH(int, expectedLength);
 
1743
 
 
1744
    testWidget->setInputMask(mask);
 
1745
 
 
1746
    QCOMPARE(testWidget->maxLength(), expectedLength);
 
1747
}
 
1748
 
 
1749
void tst_QLineEdit::maxLength_data()
 
1750
{
 
1751
    QTest::addColumn<QString>("insertString");
 
1752
    QTest::addColumn<QString>("expectedString");
 
1753
    QTest::addColumn<int>("length");
 
1754
    QTest::addColumn<bool>("insertBeforeSettingMaxLength");
 
1755
    QTest::addColumn<bool>("use_setText");
 
1756
 
 
1757
    QTest::newRow("keyclick before0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(true) << bool(false);
 
1758
    QTest::newRow("keyclick before1") << QString("this is a test.") << QString("this is a ") << 10 << bool(true) << bool(false);
 
1759
    QTest::newRow("keyclick after0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(false) << bool(false);
 
1760
    QTest::newRow("keyclick after1") << QString("this is a test.") << QString("this is a ") << 10 << bool(false) << bool(false);
 
1761
    QTest::newRow("settext before0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(true) << bool(true);
 
1762
    QTest::newRow("settext before1") << QString("this is a test.") << QString("this is a ") << 10 << bool(true) << bool(true);
 
1763
    QTest::newRow("settext after0") << QString("this is a test.") << QString("this is a test.") << 20 << bool(false) << bool(true);
 
1764
    QTest::newRow("settext after1") << QString("this is a test.") << QString("this is a ") << 10 << bool(false) << bool(true);
 
1765
}
 
1766
 
 
1767
void tst_QLineEdit::maxLength()
 
1768
{
 
1769
    QFETCH(QString, insertString);
 
1770
    QFETCH(QString, expectedString);
 
1771
    QFETCH(int, length);
 
1772
    QFETCH(bool, insertBeforeSettingMaxLength);
 
1773
    QFETCH(bool, use_setText);
 
1774
 
 
1775
    // in some cases we set the maxLength _before_ entering the text.
 
1776
    if (!insertBeforeSettingMaxLength)
 
1777
        testWidget->setMaxLength(length);
 
1778
 
 
1779
    // I expect MaxLength to work BOTH with entering live characters AND with setting the text.
 
1780
    if (use_setText) {
 
1781
        // Enter insertString using setText.
 
1782
        testWidget->setText(insertString);
 
1783
    } else {
 
1784
        // Enter insertString as a sequence of keyClicks
 
1785
        QTest::keyClicks(testWidget, insertString);
 
1786
    }
 
1787
 
 
1788
    // in all other cases we set the maxLength _after_ entering the text.
 
1789
    if (insertBeforeSettingMaxLength) {
 
1790
        changed_count = 0;
 
1791
        testWidget->setMaxLength(length);
 
1792
 
 
1793
        // Make sure that the textChanged is not emitted unless the text is actually changed
 
1794
        if (insertString == expectedString) {
 
1795
            QVERIFY(changed_count == 0);
 
1796
        } else {
 
1797
            QVERIFY(changed_count == 1);
 
1798
        }
 
1799
    }
 
1800
 
 
1801
    // and check if we get the expected string back
 
1802
    QCOMPARE(testWidget->text(), expectedString);
 
1803
}
 
1804
 
 
1805
void tst_QLineEdit::isReadOnly()
 
1806
{
 
1807
    QVERIFY(!testWidget->isReadOnly());
 
1808
 
 
1809
    // start with a basic text
 
1810
    QTest::keyClicks(testWidget, "the quick brown fox");
 
1811
    QCOMPARE(testWidget->text(), QString("the quick brown fox"));
 
1812
 
 
1813
    // do a quick check to verify that we can indeed edit the text
 
1814
    testWidget->home(false);
 
1815
    testWidget->cursorForward(false, 10);
 
1816
    QTest::keyClicks(testWidget, "dark ");
 
1817
    QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
 
1818
 
 
1819
    testWidget->setReadOnly(true);
 
1820
    QVERIFY(testWidget->isReadOnly());
 
1821
 
 
1822
    // verify that we cannot edit the text anymore
 
1823
    testWidget->home(false);
 
1824
    testWidget->cursorForward(false, 10);
 
1825
    QTest::keyClick(testWidget, Qt::Key_Delete);
 
1826
    QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
 
1827
    testWidget->cursorForward(false, 10);
 
1828
    QTest::keyClicks(testWidget, "this should not have any effect!! ");
 
1829
    QCOMPARE(testWidget->text(), QString("the quick dark brown fox"));
 
1830
}
 
1831
 
 
1832
class BlinkTestLineEdit : public QLineEdit
 
1833
{
 
1834
public:
 
1835
    void paintEvent(QPaintEvent *e)
 
1836
    {
 
1837
        ++updates;
 
1838
        QLineEdit::paintEvent(e);
 
1839
    }
 
1840
 
 
1841
    int updates;
 
1842
};
 
1843
 
 
1844
void tst_QLineEdit::noCursorBlinkWhenReadOnly()
 
1845
{
 
1846
    int cursorFlashTime = QApplication::cursorFlashTime();
 
1847
    if (cursorFlashTime == 0)
 
1848
        return;
 
1849
    BlinkTestLineEdit le;
 
1850
    le.show();
 
1851
    le.setFocus();
 
1852
    QTest::qWaitForWindowActive(&le);
 
1853
    le.updates = 0;
 
1854
    QTest::qWait(cursorFlashTime);
 
1855
    QVERIFY(le.updates > 0);
 
1856
    le.setReadOnly(true);
 
1857
    QTest::qWait(10);
 
1858
    le.updates = 0;
 
1859
    QTest::qWait(cursorFlashTime);
 
1860
    QCOMPARE(le.updates, 0);
 
1861
    le.setReadOnly(false);
 
1862
    QTest::qWait(10);
 
1863
    le.updates = 0;
 
1864
    QTest::qWait(cursorFlashTime);
 
1865
    QVERIFY(le.updates > 0);
 
1866
}
 
1867
 
 
1868
static void figureOutProperKey(Qt::Key &key, Qt::KeyboardModifiers &pressState)
 
1869
{
 
1870
#ifdef Q_OS_MAC
 
1871
    static bool tst_lineedit_randomized = false;
 
1872
    // Mac has 3 different ways of accomplishing this (same for moving to the back)
 
1873
    // So I guess we should just randomly do this for now. Which may get people mad, but if
 
1874
    // we fail at one point, it's just a matter of setting roll to the correct value
 
1875
    // instead of random.
 
1876
 
 
1877
    if (!tst_lineedit_randomized) {
 
1878
        tst_lineedit_randomized = true;
 
1879
        ::srandom(ulong(time(0)));
 
1880
    }
 
1881
    long roll = ::random() % 3;
 
1882
    switch (roll) {
 
1883
    case 0:
 
1884
        key = key == Qt::Key_Home ? Qt::Key_Up : Qt::Key_Down;
 
1885
        break;
 
1886
    case 1:
 
1887
    case 2:
 
1888
        key = key == Qt::Key_Home ? Qt::Key_Left : Qt::Key_Right;
 
1889
        pressState |= (roll == 1) ? Qt::ControlModifier : Qt::MetaModifier;
 
1890
        break;
 
1891
    }
 
1892
#else
 
1893
    // Naively kill the warning.
 
1894
    key = key;
 
1895
    pressState = pressState;
 
1896
#endif
 
1897
}
 
1898
 
 
1899
// Platform specific move. Home and End do nothing on the Mac,
 
1900
// so do something a bit smarter than tons of #ifdefs
 
1901
void tst_QLineEdit::psKeyClick(QWidget *target, Qt::Key key, Qt::KeyboardModifiers pressState)
 
1902
{
 
1903
    figureOutProperKey(key, pressState);
 
1904
    QTest::keyClick(target, key, pressState);
 
1905
}
 
1906
 
 
1907
void tst_QLineEdit::psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardModifiers pressState)
 
1908
{
 
1909
    figureOutProperKey(key, pressState);
 
1910
    keys.addKeyClick(key, pressState);
 
1911
}
 
1912
 
 
1913
void tst_QLineEdit::cursorPosition()
 
1914
{
 
1915
    QVERIFY(testWidget->cursorPosition() == 0);
 
1916
 
 
1917
    // start with a basic text
 
1918
    QTest::keyClicks(testWidget, "The");
 
1919
    QCOMPARE(testWidget->cursorPosition(), 3);
 
1920
    QTest::keyClicks(testWidget, " quick");
 
1921
    QCOMPARE(testWidget->cursorPosition(), 9);
 
1922
    QTest::keyClicks(testWidget, " brown fox jumps over the lazy dog");
 
1923
    QCOMPARE(testWidget->cursorPosition(), 43);
 
1924
 
 
1925
    // The text we have now is:
 
1926
    //           1         2         3         4         5
 
1927
    // 012345678901234567890123456789012345678901234567890
 
1928
    // The quick brown fox jumps over the lazy dog
 
1929
 
 
1930
    // next we will check some of the cursor movement functions
 
1931
    testWidget->end(false);
 
1932
    QCOMPARE(testWidget->cursorPosition() , 43);
 
1933
    testWidget->cursorForward(false, -1);
 
1934
    QCOMPARE(testWidget->cursorPosition() , 42);
 
1935
    testWidget->cursorBackward(false, 1);
 
1936
    QCOMPARE(testWidget->cursorPosition() , 41);
 
1937
    testWidget->home(false);
 
1938
    QCOMPARE(testWidget->cursorPosition() , 0);
 
1939
    testWidget->cursorForward(false, 1);
 
1940
    QCOMPARE(testWidget->cursorPosition() , 1);
 
1941
    testWidget->cursorForward(false, 9);
 
1942
    QCOMPARE(testWidget->cursorPosition() , 10);
 
1943
    testWidget->cursorWordForward(false); // 'fox'
 
1944
    QCOMPARE(testWidget->cursorPosition(), 16);
 
1945
    testWidget->cursorWordForward(false); // 'jumps'
 
1946
    QCOMPARE(testWidget->cursorPosition(), 20);
 
1947
    testWidget->cursorWordBackward(false); // 'fox'
 
1948
    QCOMPARE(testWidget->cursorPosition(), 16);
 
1949
    testWidget->cursorWordBackward(false); // 'brown'
 
1950
    testWidget->cursorWordBackward(false); // 'quick'
 
1951
    testWidget->cursorWordBackward(false); // 'The'
 
1952
    QCOMPARE(testWidget->cursorPosition(), 0);
 
1953
    testWidget->cursorWordBackward(false); // 'The'
 
1954
    QCOMPARE(testWidget->cursorPosition(), 0);
 
1955
 
 
1956
    // Cursor position should be 0 here!
 
1957
    int i;
 
1958
    for (i=0; i<5; i++)
 
1959
        QTest::keyClick(testWidget, Qt::Key_Right);
 
1960
    QCOMPARE(testWidget->cursorPosition(), 5);
 
1961
    psKeyClick(testWidget, Qt::Key_End);
 
1962
    QCOMPARE(testWidget->cursorPosition(), 43);
 
1963
    QTest::keyClick(testWidget, Qt::Key_Left);
 
1964
    QCOMPARE(testWidget->cursorPosition(), 42);
 
1965
    QTest::keyClick(testWidget, Qt::Key_Left);
 
1966
    QCOMPARE(testWidget->cursorPosition(), 41);
 
1967
    psKeyClick(testWidget, Qt::Key_Home);
 
1968
    QCOMPARE(testWidget->cursorPosition(), 0);
 
1969
 
 
1970
    // cursorposition when maxlength is set
 
1971
    int maxLength = 9;
 
1972
    testWidget->clear();
 
1973
    testWidget->setMaxLength(maxLength);
 
1974
    QCOMPARE(testWidget->cursorPosition() , 0);
 
1975
    QTest::keyClicks(testWidget, "123ABC123");
 
1976
    QCOMPARE(testWidget->cursorPosition() , maxLength);
 
1977
    psKeyClick(testWidget, Qt::Key_Home);
 
1978
    QCOMPARE(testWidget->cursorPosition() , 0);
 
1979
    psKeyClick(testWidget, Qt::Key_End);
 
1980
    QCOMPARE(testWidget->cursorPosition() , maxLength);
 
1981
}
 
1982
 
 
1983
/* // tested in cursorPosition
 
1984
void tst_QLineEdit::cursorLeft()
 
1985
void tst_QLineEdit::cursorRight()
 
1986
void tst_QLineEdit::cursorForward()
 
1987
void tst_QLineEdit::cursorBackward()
 
1988
void tst_QLineEdit::cursorWordForward()
 
1989
void tst_QLineEdit::cursorWordBackward()
 
1990
void tst_QLineEdit::home()
 
1991
void tst_QLineEdit::end()
 
1992
*/
 
1993
 
 
1994
void tst_QLineEdit::cursorPositionChanged_data()
 
1995
{
 
1996
    QTest::addColumn<QTestEventList>("input");
 
1997
    QTest::addColumn<int>("lastPos");
 
1998
    QTest::addColumn<int>("newPos");
 
1999
 
 
2000
    QTestEventList keys;
 
2001
    keys.addKeyClick(Qt::Key_A);
 
2002
    QTest::newRow("a") << keys << 0 << 1;
 
2003
    keys.clear();
 
2004
 
 
2005
    keys.addKeyClick(Qt::Key_A);
 
2006
    keys.addKeyClick(Qt::Key_B);
 
2007
    keys.addKeyClick(Qt::Key_C);
 
2008
    psKeyClick(keys, Qt::Key_Home);
 
2009
    QTest::newRow("abc<home>") << keys << 3 << 0;
 
2010
    keys.clear();
 
2011
 
 
2012
    keys.addKeyClick(Qt::Key_A);
 
2013
    keys.addKeyClick(Qt::Key_B);
 
2014
    keys.addKeyClick(Qt::Key_C);
 
2015
    keys.addKeyClick(Qt::Key_Left);
 
2016
    QTest::newRow("abc<left>") << keys << 3 << 2;
 
2017
    keys.clear();
 
2018
 
 
2019
    keys.addKeyClick(Qt::Key_A);
 
2020
    keys.addKeyClick(Qt::Key_B);
 
2021
    keys.addKeyClick(Qt::Key_C);
 
2022
    keys.addKeyClick(Qt::Key_Right);
 
2023
    QTest::newRow("abc<right>") << keys << 2 << 3;
 
2024
    keys.clear();
 
2025
 
 
2026
    keys.addKeyClick(Qt::Key_A);
 
2027
    keys.addKeyClick(Qt::Key_B);
 
2028
    keys.addKeyClick(Qt::Key_C);
 
2029
    psKeyClick(keys, Qt::Key_Home);
 
2030
    keys.addKeyClick(Qt::Key_Right);
 
2031
    QTest::newRow("abc<home><right>") << keys << 0 << 1;
 
2032
    keys.clear();
 
2033
 
 
2034
    keys.addKeyClick(Qt::Key_A);
 
2035
    keys.addKeyClick(Qt::Key_B);
 
2036
    keys.addKeyClick(Qt::Key_C);
 
2037
    keys.addKeyClick(Qt::Key_Backspace);
 
2038
    QTest::newRow("abc<backspace>") << keys << 3 << 2;
 
2039
    keys.clear();
 
2040
 
 
2041
    keys.addKeyClick(Qt::Key_A);
 
2042
    keys.addKeyClick(Qt::Key_B);
 
2043
    keys.addKeyClick(Qt::Key_C);
 
2044
    keys.addKeyClick(Qt::Key_Delete);
 
2045
    QTest::newRow("abc<delete>") << keys << 2 << 3;
 
2046
    keys.clear();
 
2047
 
 
2048
    keys.addKeyClick(Qt::Key_A);
 
2049
    keys.addKeyClick(Qt::Key_B);
 
2050
    keys.addKeyClick(Qt::Key_C);
 
2051
    keys.addKeyClick(Qt::Key_Left);
 
2052
    keys.addKeyClick(Qt::Key_Delete);
 
2053
    QTest::newRow("abc<left><delete>") << keys << 3 << 2;
 
2054
    keys.clear();
 
2055
 
 
2056
    keys.addKeyClick(Qt::Key_A);
 
2057
    keys.addKeyClick(Qt::Key_B);
 
2058
    keys.addKeyClick(Qt::Key_C);
 
2059
    psKeyClick(keys, Qt::Key_Home);
 
2060
    psKeyClick(keys, Qt::Key_End);
 
2061
    QTest::newRow("abc<home><end>") << keys << 0 << 3;
 
2062
    keys.clear();
 
2063
 
 
2064
    keys.addKeyClick(Qt::Key_A);
 
2065
    keys.addKeyClick(Qt::Key_B);
 
2066
    keys.addKeyClick(Qt::Key_C);
 
2067
    keys.addKeyClick(Qt::Key_Space);
 
2068
    keys.addKeyClick(Qt::Key_D);
 
2069
    keys.addKeyClick(Qt::Key_E);
 
2070
    keys.addKeyClick(Qt::Key_F);
 
2071
    keys.addKeyClick(Qt::Key_Home);
 
2072
    keys.addKeyClick(Qt::Key_Right, Qt::ControlModifier);
 
2073
    QTest::newRow("abc efg<home><ctrl-right>") << keys
 
2074
#ifndef Q_OS_MAC
 
2075
        << 0 << 4;
 
2076
#else
 
2077
        << 6 << 7;
 
2078
#endif
 
2079
    keys.clear();
 
2080
 
 
2081
#ifdef Q_OS_MAC
 
2082
    keys.addKeyClick(Qt::Key_A);
 
2083
    keys.addKeyClick(Qt::Key_B);
 
2084
    keys.addKeyClick(Qt::Key_C);
 
2085
    keys.addKeyClick(Qt::Key_Space);
 
2086
    keys.addKeyClick(Qt::Key_D);
 
2087
    keys.addKeyClick(Qt::Key_E);
 
2088
    keys.addKeyClick(Qt::Key_F);
 
2089
    keys.addKeyClick(Qt::Key_Up);
 
2090
    keys.addKeyClick(Qt::Key_Right, Qt::AltModifier);
 
2091
    QTest::newRow("mac equivalent abc efg<up><option-right>") << keys << 0 << 4;
 
2092
    keys.clear();
 
2093
#endif
 
2094
 
 
2095
    keys.addKeyClick(Qt::Key_A);
 
2096
    keys.addKeyClick(Qt::Key_B);
 
2097
    keys.addKeyClick(Qt::Key_C);
 
2098
    keys.addKeyClick(Qt::Key_Space);
 
2099
    keys.addKeyClick(Qt::Key_D);
 
2100
    keys.addKeyClick(Qt::Key_E);
 
2101
    keys.addKeyClick(Qt::Key_F);
 
2102
    keys.addKeyClick(Qt::Key_Left, Qt::ControlModifier);
 
2103
    QTest::newRow("abc efg<ctrl-left>") << keys << 7
 
2104
#ifndef Q_OS_MAC
 
2105
        << 4;
 
2106
#else
 
2107
        << 0;
 
2108
#endif
 
2109
    keys.clear();
 
2110
#ifdef Q_OS_MAC
 
2111
    keys.addKeyClick(Qt::Key_A);
 
2112
    keys.addKeyClick(Qt::Key_B);
 
2113
    keys.addKeyClick(Qt::Key_C);
 
2114
    keys.addKeyClick(Qt::Key_Space);
 
2115
    keys.addKeyClick(Qt::Key_D);
 
2116
    keys.addKeyClick(Qt::Key_E);
 
2117
    keys.addKeyClick(Qt::Key_F);
 
2118
    keys.addKeyClick(Qt::Key_Left, Qt::AltModifier);
 
2119
    QTest::newRow("mac equivalent abc efg<option-left>") << keys << 7 << 4;
 
2120
    keys.clear();
 
2121
#endif
 
2122
}
 
2123
 
 
2124
 
 
2125
void tst_QLineEdit::cursorPositionChanged()
 
2126
{
 
2127
    QFETCH(QTestEventList, input);
 
2128
    QFETCH(int, lastPos);
 
2129
    QFETCH(int, newPos);
 
2130
 
 
2131
    lastCursorPos = 0;
 
2132
    newCursorPos = 0;
 
2133
    input.simulate(testWidget);
 
2134
    QCOMPARE(lastCursorPos, lastPos);
 
2135
    QCOMPARE(newCursorPos, newPos);
 
2136
}
 
2137
 
 
2138
void tst_QLineEdit::selectedText()
 
2139
{
 
2140
    QString testString = "Abc defg hijklmno, p 'qrst' uvw xyz";
 
2141
 
 
2142
    // start with a basic text
 
2143
    testWidget->setText(testString);
 
2144
    selection_count = 0;
 
2145
 
 
2146
    // The text we have now is:
 
2147
    //           1         2         3         4         5
 
2148
    // 012345678901234567890123456789012345678901234567890
 
2149
    // Abc defg hijklmno, p 'qrst' uvw xyz
 
2150
 
 
2151
    testWidget->home(false);
 
2152
    QVERIFY(!testWidget->hasSelectedText());
 
2153
    QCOMPARE(testWidget->selectedText(), QString());
 
2154
 
 
2155
    // play a bit with the cursorForward, cursorBackward(), etc
 
2156
    testWidget->cursorForward(true, 9);
 
2157
    QVERIFY(testWidget->hasSelectedText());
 
2158
    QCOMPARE(testWidget->selectedText(), QString("Abc defg "));
 
2159
    QVERIFY(selection_count == 1);
 
2160
 
 
2161
    // reset selection
 
2162
    testWidget->home(false);
 
2163
    QVERIFY(!testWidget->hasSelectedText());
 
2164
    QCOMPARE(testWidget->selectedText(), QString());
 
2165
    selection_count = 0;
 
2166
}
 
2167
 
 
2168
/* // tested in selectedText
 
2169
void tst_QLineEdit::backspace()
 
2170
void tst_QLineEdit::del()
 
2171
void tst_QLineEdit::selectionChanged()
 
2172
void tst_QLineEdit::selectAll()
 
2173
void tst_QLineEdit::deselect()
 
2174
*/
 
2175
 
 
2176
void tst_QLineEdit::onSelectionChanged()
 
2177
{
 
2178
    selection_count++;
 
2179
}
 
2180
 
 
2181
void tst_QLineEdit::deleteSelectedText()
 
2182
{
 
2183
    const QString text = QString::fromLatin1("bar");
 
2184
    QLineEdit edit( text );
 
2185
    QCOMPARE(edit.text(), text);
 
2186
 
 
2187
    edit.selectAll();
 
2188
 
 
2189
    QTest::keyClick(&edit, Qt::Key_Delete, 0);
 
2190
    QVERIFY(edit.text().isEmpty());
 
2191
 
 
2192
    edit.setText(text);
 
2193
    edit.selectAll();
 
2194
 
 
2195
    QMenu *menu = edit.createStandardContextMenu();
 
2196
    for (int i = 0; i < menu->actions().count(); ++i) {
 
2197
        QAction *current = menu->actions().at(i);
 
2198
        if (current->text() == QLineEdit::tr("Delete")) {
 
2199
            current->trigger(); //this will delete the whole text selected
 
2200
            QVERIFY(edit.text().isEmpty());
 
2201
        }
 
2202
    }
 
2203
 
 
2204
}
 
2205
 
 
2206
 
 
2207
void tst_QLineEdit::textChangedAndTextEdited()
 
2208
{
 
2209
    changed_count = 0;
 
2210
    edited_count = 0;
 
2211
 
 
2212
    QTest::keyClick(testWidget, Qt::Key_A);
 
2213
    QCOMPARE(changed_count, 1);
 
2214
    QVERIFY(edited_count == changed_count);
 
2215
    QTest::keyClick(testWidget, 'b');
 
2216
    QCOMPARE(changed_count, 2);
 
2217
    QVERIFY(edited_count == changed_count);
 
2218
    QTest::keyClick(testWidget, 'c');
 
2219
    QCOMPARE(changed_count, 3);
 
2220
    QVERIFY(edited_count == changed_count);
 
2221
    QTest::keyClick(testWidget, ' ');
 
2222
    QCOMPARE(changed_count, 4);
 
2223
    QVERIFY(edited_count == changed_count);
 
2224
    QTest::keyClick(testWidget, 'd');
 
2225
    QCOMPARE(changed_count, 5);
 
2226
    QVERIFY(edited_count == changed_count);
 
2227
 
 
2228
    changed_count = 0;
 
2229
    edited_count = 0;
 
2230
    changed_string = QString::null;
 
2231
 
 
2232
    testWidget->setText("foo");
 
2233
    QCOMPARE(changed_count, 1);
 
2234
    QCOMPARE(edited_count, 0);
 
2235
    QCOMPARE(changed_string, QString("foo"));
 
2236
 
 
2237
    changed_count = 0;
 
2238
    edited_count = 0;
 
2239
    changed_string = QString::null;
 
2240
 
 
2241
    testWidget->setText("");
 
2242
    QCOMPARE(changed_count, 1);
 
2243
    QCOMPARE(edited_count, 0);
 
2244
    QVERIFY(changed_string.isEmpty());
 
2245
    QVERIFY(!changed_string.isNull());
 
2246
}
 
2247
 
 
2248
void tst_QLineEdit::onTextChanged(const QString &text)
 
2249
{
 
2250
    changed_count++;
 
2251
    changed_string = text;
 
2252
}
 
2253
 
 
2254
void tst_QLineEdit::onTextEdited(const QString &/*text*/)
 
2255
{
 
2256
    edited_count++;
 
2257
}
 
2258
 
 
2259
 
 
2260
void tst_QLineEdit::onCursorPositionChanged(int oldPos, int newPos)
 
2261
{
 
2262
    lastCursorPos = oldPos;
 
2263
    newCursorPos = newPos;
 
2264
}
 
2265
 
 
2266
void tst_QLineEdit::returnPressed()
 
2267
{
 
2268
    return_count = 0;
 
2269
 
 
2270
    QTest::keyClick(testWidget, Qt::Key_Return);
 
2271
    QVERIFY(return_count == 1);
 
2272
    return_count = 0;
 
2273
 
 
2274
    QTest::keyClick(testWidget, 'A');
 
2275
    QVERIFY(return_count == 0);
 
2276
    QTest::keyClick(testWidget, 'b');
 
2277
    QVERIFY(return_count == 0);
 
2278
    QTest::keyClick(testWidget, 'c');
 
2279
    QVERIFY(return_count == 0);
 
2280
    QTest::keyClick(testWidget, ' ');
 
2281
    QVERIFY(return_count == 0);
 
2282
    QTest::keyClick(testWidget, 'd');
 
2283
    QVERIFY(return_count == 0);
 
2284
    psKeyClick(testWidget, Qt::Key_Home);
 
2285
    QVERIFY(return_count == 0);
 
2286
    psKeyClick(testWidget, Qt::Key_End);
 
2287
    QVERIFY(return_count == 0);
 
2288
    QTest::keyClick(testWidget, Qt::Key_Escape);
 
2289
    QVERIFY(return_count == 0);
 
2290
    QTest::keyClick(testWidget, Qt::Key_Return);
 
2291
    QVERIFY(return_count == 1);
 
2292
}
 
2293
 
 
2294
// int validator that fixes all !isNumber to '0'
 
2295
class QIntFixValidator : public QIntValidator {
 
2296
public:
 
2297
    QIntFixValidator(int min, int max, QObject *parent) : QIntValidator(min, max, parent) {}
 
2298
    void fixup (QString &input) const {
 
2299
        for (int i=0; i<input.length(); ++i)
 
2300
            if (!input.at(i).isNumber()) {
 
2301
                input[(int)i] = QChar('0');
 
2302
            }
 
2303
    }
 
2304
};
 
2305
 
 
2306
void tst_QLineEdit::returnPressed_maskvalidator_data() {
 
2307
    QTest::addColumn<QString>("inputMask");
 
2308
    QTest::addColumn<bool>("hasValidator");
 
2309
    QTest::addColumn<QTestEventList>("input");
 
2310
    QTest::addColumn<QString>("expectedText");
 
2311
    QTest::addColumn<bool>("returnPressed");
 
2312
 
 
2313
    {
 
2314
        QTestEventList keys;
 
2315
        keys.addKeyClick(Qt::Key_Home);
 
2316
        keys.addKeyClick(Qt::Key_1);
 
2317
        keys.addKeyClick(Qt::Key_2);
 
2318
        keys.addKeyClick(Qt::Key_3);
 
2319
        keys.addKeyClick(Qt::Key_Return);
 
2320
        QTest::newRow("no mask, no validator, input '123<cr>'")
 
2321
            << QString()
 
2322
            << false
 
2323
            << keys
 
2324
            << QString("123")
 
2325
            << true;
 
2326
    }
 
2327
    {
 
2328
        QTestEventList keys;
 
2329
        keys.addKeyClick(Qt::Key_Home);
 
2330
        keys.addKeyClick(Qt::Key_1);
 
2331
        keys.addKeyClick(Qt::Key_2);
 
2332
        keys.addKeyClick(Qt::Key_Return);
 
2333
        QTest::newRow("mask '999', no validator, input '12<cr>'")
 
2334
            << QString("999")
 
2335
            << false
 
2336
            << keys
 
2337
            << QString("12")
 
2338
            << false;
 
2339
    }
 
2340
    {
 
2341
        QTestEventList keys;
 
2342
        keys.addKeyClick(Qt::Key_Home);
 
2343
        keys.addKeyClick(Qt::Key_1);
 
2344
        keys.addKeyClick(Qt::Key_2);
 
2345
        keys.addKeyClick(Qt::Key_3);
 
2346
        keys.addKeyClick(Qt::Key_Return);
 
2347
        QTest::newRow("mask '999', no validator, input '123<cr>'")
 
2348
            << QString("999")
 
2349
            << false
 
2350
            << keys
 
2351
            << QString("123")
 
2352
            << true;
 
2353
    }
 
2354
    {
 
2355
        QTestEventList keys;
 
2356
        keys.addKeyClick(Qt::Key_Home);
 
2357
        keys.addKeyClick(Qt::Key_1);
 
2358
        keys.addKeyClick(Qt::Key_2);
 
2359
        keys.addKeyClick(Qt::Key_3);
 
2360
        keys.addKeyClick(Qt::Key_Return);
 
2361
        QTest::newRow("no mask, intfix validator(0,999), input '123<cr>'")
 
2362
            << QString()
 
2363
            << true
 
2364
            << keys
 
2365
            << QString("123")
 
2366
            << true;
 
2367
    }
 
2368
    {
 
2369
        QTestEventList keys;
 
2370
        keys.addKeyClick(Qt::Key_Home);
 
2371
        keys.addKeyClick(Qt::Key_7);
 
2372
        keys.addKeyClick(Qt::Key_7);
 
2373
        keys.addKeyClick(Qt::Key_7);
 
2374
        keys.addKeyClick(Qt::Key_7);
 
2375
        keys.addKeyClick(Qt::Key_Return);
 
2376
        QTest::newRow("no mask, intfix validator(0,999), input '7777<cr>'")
 
2377
            << QString()
 
2378
            << true
 
2379
            << keys
 
2380
            << QString("777")
 
2381
            << true;
 
2382
    }
 
2383
    {
 
2384
        QTestEventList keys;
 
2385
        keys.addKeyClick(Qt::Key_Home);
 
2386
        keys.addKeyClick(Qt::Key_1);
 
2387
        keys.addKeyClick(Qt::Key_2);
 
2388
        keys.addKeyClick(Qt::Key_Return);
 
2389
        QTest::newRow("mask '999', intfix validator(0,999), input '12<cr>'")
 
2390
            << QString("999")
 
2391
            << true
 
2392
            << keys
 
2393
            << QString("12")
 
2394
            << false;
 
2395
    }
 
2396
    {
 
2397
        QTestEventList keys;
 
2398
        keys.addKeyClick(Qt::Key_Home);
 
2399
        keys.addKeyClick(Qt::Key_Return);
 
2400
        QTest::newRow("mask '999', intfix validator(0,999), input '<cr>'")
 
2401
            << QString("999")
 
2402
            << true
 
2403
            << keys
 
2404
            << QString("000")
 
2405
            << true;
 
2406
    }
 
2407
}
 
2408
 
 
2409
void tst_QLineEdit::returnPressed_maskvalidator()
 
2410
{
 
2411
    QFETCH(QString, inputMask);
 
2412
    QFETCH(bool, hasValidator);
 
2413
    QFETCH(QTestEventList, input);
 
2414
    QFETCH(QString, expectedText);
 
2415
    QFETCH(bool, returnPressed);
 
2416
 
 
2417
    QEXPECT_FAIL("mask '999', intfix validator(0,999), input '12<cr>'", "QIntValidator has changed behaviour. Does not accept spaces. Task 43082.", Abort);
 
2418
 
 
2419
    testWidget->setInputMask(inputMask);
 
2420
    if (hasValidator)
 
2421
        testWidget->setValidator(new QIntFixValidator(0, 999, testWidget));
 
2422
 
 
2423
    return_count = 0;
 
2424
    input.simulate(testWidget);
 
2425
 
 
2426
    QCOMPARE(testWidget->text(), expectedText);
 
2427
    QCOMPARE(return_count , returnPressed ? 1 : 0);
 
2428
}
 
2429
 
 
2430
void tst_QLineEdit::onReturnPressed()
 
2431
{
 
2432
    return_count++;
 
2433
}
 
2434
 
 
2435
void tst_QLineEdit::setValidator()
 
2436
{
 
2437
    // Verify that we can set and re-set a validator.
 
2438
    QVERIFY(!testWidget->validator());
 
2439
 
 
2440
    QIntValidator iv1(0);
 
2441
    testWidget->setValidator(&iv1);
 
2442
    QCOMPARE(testWidget->validator(), static_cast<const QValidator*>(&iv1));
 
2443
 
 
2444
    testWidget->setValidator(0);
 
2445
    QVERIFY(testWidget->validator() == 0);
 
2446
 
 
2447
    QIntValidator iv2(0, 99, 0);
 
2448
    testWidget->setValidator(&iv2);
 
2449
    QCOMPARE(testWidget->validator(), static_cast<const QValidator *>(&iv2));
 
2450
 
 
2451
    testWidget->setValidator(0);
 
2452
    QVERIFY(testWidget->validator() == 0);
 
2453
}
 
2454
 
 
2455
void tst_QLineEdit::setValidator_QIntValidator_data()
 
2456
{
 
2457
    QTest::addColumn<int>("mini");
 
2458
    QTest::addColumn<int>("maxi");
 
2459
    QTest::addColumn<QString>("input");
 
2460
    QTest::addColumn<QString>("expectedText");
 
2461
    QTest::addColumn<bool>("useKeys");
 
2462
    QTest::addColumn<bool>("is_valid");
 
2463
 
 
2464
    for (int i=0; i<2; i++) {
 
2465
        bool useKeys = false;
 
2466
        QString inputMode = "insert ";
 
2467
        if (i!=0) {
 
2468
            inputMode = "useKeys ";
 
2469
            useKeys = true;
 
2470
        }
 
2471
 
 
2472
        // valid data
 
2473
        QTest::newRow(QString(inputMode + "range [0,9] valid '1'").toLatin1())
 
2474
            << 0
 
2475
            << 9
 
2476
            << QString("1")
 
2477
            << QString("1")
 
2478
            << bool(useKeys)
 
2479
            << bool(true);
 
2480
 
 
2481
        QTest::newRow(QString(inputMode + "range [3,7] valid '3'").toLatin1())
 
2482
            << 3
 
2483
            << 7
 
2484
            << QString("3")
 
2485
            << QString("3")
 
2486
            << bool(useKeys)
 
2487
            << bool(true);
 
2488
 
 
2489
        QTest::newRow(QString(inputMode + "range [3,7] valid '7'").toLatin1())
 
2490
            << 3
 
2491
            << 7
 
2492
            << QString("7")
 
2493
            << QString("7")
 
2494
            << bool(useKeys)
 
2495
            << bool(true);
 
2496
 
 
2497
        QTest::newRow(QString(inputMode + "range [0,100] valid '9'").toLatin1())
 
2498
            << 0
 
2499
            << 100
 
2500
            << QString("9")
 
2501
            << QString("9")
 
2502
            << bool(useKeys)
 
2503
            << bool(true);
 
2504
 
 
2505
        QTest::newRow(QString(inputMode + "range [0,100] valid '12'").toLatin1())
 
2506
            << 0
 
2507
            << 100
 
2508
            << QString("12")
 
2509
            << QString("12")
 
2510
            << bool(useKeys)
 
2511
            << bool(true);
 
2512
 
 
2513
        QTest::newRow(QString(inputMode + "range [-100,100] valid '-12'").toLatin1())
 
2514
            << -100
 
2515
            << 100
 
2516
            << QString("-12")
 
2517
            << QString("-12")
 
2518
            << bool(useKeys)
 
2519
            << bool(true);
 
2520
 
 
2521
        // invalid data
 
2522
        // characters not allowed in QIntValidator
 
2523
        QTest::newRow(QString(inputMode + "range [0,9] inv 'a-a'").toLatin1())
 
2524
            << 0
 
2525
            << 9
 
2526
            << QString("a")
 
2527
            << QString("")
 
2528
            << bool(useKeys)
 
2529
            << bool(false);
 
2530
 
 
2531
        QTest::newRow(QString(inputMode + "range [0,9] inv 'A'").toLatin1())
 
2532
            << 0
 
2533
            << 9
 
2534
            << QString("A")
 
2535
            << QString("")
 
2536
            << bool(useKeys)
 
2537
            << bool(false);
 
2538
        // minus sign only allowed with a range on the negative side
 
2539
        QTest::newRow(QString(inputMode + "range [0,100] inv '-'").toLatin1())
 
2540
            << 0
 
2541
            << 100
 
2542
            << QString("-")
 
2543
            << QString("")
 
2544
            << bool(useKeys)
 
2545
            << bool(false);
 
2546
        QTest::newRow(QString(inputMode + "range [0,100] int '153'").toLatin1())
 
2547
            << 0
 
2548
            << 100
 
2549
            << QString("153")
 
2550
            << QString(useKeys ? "15" : "")
 
2551
            << bool(useKeys)
 
2552
            << bool(useKeys ? true : false);
 
2553
        QTest::newRow(QString(inputMode + "range [-100,100] int '-153'").toLatin1())
 
2554
            << -100
 
2555
            << 100
 
2556
            << QString("-153")
 
2557
            << QString(useKeys ? "-15" : "")
 
2558
            << bool(useKeys)
 
2559
            << bool(useKeys ? true : false);
 
2560
        QTest::newRow(QString(inputMode + "range [3,7] int '2'").toLatin1())
 
2561
            << 3
 
2562
            << 7
 
2563
            << QString("2")
 
2564
            << QString("2")
 
2565
            << bool(useKeys)
 
2566
            << bool(false);
 
2567
 
 
2568
        QTest::newRow(QString(inputMode + "range [3,7] int '8'").toLatin1())
 
2569
            << 3
 
2570
            << 7
 
2571
            << QString("8")
 
2572
            << QString("")
 
2573
            << bool(useKeys)
 
2574
            << bool(false);
 
2575
    }
 
2576
}
 
2577
 
 
2578
void tst_QLineEdit::setValidator_QIntValidator()
 
2579
{
 
2580
    QFETCH(int, mini);
 
2581
    QFETCH(int, maxi);
 
2582
    QFETCH(QString, input);
 
2583
    QFETCH(QString, expectedText);
 
2584
    QFETCH(bool, useKeys);
 
2585
    QFETCH(bool, is_valid);
 
2586
 
 
2587
    QIntValidator intValidator(mini, maxi, 0);
 
2588
    testWidget->setValidator(&intValidator);
 
2589
    QVERIFY(testWidget->text().isEmpty());
 
2590
//qDebug("1 input: '" + input + "' Exp: '" + expectedText + "'");
 
2591
 
 
2592
    // tests valid input
 
2593
    if (!useKeys) {
 
2594
        testWidget->insert(input);
 
2595
    } else {
 
2596
        QTest::keyClicks(testWidget, input);
 
2597
        return_count = 0;
 
2598
        QTest::keyClick(testWidget, Qt::Key_Return);
 
2599
        QCOMPARE(return_count, int(is_valid)); // assuming that is_valid = true equals 1
 
2600
    }
 
2601
//qDebug("2 input: '" + input + "' Exp: '" + expectedText + "'");
 
2602
//    QCOMPARE(testWidget->displayText(), expectedText);
 
2603
    QCOMPARE(testWidget->text(), expectedText);
 
2604
}
 
2605
 
 
2606
#define NO_PIXMAP_TESTS
 
2607
 
 
2608
void tst_QLineEdit::frame_data()
 
2609
{
 
2610
#ifndef NO_PIXMAP_TESTS
 
2611
#if defined Q_OS_WIN
 
2612
    QTest::addColumn<QPixmap>("noFrame");
 
2613
    QTest::addColumn<QPixmap>("useFrame");
 
2614
 
 
2615
    QTest::newRow("win");
 
2616
//#else
 
2617
//    QTest::newRow("x11");
 
2618
#endif
 
2619
#endif
 
2620
}
 
2621
 
 
2622
void tst_QLineEdit::frame()
 
2623
{
 
2624
    testWidget->setFrame(false);
 
2625
    // verify that the editor is shown without a frame
 
2626
#ifndef NO_PIXMAP_TESTS
 
2627
#if defined Q_OS_WIN
 
2628
    QTEST(testWidget, "noFrame");
 
2629
#endif
 
2630
#endif
 
2631
    QVERIFY(!testWidget->hasFrame());
 
2632
 
 
2633
    testWidget->setFrame(true);
 
2634
    // verify that the editor is shown with a frame
 
2635
#ifndef NO_PIXMAP_TESTS
 
2636
#if defined Q_OS_WIN
 
2637
    QTEST(testWidget, "useFrame");
 
2638
#endif
 
2639
#endif
 
2640
    QVERIFY(testWidget->hasFrame());
 
2641
}
 
2642
 
 
2643
void tst_QLineEdit::setAlignment_data()
 
2644
{
 
2645
#ifndef NO_PIXMAP_TESTS
 
2646
#if defined Q_OS_WIN
 
2647
    QTest::addColumn<QPixmap>("left");
 
2648
    QTest::addColumn<QPixmap>("right");
 
2649
    QTest::addColumn<QPixmap>("hcenter");
 
2650
    QTest::addColumn<QPixmap>("auto");
 
2651
 
 
2652
    QTest::newRow("win");
 
2653
//#else
 
2654
//    QTest::newRow("x11");
 
2655
#endif
 
2656
#endif
 
2657
}
 
2658
 
 
2659
void tst_QLineEdit::setAlignment()
 
2660
{
 
2661
    testWidget->setText("left");
 
2662
    testWidget->setAlignment(Qt::AlignLeft);
 
2663
#ifndef NO_PIXMAP_TESTS
 
2664
#if defined Q_OS_WIN
 
2665
    QTEST(testWidget, "left");
 
2666
#endif
 
2667
#endif
 
2668
    QVERIFY(testWidget->alignment() == Qt::AlignLeft);
 
2669
 
 
2670
    testWidget->setText("hcenter");
 
2671
    testWidget->setAlignment(Qt::AlignHCenter);
 
2672
#ifndef NO_PIXMAP_TESTS
 
2673
#if defined Q_OS_WIN
 
2674
    QTEST(testWidget, "hcenter");
 
2675
#endif
 
2676
#endif
 
2677
    QVERIFY(testWidget->alignment() == Qt::AlignHCenter);
 
2678
 
 
2679
    testWidget->setText("right");
 
2680
    testWidget->setAlignment(Qt::AlignRight);
 
2681
#ifndef NO_PIXMAP_TESTS
 
2682
#if defined Q_OS_WIN
 
2683
    QTEST(testWidget, "right");
 
2684
#endif
 
2685
#endif
 
2686
    QVERIFY(testWidget->alignment() == Qt::AlignRight);
 
2687
 
 
2688
    testWidget->setAlignment(Qt::AlignTop);
 
2689
    QVERIFY(testWidget->alignment() == Qt::AlignTop);
 
2690
 
 
2691
    testWidget->setAlignment(Qt::AlignBottom);
 
2692
    QVERIFY(testWidget->alignment() == Qt::AlignBottom);
 
2693
 
 
2694
    testWidget->setAlignment(Qt::AlignCenter);
 
2695
    QVERIFY(testWidget->alignment() == Qt::AlignCenter);
 
2696
}
 
2697
 
 
2698
void tst_QLineEdit::isModified()
 
2699
{
 
2700
    QVERIFY(!testWidget->isModified());
 
2701
    testWidget->setText("bla");
 
2702
    QVERIFY(!testWidget->isModified());
 
2703
 
 
2704
    psKeyClick(testWidget, Qt::Key_Home);
 
2705
    QVERIFY(!testWidget->isModified());
 
2706
    QTest::keyClick(testWidget, Qt::Key_Right);
 
2707
    QVERIFY(!testWidget->isModified());
 
2708
    QTest::keyClick(testWidget, Qt::Key_Right);
 
2709
    QVERIFY(!testWidget->isModified());
 
2710
    QTest::keyClick(testWidget, Qt::Key_Right);
 
2711
    QVERIFY(!testWidget->isModified());
 
2712
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2713
    QVERIFY(!testWidget->isModified());
 
2714
    psKeyClick(testWidget, Qt::Key_End);
 
2715
    QVERIFY(!testWidget->isModified());
 
2716
 
 
2717
    QTest::keyClicks(testWidget, "T");
 
2718
    QVERIFY(testWidget->isModified());
 
2719
    QTest::keyClicks(testWidget, "his is a string");
 
2720
    QVERIFY(testWidget->isModified());
 
2721
 
 
2722
    testWidget->setText("");
 
2723
    QVERIFY(!testWidget->isModified());
 
2724
    testWidget->setText("foo");
 
2725
    QVERIFY(!testWidget->isModified());
 
2726
}
 
2727
 
 
2728
/*
 
2729
    Obsolete function but as long as we provide it, it needs to work.
 
2730
*/
 
2731
 
 
2732
void tst_QLineEdit::edited()
 
2733
{
 
2734
    QVERIFY(!testWidget->isModified());
 
2735
    testWidget->setText("bla");
 
2736
    QVERIFY(!testWidget->isModified());
 
2737
 
 
2738
    psKeyClick(testWidget, Qt::Key_Home);
 
2739
    QVERIFY(!testWidget->isModified());
 
2740
    QTest::keyClick(testWidget, Qt::Key_Right);
 
2741
    QVERIFY(!testWidget->isModified());
 
2742
    QTest::keyClick(testWidget, Qt::Key_Right);
 
2743
    QVERIFY(!testWidget->isModified());
 
2744
    QTest::keyClick(testWidget, Qt::Key_Right);
 
2745
    QVERIFY(!testWidget->isModified());
 
2746
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2747
    QVERIFY(!testWidget->isModified());
 
2748
    psKeyClick(testWidget, Qt::Key_End);
 
2749
    QVERIFY(!testWidget->isModified());
 
2750
 
 
2751
    QTest::keyClicks(testWidget, "T");
 
2752
    QVERIFY(testWidget->isModified());
 
2753
    QTest::keyClicks(testWidget, "his is a string");
 
2754
    QVERIFY(testWidget->isModified());
 
2755
 
 
2756
    testWidget->setModified(false);
 
2757
    QVERIFY(!testWidget->isModified());
 
2758
 
 
2759
    testWidget->setModified(true);
 
2760
    QVERIFY(testWidget->isModified());
 
2761
}
 
2762
 
 
2763
void tst_QLineEdit::insert()
 
2764
{
 
2765
    testWidget->insert("This");
 
2766
    testWidget->insert(" is");
 
2767
    testWidget->insert(" a");
 
2768
    testWidget->insert(" test");
 
2769
 
 
2770
    QCOMPARE(testWidget->text(), QString("This is a test"));
 
2771
 
 
2772
    testWidget->cursorWordBackward(false);
 
2773
    testWidget->cursorBackward(false, 1);
 
2774
    testWidget->insert(" nice");
 
2775
    QCOMPARE(testWidget->text(), QString("This is a nice test"));
 
2776
 
 
2777
    testWidget->setCursorPosition(-1);
 
2778
    testWidget->insert("No Crash! ");
 
2779
    QCOMPARE(testWidget->text(), QString("No Crash! This is a nice test"));
 
2780
}
 
2781
 
 
2782
void tst_QLineEdit::setSelection_data()
 
2783
{
 
2784
    QTest::addColumn<QString>("text");
 
2785
    QTest::addColumn<int>("start");
 
2786
    QTest::addColumn<int>("length");
 
2787
    QTest::addColumn<int>("expectedCursor");
 
2788
    QTest::addColumn<QString>("expectedText");
 
2789
    QTest::addColumn<bool>("expectedHasSelectedText");
 
2790
 
 
2791
    QString text = "Abc defg hijklmno, p 'qrst' uvw xyz";
 
2792
    int start, length, pos;
 
2793
 
 
2794
    start = 0; length = 1; pos = 1;
 
2795
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2796
        << text << start << length << pos << QString("A") << true;
 
2797
 
 
2798
    start = 0; length = 2; pos = 2;
 
2799
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2800
        << text << start << length << pos << QString("Ab") << true;
 
2801
 
 
2802
    start = 0; length = 4; pos = 4;
 
2803
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2804
        << text << start << length << pos << QString("Abc ") << true;
 
2805
 
 
2806
    start = -1; length = 0; pos = text.length();
 
2807
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2808
        << text << start << length << pos << QString() << false;
 
2809
 
 
2810
    start = 34; length = 1; pos = 35;
 
2811
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2812
        << text << start << length << pos << QString("z") << true;
 
2813
 
 
2814
    start = 34; length = 2; pos = 35;
 
2815
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2816
        << text << start << length << pos << QString("z") << true;
 
2817
 
 
2818
    start = 34; length = -1; pos = 33;
 
2819
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2820
        << text << start << length << pos << QString("y") << true;
 
2821
 
 
2822
    start = 1; length = -2; pos = 0;
 
2823
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2824
        << text << start << length << pos << QString("A") << true;
 
2825
 
 
2826
    start = -1; length = -1; pos = text.length();
 
2827
    QTest::newRow(QString("selection start: %1 length: %2").arg(start).arg(length).toLatin1())
 
2828
        << text << start << length << pos << QString() << false;
 
2829
}
 
2830
 
 
2831
 
 
2832
void tst_QLineEdit::setSelection()
 
2833
{
 
2834
    QFETCH(QString, text);
 
2835
    QFETCH(int, start);
 
2836
    QFETCH(int, length);
 
2837
    QFETCH(int, expectedCursor);
 
2838
    QFETCH(QString, expectedText);
 
2839
    QFETCH(bool, expectedHasSelectedText);
 
2840
 
 
2841
    testWidget->setText(text);
 
2842
    testWidget->setSelection(start, length);
 
2843
    QCOMPARE(testWidget->hasSelectedText(), expectedHasSelectedText);
 
2844
    QCOMPARE(testWidget->selectedText(), expectedText);
 
2845
    if (expectedCursor >= 0)
 
2846
        QCOMPARE(testWidget->cursorPosition(), expectedCursor);
 
2847
}
 
2848
 
 
2849
#ifndef QT_NO_CLIPBOARD
 
2850
void tst_QLineEdit::cut()
 
2851
{
 
2852
    if (!PlatformClipboard::isAvailable())
 
2853
        QSKIP("Autotests run from cron and pasteboard don't get along quite ATM");
 
2854
 
 
2855
    // test newlines in cut'n'paste
 
2856
    testWidget->setText("A\nB\nC\n");
 
2857
    testWidget->setSelection(0, 6);
 
2858
    testWidget->cut();
 
2859
    psKeyClick(testWidget, Qt::Key_Home);
 
2860
    testWidget->paste();
 
2861
    QCOMPARE(testWidget->text(), QString("A\nB\nC\n"));
 
2862
    //                              1         2         3         4
 
2863
    //                    01234567890123456789012345678901234567890
 
2864
    testWidget->setText("Abc defg hijklmno");
 
2865
 
 
2866
    testWidget->setSelection(0, 3);
 
2867
    testWidget->cut();
 
2868
    QCOMPARE(testWidget->text(), QString(" defg hijklmno"));
 
2869
 
 
2870
    psKeyClick(testWidget, Qt::Key_End);
 
2871
    testWidget->paste();
 
2872
    QCOMPARE(testWidget->text(), QString(" defg hijklmnoAbc"));
 
2873
 
 
2874
    psKeyClick(testWidget, Qt::Key_Home);
 
2875
    testWidget->del();
 
2876
    QCOMPARE(testWidget->text(), QString("defg hijklmnoAbc"));
 
2877
 
 
2878
    testWidget->setSelection(0, 4);
 
2879
    testWidget->copy();
 
2880
    psKeyClick(testWidget, Qt::Key_End);
 
2881
    testWidget->paste();
 
2882
    QCOMPARE(testWidget->text(), QString("defg hijklmnoAbcdefg"));
 
2883
 
 
2884
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2885
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2886
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2887
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2888
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2889
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2890
    QTest::keyClick(testWidget, Qt::Key_Left);
 
2891
    QTest::keyClick(testWidget, ' ');
 
2892
    QCOMPARE(testWidget->text(), QString("defg hijklmno Abcdefg"));
 
2893
 
 
2894
    testWidget->setSelection(0, 5);
 
2895
    testWidget->del();
 
2896
    QCOMPARE(testWidget->text(), QString("hijklmno Abcdefg"));
 
2897
 
 
2898
    testWidget->end(false);
 
2899
    QTest::keyClick(testWidget, ' ');
 
2900
    testWidget->paste();
 
2901
    QCOMPARE(testWidget->text(), QString("hijklmno Abcdefg defg"));
 
2902
 
 
2903
    testWidget->home(false);
 
2904
    testWidget->cursorWordForward(true);
 
2905
    testWidget->cut();
 
2906
    testWidget->end(false);
 
2907
    QTest::keyClick(testWidget, ' ');
 
2908
    testWidget->paste();
 
2909
    testWidget->cursorBackward(true, 1);
 
2910
    testWidget->cut();
 
2911
    QCOMPARE(testWidget->text(), QString("Abcdefg defg hijklmno"));
 
2912
}
 
2913
#endif
 
2914
 
 
2915
class InputMaskValidator : public QValidator
 
2916
{
 
2917
public:
 
2918
    InputMaskValidator(QObject *parent, const char *name = 0) : QValidator(parent) { setObjectName(name); }
 
2919
    State validate(QString &text, int &pos) const
 
2920
    {
 
2921
        InputMaskValidator *that = (InputMaskValidator *)this;
 
2922
        that->validateText = text;
 
2923
        that->validatePos = pos;
 
2924
        return Acceptable;
 
2925
    }
 
2926
    QString validateText;
 
2927
    int validatePos;
 
2928
};
 
2929
 
 
2930
void tst_QLineEdit::inputMaskAndValidator_data()
 
2931
{
 
2932
    QTest::addColumn<QString>("inputMask");
 
2933
    QTest::addColumn<QTestEventList>("keys");
 
2934
    QTest::addColumn<QString>("validateText");
 
2935
    QTest::addColumn<int>("validatePos");
 
2936
 
 
2937
    QTestEventList inputKeys;
 
2938
    inputKeys.addKeyClick(Qt::Key_1);
 
2939
    inputKeys.addKeyClick(Qt::Key_2);
 
2940
 
 
2941
    QTest::newRow("task28291") << "000;_" << inputKeys << "12_" << 2;
 
2942
}
 
2943
 
 
2944
void tst_QLineEdit::inputMaskAndValidator()
 
2945
{
 
2946
    QFETCH(QString, inputMask);
 
2947
    QFETCH(QTestEventList, keys);
 
2948
    QFETCH(QString, validateText);
 
2949
    QFETCH(int, validatePos);
 
2950
 
 
2951
    InputMaskValidator imv(testWidget);
 
2952
    testWidget->setValidator(&imv);
 
2953
 
 
2954
    testWidget->setInputMask(inputMask);
 
2955
    keys.simulate(testWidget);
 
2956
 
 
2957
    QCOMPARE(imv.validateText, validateText);
 
2958
    QCOMPARE(imv.validatePos, validatePos);
 
2959
}
 
2960
 
 
2961
void tst_QLineEdit::maxLengthAndInputMask()
 
2962
{
 
2963
    // Really a test for #30447
 
2964
    QVERIFY(testWidget->inputMask().isNull());
 
2965
    testWidget->setMaxLength(10);
 
2966
    QVERIFY(testWidget->maxLength() == 10);
 
2967
    testWidget->setInputMask(QString::null);
 
2968
    QVERIFY(testWidget->inputMask().isNull());
 
2969
    QVERIFY(testWidget->maxLength() == 10);
 
2970
}
 
2971
 
 
2972
 
 
2973
class LineEdit : public QLineEdit
 
2974
{
 
2975
public:
 
2976
    LineEdit() { state = Other; }
 
2977
 
 
2978
    void keyPressEvent(QKeyEvent *e)
 
2979
    {
 
2980
        QLineEdit::keyPressEvent(e);
 
2981
        if (e->key() == Qt::Key_Enter) {
 
2982
            state = e->isAccepted() ? Accepted : Ignored;
 
2983
        } else {
 
2984
            state = Other;
 
2985
        }
 
2986
 
 
2987
    }
 
2988
    enum State {
 
2989
        Accepted,
 
2990
        Ignored,
 
2991
        Other
 
2992
    };
 
2993
 
 
2994
    State state;
 
2995
 
 
2996
    friend class tst_QLineEdit;
 
2997
};
 
2998
 
 
2999
Q_DECLARE_METATYPE(LineEdit::State);
 
3000
void tst_QLineEdit::returnPressedKeyEvent()
 
3001
{
 
3002
    LineEdit lineedit;
 
3003
    lineedit.show();
 
3004
    QCOMPARE((int)lineedit.state, (int)LineEdit::Other);
 
3005
    QTest::keyClick(&lineedit, Qt::Key_Enter);
 
3006
    QCOMPARE((int)lineedit.state, (int)LineEdit::Ignored);
 
3007
    connect(&lineedit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
 
3008
    QTest::keyClick(&lineedit, Qt::Key_Enter);
 
3009
    QCOMPARE((int)lineedit.state, (int)LineEdit::Ignored);
 
3010
    disconnect(&lineedit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
 
3011
    QTest::keyClick(&lineedit, Qt::Key_Enter);
 
3012
    QCOMPARE((int)lineedit.state, (int)LineEdit::Ignored);
 
3013
    QTest::keyClick(&lineedit, Qt::Key_1);
 
3014
    QCOMPARE((int)lineedit.state, (int)LineEdit::Other);
 
3015
}
 
3016
 
 
3017
void tst_QLineEdit::keepSelectionOnTabFocusIn()
 
3018
{
 
3019
    testWidget->setText("hello world");
 
3020
    {
 
3021
        QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason);
 
3022
        QApplication::sendEvent(testWidget, &e);
 
3023
    }
 
3024
    QCOMPARE(testWidget->selectedText(), QString("hello world"));
 
3025
    testWidget->setSelection(0, 5);
 
3026
    QCOMPARE(testWidget->selectedText(), QString("hello"));
 
3027
    {
 
3028
        QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason);
 
3029
        QApplication::sendEvent(testWidget, &e);
 
3030
    }
 
3031
    QCOMPARE(testWidget->selectedText(), QString("hello"));
 
3032
}
 
3033
 
 
3034
void tst_QLineEdit::readOnlyStyleOption()
 
3035
{
 
3036
    bool wasReadOnly = testWidget->isReadOnly();
 
3037
    QStyle *oldStyle = testWidget->style();
 
3038
 
 
3039
    StyleOptionTestStyle myStyle;
 
3040
    testWidget->setStyle(&myStyle);
 
3041
 
 
3042
    myStyle.setReadOnly(true);
 
3043
    testWidget->setReadOnly(true);
 
3044
    testWidget->repaint();
 
3045
    qApp->processEvents();
 
3046
 
 
3047
    testWidget->setReadOnly(false);
 
3048
    myStyle.setReadOnly(false);
 
3049
    testWidget->repaint();
 
3050
    qApp->processEvents();
 
3051
 
 
3052
    testWidget->setReadOnly(wasReadOnly);
 
3053
    testWidget->setStyle(oldStyle);
 
3054
}
 
3055
 
 
3056
void tst_QLineEdit::validateOnFocusOut()
 
3057
{
 
3058
    QSignalSpy editingFinishedSpy(testWidget, SIGNAL(editingFinished()));
 
3059
    testWidget->setValidator(new QIntValidator(100, 999, 0));
 
3060
    QTest::keyPress(testWidget, '1');
 
3061
    QTest::keyPress(testWidget, '0');
 
3062
    QCOMPARE(testWidget->text(), QString("10"));
 
3063
    testWidget->clearFocus();
 
3064
    QCOMPARE(editingFinishedSpy.count(), 0);
 
3065
 
 
3066
    testWidget->setFocus();
 
3067
    testWidget->activateWindow();
 
3068
    QTRY_VERIFY(testWidget->hasFocus());
 
3069
 
 
3070
    QTest::keyPress(testWidget, '0');
 
3071
    QTRY_COMPARE(testWidget->text(), QString("100"));
 
3072
 
 
3073
    testWidget->clearFocus();
 
3074
    QCOMPARE(editingFinishedSpy.count(), 1);
 
3075
}
 
3076
 
 
3077
void tst_QLineEdit::editInvalidText()
 
3078
{
 
3079
    testWidget->clear();
 
3080
    testWidget->setValidator(new QIntValidator(0, 120, 0));
 
3081
    testWidget->setText("1234");
 
3082
 
 
3083
    QVERIFY(!testWidget->hasAcceptableInput());
 
3084
    QTest::keyPress(testWidget, Qt::Key_Backspace);
 
3085
    QTest::keyPress(testWidget, Qt::Key_Backspace);
 
3086
    QTest::keyPress(testWidget, Qt::Key_A);
 
3087
    QTest::keyPress(testWidget, Qt::Key_B);
 
3088
    QTest::keyPress(testWidget, Qt::Key_C);
 
3089
    QTest::keyPress(testWidget, Qt::Key_1);
 
3090
    QVERIFY(testWidget->hasAcceptableInput());
 
3091
    QCOMPARE(testWidget->text(), QString("12"));
 
3092
    testWidget->cursorBackward(false);
 
3093
    testWidget->cursorBackward(true, 2);
 
3094
    QTest::keyPress(testWidget, Qt::Key_Delete);
 
3095
    QVERIFY(testWidget->hasAcceptableInput());
 
3096
    QCOMPARE(testWidget->text(), QString("2"));
 
3097
    QTest::keyPress(testWidget, Qt::Key_1);
 
3098
    QVERIFY(testWidget->hasAcceptableInput());
 
3099
    QCOMPARE(testWidget->text(), QString("12"));
 
3100
 
 
3101
    testWidget->setValidator(0);
 
3102
}
 
3103
 
 
3104
void tst_QLineEdit::charWithAltOrCtrlModifier()
 
3105
{
 
3106
    testWidget->clear();
 
3107
    QCOMPARE(testWidget->text(), QString(""));
 
3108
    QTest::keyPress(testWidget, Qt::Key_Plus);
 
3109
    QCOMPARE(testWidget->text(), QString("+"));
 
3110
    QTest::keyPress(testWidget, Qt::Key_Plus, Qt::ControlModifier);
 
3111
    QCOMPARE(testWidget->text(), QString("++"));
 
3112
    QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier);
 
3113
    QCOMPARE(testWidget->text(), QString("+++"));
 
3114
    QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier | Qt::ControlModifier);
 
3115
    QCOMPARE(testWidget->text(), QString("++++"));
 
3116
}
 
3117
 
 
3118
void tst_QLineEdit::leftKeyOnSelectedText()
 
3119
{
 
3120
    testWidget->clear();
 
3121
    testWidget->setText("0123");
 
3122
    testWidget->setCursorPosition(4);
 
3123
    QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier);
 
3124
    QCOMPARE(testWidget->cursorPosition(), 3);
 
3125
    QCOMPARE(testWidget->selectedText(), QString("3"));
 
3126
    QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier);
 
3127
    QCOMPARE(testWidget->cursorPosition(), 2);
 
3128
    QCOMPARE(testWidget->selectedText(), QString("23"));
 
3129
    QTest::keyClick(testWidget, Qt::Key_Left);
 
3130
#ifdef Q_OS_WIN
 
3131
    QCOMPARE(testWidget->cursorPosition(), 1);
 
3132
#else
 
3133
    // Selection is cleared ands cursor remains at position 2.
 
3134
    // X11 used to behave like window prior to 4.2. Changes caused by QKeySequence
 
3135
    // resulted in an inadvertant change in behavior
 
3136
    QCOMPARE(testWidget->cursorPosition(), 2);
 
3137
#endif
 
3138
}
 
3139
 
 
3140
void tst_QLineEdit::inlineCompletion()
 
3141
{
 
3142
    testWidget->clear();
 
3143
    QStandardItemModel *model = new QStandardItemModel;
 
3144
    QStandardItem *root = model->invisibleRootItem();
 
3145
    QStandardItem *items[5];
 
3146
    for (int i = 0; i < 5; i++) {
 
3147
        items[i] = new QStandardItem(QString("item%1").arg(i));
 
3148
        if ((i+2)%2 == 0) { // disable 0,2,4
 
3149
            items[i]->setFlags(items[i]->flags() & ~Qt::ItemIsEnabled);
 
3150
        }
 
3151
        root->appendRow(items[i]);
 
3152
    }
 
3153
    QCompleter *completer = new QCompleter(model);
 
3154
    completer->setCompletionMode(QCompleter::InlineCompletion);
 
3155
    completer->setCaseSensitivity(Qt::CaseInsensitive);
 
3156
    testWidget->setFocus();
 
3157
    QTRY_COMPARE(qApp->activeWindow(), (QWidget*)testWidget);
 
3158
    testWidget->setCompleter(completer);
 
3159
 
 
3160
    // sanity
 
3161
    QTest::keyClick(testWidget, Qt::Key_X);
 
3162
    QCOMPARE(testWidget->selectedText(), QString());
 
3163
    QCOMPARE(testWidget->text(), QString("x"));
 
3164
    QTest::keyClick(testWidget, Qt::Key_Down, Qt::ControlModifier);
 
3165
    QCOMPARE(testWidget->selectedText(), QString());
 
3166
    QCOMPARE(testWidget->text(), QString("x"));
 
3167
    QTest::keyClick(testWidget, Qt::Key_Up, Qt::ControlModifier);
 
3168
    QCOMPARE(testWidget->selectedText(), QString());
 
3169
    QCOMPARE(testWidget->text(), QString("x"));
 
3170
 
 
3171
    testWidget->clear();
 
3172
    QTest::keyClick(testWidget, Qt::Key_I);
 
3173
    QCOMPARE(testWidget->selectedText(), QString("tem1"));
 
3174
 
 
3175
    Qt::KeyboardModifiers keyboardModifiers = Qt::ControlModifier;
 
3176
#ifdef Q_OS_MAC
 
3177
    keyboardModifiers |= Qt::AltModifier;
 
3178
#endif
 
3179
    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
 
3180
    QCOMPARE(testWidget->selectedText(), QString("tem3"));
 
3181
 
 
3182
    // wraps around (Default)
 
3183
    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
 
3184
    QCOMPARE(testWidget->selectedText(), QString("tem1"));
 
3185
 
 
3186
    QTest::keyClick(testWidget, Qt::Key_Up, keyboardModifiers);
 
3187
    QCOMPARE(testWidget->selectedText(), QString("tem3"));
 
3188
 
 
3189
    // should not wrap
 
3190
    completer->setWrapAround(false);
 
3191
    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
 
3192
    QCOMPARE(testWidget->selectedText(), QString("tem3"));
 
3193
    QTest::keyClick(testWidget, Qt::Key_Up, keyboardModifiers); // item1
 
3194
    QTest::keyClick(testWidget, Qt::Key_Up, keyboardModifiers); // item1
 
3195
    QCOMPARE(testWidget->selectedText(), QString("tem1"));
 
3196
 
 
3197
    // trivia :)
 
3198
    root->appendRow(new QStandardItem("item11"));
 
3199
    root->appendRow(new QStandardItem("item12"));
 
3200
    testWidget->clear();
 
3201
    QTest::keyClick(testWidget, Qt::Key_I);
 
3202
    QCOMPARE(testWidget->selectedText(), QString("tem1"));
 
3203
    QTest::keyClick(testWidget, Qt::Key_Delete);
 
3204
    QCOMPARE(testWidget->selectedText(), QString());
 
3205
    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
 
3206
    QCOMPARE(testWidget->selectedText(), QString("tem1")); // neato
 
3207
    testWidget->setText("item1");
 
3208
    testWidget->setSelection(1, 2);
 
3209
    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers);
 
3210
    testWidget->end(false);
 
3211
    QCOMPARE(testWidget->text(), QString("item1")); // no effect for selection in "middle"
 
3212
    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers); // item1
 
3213
    QTest::keyClick(testWidget, Qt::Key_Down, keyboardModifiers); // item11
 
3214
    QCOMPARE(testWidget->text(), QString("item11"));
 
3215
 
 
3216
    delete model;
 
3217
    delete completer;
 
3218
}
 
3219
 
 
3220
void tst_QLineEdit::noTextEditedOnClear()
 
3221
{
 
3222
    testWidget->setText("Test");
 
3223
    QSignalSpy textEditedSpy(testWidget, SIGNAL(textEdited(QString)));
 
3224
    testWidget->clear();
 
3225
    QCOMPARE(textEditedSpy.count(), 0);
 
3226
}
 
3227
 
 
3228
void tst_QLineEdit::textMargin_data()
 
3229
{
 
3230
    QTest::addColumn<int>("left");
 
3231
    QTest::addColumn<int>("top");
 
3232
    QTest::addColumn<int>("right");
 
3233
    QTest::addColumn<int>("bottom");
 
3234
 
 
3235
    QTest::addColumn<QPoint>("mousePressPos");
 
3236
    QTest::addColumn<int>("cursorPosition");
 
3237
 
 
3238
    QLineEdit testWidget;
 
3239
    QFontMetrics metrics(testWidget.font());
 
3240
    const QString s = QLatin1String("MMM MMM MMM");
 
3241
 
 
3242
    // Different styles generate different offsets, so
 
3243
    // calculate the width rather than hardcode it.
 
3244
    const int pixelWidthOfM = metrics.width(s, 1);
 
3245
    const int pixelWidthOfMMM_MM = metrics.width(s, 6);
 
3246
 
 
3247
    QTest::newRow("default-0") << 0 << 0 << 0 << 0 << QPoint(pixelWidthOfMMM_MM, 0) << 6;
 
3248
    QTest::newRow("default-1") << 0 << 0 << 0 << 0 << QPoint(1, 1) << 0;
 
3249
    QTest::newRow("default-2") << -1 << 0 << -1 << 0 << QPoint(pixelWidthOfMMM_MM, 0) << 6;
 
3250
    QTest::newRow("default-3") << 0 << 0 << 0 << 0 << QPoint(pixelWidthOfM, 1) << 1;
 
3251
 
 
3252
    QTest::newRow("hor-0") << 10 << 0 << 10 << 0 << QPoint(1, 1) << 0;
 
3253
    QTest::newRow("hor-1") << 10 << 0 << 10 << 0 << QPoint(10, 1) << 0;
 
3254
    QTest::newRow("hor-2") << 20 << 0 << 10 << 0 << QPoint(20, 1) << 0;
 
3255
 
 
3256
    if (!qApp->style()->inherits("QMacStyle")) { //MacStyle doesn't support verticals margins.
 
3257
        QTest::newRow("default-2-ver") << -1 << -1 << -1 << -1 << QPoint(pixelWidthOfMMM_MM, 0) << 6;
 
3258
        QTest::newRow("ver") << 0 << 10 << 0 << 10 << QPoint(1, 1) << 0;
 
3259
    }
 
3260
}
 
3261
 
 
3262
void tst_QLineEdit::textMargin()
 
3263
{
 
3264
    QFETCH(int, left);
 
3265
    QFETCH(int, top);
 
3266
    QFETCH(int, right);
 
3267
    QFETCH(int, bottom);
 
3268
    QFETCH(QPoint, mousePressPos);
 
3269
    QFETCH(int, cursorPosition);
 
3270
 
 
3271
    // Put the line edit into a toplevel window to avoid
 
3272
    // resizing by the window system.
 
3273
    QWidget tlw;
 
3274
    QLineEdit testWidget(&tlw);
 
3275
    testWidget.setGeometry(100, 100, 100, 30);
 
3276
    testWidget.setText("MMM MMM MMM");
 
3277
    testWidget.setCursorPosition(6);
 
3278
 
 
3279
    QSize sizeHint = testWidget.sizeHint();
 
3280
    testWidget.setTextMargins(left, top, right, bottom);
 
3281
    sizeHint.setWidth(sizeHint.width() + left + right);
 
3282
    sizeHint.setHeight(sizeHint.height() + top +bottom);
 
3283
    QCOMPARE(testWidget.sizeHint(), sizeHint);
 
3284
    testWidget.setFrame(false);
 
3285
    tlw.show();
 
3286
 
 
3287
    int l;
 
3288
    int t;
 
3289
    int r;
 
3290
    int b;
 
3291
    testWidget.getTextMargins(&l, &t, &r, &b);
 
3292
    QCOMPARE(left, l);
 
3293
    QCOMPARE(top, t);
 
3294
    QCOMPARE(right, r);
 
3295
    QCOMPARE(bottom, b);
 
3296
 
 
3297
    QTest::mouseClick(&testWidget, Qt::LeftButton, 0, mousePressPos);
 
3298
    QTRY_COMPARE(testWidget.cursorPosition(), cursorPosition);
 
3299
}
 
3300
 
 
3301
#ifndef QTEST_NO_CURSOR
 
3302
void tst_QLineEdit::cursor()
 
3303
{
 
3304
    testWidget->setReadOnly(false);
 
3305
    QCOMPARE(testWidget->cursor().shape(), Qt::IBeamCursor);
 
3306
    testWidget->setReadOnly(true);
 
3307
    QCOMPARE(testWidget->cursor().shape(), Qt::ArrowCursor);
 
3308
    testWidget->setReadOnly(false);
 
3309
    QCOMPARE(testWidget->cursor().shape(), Qt::IBeamCursor);
 
3310
}
 
3311
#endif
 
3312
 
 
3313
class task180999_Widget : public QWidget
 
3314
{
 
3315
public:
 
3316
    task180999_Widget(QWidget *parent = 0) : QWidget(parent)
 
3317
    {
 
3318
        QHBoxLayout *layout  = new QHBoxLayout(this);
 
3319
        lineEdit1.setText("some text 1 ...");
 
3320
        lineEdit2.setText("some text 2 ...");
 
3321
        layout->addWidget(&lineEdit1);
 
3322
        layout->addWidget(&lineEdit2);
 
3323
    }
 
3324
 
 
3325
    QLineEdit lineEdit1;
 
3326
    QLineEdit lineEdit2;
 
3327
};
 
3328
 
 
3329
void tst_QLineEdit::task180999_focus()
 
3330
{
 
3331
    task180999_Widget widget;
 
3332
 
 
3333
    widget.lineEdit1.setFocus();
 
3334
    widget.show();
 
3335
 
 
3336
    widget.lineEdit2.setFocus();
 
3337
    widget.lineEdit2.selectAll();
 
3338
    widget.hide();
 
3339
 
 
3340
    widget.lineEdit1.setFocus();
 
3341
    widget.show();
 
3342
    QTest::qWait(200);
 
3343
    widget.activateWindow();
 
3344
 
 
3345
    QTRY_VERIFY(!widget.lineEdit2.hasSelectedText());
 
3346
}
 
3347
 
 
3348
void tst_QLineEdit::task174640_editingFinished()
 
3349
{
 
3350
    QWidget mw;
 
3351
    QVBoxLayout *layout = new QVBoxLayout(&mw);
 
3352
    QLineEdit *le1 = new QLineEdit(&mw);
 
3353
    QLineEdit *le2 = new QLineEdit(&mw);
 
3354
    layout->addWidget(le1);
 
3355
    layout->addWidget(le2);
 
3356
 
 
3357
    mw.show();
 
3358
    QApplication::setActiveWindow(&mw);
 
3359
    mw.activateWindow();
 
3360
    QVERIFY(QTest::qWaitForWindowActive(&mw));
 
3361
    QCOMPARE(&mw, QApplication::activeWindow());
 
3362
 
 
3363
    QSignalSpy editingFinishedSpy(le1, SIGNAL(editingFinished()));
 
3364
 
 
3365
    le1->setFocus();
 
3366
    QTest::qWait(20);
 
3367
    QTRY_VERIFY(le1->hasFocus());
 
3368
    QCOMPARE(editingFinishedSpy.count(), 0);
 
3369
 
 
3370
    le2->setFocus();
 
3371
    QTest::qWait(20);
 
3372
    QTRY_VERIFY(le2->hasFocus());
 
3373
    QCOMPARE(editingFinishedSpy.count(), 1);
 
3374
    editingFinishedSpy.clear();
 
3375
 
 
3376
    le1->setFocus();
 
3377
    QTest::qWait(20);
 
3378
    QTRY_VERIFY(le1->hasFocus());
 
3379
 
 
3380
    QMenu *testMenu1 = new QMenu(le1);
 
3381
    testMenu1->addAction("foo");
 
3382
    testMenu1->addAction("bar");
 
3383
    testMenu1->show();
 
3384
    QVERIFY(QTest::qWaitForWindowExposed(testMenu1));
 
3385
    QTest::qWait(20);
 
3386
    mw.activateWindow();
 
3387
 
 
3388
    delete testMenu1;
 
3389
    QCOMPARE(editingFinishedSpy.count(), 0);
 
3390
    QTRY_VERIFY(le1->hasFocus());
 
3391
 
 
3392
    QMenu *testMenu2 = new QMenu(le2);
 
3393
    testMenu2->addAction("foo2");
 
3394
    testMenu2->addAction("bar2");
 
3395
    testMenu2->show();
 
3396
    QVERIFY(QTest::qWaitForWindowExposed(testMenu2));
 
3397
    QTest::qWait(20);
 
3398
    mw.activateWindow();
 
3399
    delete testMenu2;
 
3400
    QCOMPARE(editingFinishedSpy.count(), 1);
 
3401
}
 
3402
 
 
3403
#ifndef QT_NO_COMPLETER
 
3404
class task198789_Widget : public QWidget
 
3405
{
 
3406
    Q_OBJECT
 
3407
public:
 
3408
    task198789_Widget(QWidget *parent = 0) : QWidget(parent)
 
3409
    {
 
3410
        QStringList wordList;
 
3411
        wordList << "alpha" << "omega" << "omicron" << "zeta";
 
3412
 
 
3413
        lineEdit = new QLineEdit(this);
 
3414
        completer = new QCompleter(wordList, this);
 
3415
        lineEdit->setCompleter(completer);
 
3416
 
 
3417
        connect(lineEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
 
3418
    }
 
3419
 
 
3420
    QLineEdit *lineEdit;
 
3421
    QCompleter *completer;
 
3422
    QString currentCompletion;
 
3423
 
 
3424
private slots:
 
3425
    void textChanged(const QString &)
 
3426
    {
 
3427
        currentCompletion = completer->currentCompletion();
 
3428
    }
 
3429
};
 
3430
 
 
3431
void tst_QLineEdit::task198789_currentCompletion()
 
3432
{
 
3433
    task198789_Widget widget;
 
3434
    widget.show();
 
3435
    qApp->processEvents();
 
3436
    QTest::keyPress(widget.lineEdit, 'o');
 
3437
    QTest::keyPress(widget.lineEdit, 'm');
 
3438
    QTest::keyPress(widget.lineEdit, 'i');
 
3439
    QCOMPARE(widget.currentCompletion, QLatin1String("omicron"));
 
3440
}
 
3441
 
 
3442
void tst_QLineEdit::task210502_caseInsensitiveInlineCompletion()
 
3443
{
 
3444
    QString completion("ABCD");
 
3445
    QStringList completions;
 
3446
    completions << completion;
 
3447
    QLineEdit lineEdit;
 
3448
    QCompleter completer(completions);
 
3449
    completer.setCaseSensitivity(Qt::CaseInsensitive);
 
3450
    completer.setCompletionMode(QCompleter::InlineCompletion);
 
3451
    lineEdit.setCompleter(&completer);
 
3452
    lineEdit.show();
 
3453
    QApplication::setActiveWindow(&lineEdit);
 
3454
    QVERIFY(QTest::qWaitForWindowActive(&lineEdit));
 
3455
    lineEdit.setFocus();
 
3456
    QTRY_VERIFY(lineEdit.hasFocus());
 
3457
    QTest::keyPress(&lineEdit, 'a');
 
3458
    QTest::keyPress(&lineEdit, Qt::Key_Return);
 
3459
    QCOMPARE(lineEdit.text(), completion);
 
3460
}
 
3461
 
 
3462
#endif // QT_NO_COMPLETER
 
3463
 
 
3464
 
 
3465
void tst_QLineEdit::task229938_dontEmitChangedWhenTextIsNotChanged()
 
3466
{
 
3467
    QLineEdit lineEdit;
 
3468
    lineEdit.setMaxLength(5);
 
3469
    lineEdit.show();
 
3470
    QTest::qWaitForWindowExposed(&lineEdit); // to be safe and avoid failing setFocus with window managers
 
3471
    lineEdit.setFocus();
 
3472
    QSignalSpy changedSpy(&lineEdit, SIGNAL(textChanged(QString)));
 
3473
    QTest::qWait(200);
 
3474
    QTest::keyPress(&lineEdit, 'a');
 
3475
    QTest::keyPress(&lineEdit, 'b');
 
3476
    QTest::keyPress(&lineEdit, 'c');
 
3477
    QTest::keyPress(&lineEdit, 'd');
 
3478
    QTest::keyPress(&lineEdit, 'e');
 
3479
    QTest::keyPress(&lineEdit, 'f');
 
3480
    QCOMPARE(changedSpy.count(), 5);
 
3481
}
 
3482
 
 
3483
void tst_QLineEdit::task233101_cursorPosAfterInputMethod_data()
 
3484
{
 
3485
    QTest::addColumn<int>("maxLength");
 
3486
    QTest::addColumn<int>("cursorPos");
 
3487
    QTest::addColumn<int>("replacementStart");
 
3488
    QTest::addColumn<int>("replacementLength");
 
3489
    QTest::addColumn<QString>("commitString");
 
3490
 
 
3491
    QTest::newRow("data1")  << 4 << 4 << 0 << 0 << QString("");
 
3492
    QTest::newRow("data2")  << 4 << 4 << 0 << 0 << QString("x");
 
3493
    QTest::newRow("data3")  << 4 << 4 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
 
3494
    QTest::newRow("data4")  << 4 << 3 << 0 << 0 << QString("");
 
3495
    QTest::newRow("data5")  << 4 << 3 << 0 << 0 << QString("x");
 
3496
    QTest::newRow("data6")  << 4 << 3 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
 
3497
    QTest::newRow("data7")  << 4 << 0 << 0 << 0 << QString("");
 
3498
    QTest::newRow("data8")  << 4 << 0 << 0 << 0 << QString("x");
 
3499
    QTest::newRow("data9")  << 4 << 0 << 0 << 0 << QString("xxxxxxxxxxxxxxxx");
 
3500
 
 
3501
    QTest::newRow("data10") << 4 << 4 << -4 << 4 << QString("");
 
3502
    QTest::newRow("data11") << 4 << 4 << -4 << 4 << QString("x");
 
3503
    QTest::newRow("data12") << 4 << 4 << -4 << 4 << QString("xxxxxxxxxxxxxxxx");
 
3504
    QTest::newRow("data13") << 4 << 3 << -3 << 4 << QString("");
 
3505
    QTest::newRow("data14") << 4 << 3 << -3 << 4 << QString("x");
 
3506
    QTest::newRow("data15") << 4 << 3 << -3 << 4 << QString("xxxxxxxxxxxxxxxx");
 
3507
    QTest::newRow("data16") << 4 << 0 << 0 << 4 << QString("");
 
3508
    QTest::newRow("data17") << 4 << 0 << 0 << 4 << QString("x");
 
3509
    QTest::newRow("data18") << 4 << 0 << 0 << 4 << QString("xxxxxxxxxxxxxxxx");
 
3510
 
 
3511
    QTest::newRow("data19") << 4 << 4 << -4 << 0 << QString("");
 
3512
    QTest::newRow("data20") << 4 << 4 << -4 << 0 << QString("x");
 
3513
    QTest::newRow("data21") << 4 << 4 << -4 << 0 << QString("xxxxxxxxxxxxxxxx");
 
3514
    QTest::newRow("data22") << 4 << 3 << -3 << 0 << QString("");
 
3515
    QTest::newRow("data23") << 4 << 3 << -3 << 0 << QString("x");
 
3516
    QTest::newRow("data24") << 4 << 3 << -3 << 0 << QString("xxxxxxxxxxxxxxxx");
 
3517
}
 
3518
 
 
3519
void tst_QLineEdit::task233101_cursorPosAfterInputMethod()
 
3520
{
 
3521
    QFETCH(int, maxLength);
 
3522
    QFETCH(int, cursorPos);
 
3523
    QFETCH(int, replacementStart);
 
3524
    QFETCH(int, replacementLength);
 
3525
    QFETCH(QString, commitString);
 
3526
 
 
3527
    QLineEdit lineEdit;
 
3528
    lineEdit.setMaxLength(maxLength);
 
3529
    lineEdit.insert(QString().fill(QLatin1Char('a'), cursorPos));
 
3530
    QCOMPARE(lineEdit.cursorPosition(), cursorPos);
 
3531
 
 
3532
    QInputMethodEvent event;
 
3533
    event.setCommitString(QLatin1String("x"), replacementStart, replacementLength);
 
3534
    qApp->sendEvent(&lineEdit, &event);
 
3535
    QVERIFY(lineEdit.cursorPosition() >= 0);
 
3536
    QVERIFY(lineEdit.cursorPosition() <= lineEdit.text().size());
 
3537
    QVERIFY(lineEdit.text().size() <= lineEdit.maxLength());
 
3538
}
 
3539
 
 
3540
void tst_QLineEdit::task241436_passwordEchoOnEditRestoreEchoMode()
 
3541
{
 
3542
    QStyleOptionFrameV2 opt;
 
3543
    QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
 
3544
 
 
3545
    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
 
3546
    testWidget->setFocus();
 
3547
    QApplication::setActiveWindow(testWidget);
 
3548
    QTRY_VERIFY(testWidget->hasFocus());
 
3549
 
 
3550
    QTest::keyPress(testWidget, '0');
 
3551
    QCOMPARE(testWidget->displayText(), QString("0"));
 
3552
    testWidget->setEchoMode(QLineEdit::Normal);
 
3553
    testWidget->clearFocus();
 
3554
    QCOMPARE(testWidget->displayText(), QString("0"));
 
3555
 
 
3556
    testWidget->activateWindow();
 
3557
    testWidget->setFocus();
 
3558
    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
 
3559
    QTest::keyPress(testWidget, '0');
 
3560
    QCOMPARE(testWidget->displayText(), QString("0"));
 
3561
    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
 
3562
    QCOMPARE(testWidget->displayText(), QString("0"));
 
3563
    testWidget->clearFocus();
 
3564
    QCOMPARE(testWidget->displayText(), QString(fillChar));
 
3565
 
 
3566
    // restore clean state
 
3567
    testWidget->setEchoMode(QLineEdit::Normal);
 
3568
}
 
3569
 
 
3570
void tst_QLineEdit::task248948_redoRemovedSelection()
 
3571
{
 
3572
    testWidget->setText("a");
 
3573
    testWidget->selectAll();
 
3574
    QTest::keyPress(testWidget, Qt::Key_Delete);
 
3575
    testWidget->undo();
 
3576
    testWidget->redo();
 
3577
    QTest::keyPress(testWidget, 'a');
 
3578
    QTest::keyPress(testWidget, 'b');
 
3579
    QCOMPARE(testWidget->text(), QLatin1String("ab"));
 
3580
}
 
3581
 
 
3582
void tst_QLineEdit::taskQTBUG_4401_enterKeyClearsPassword()
 
3583
{
 
3584
    QString password("Wanna guess?");
 
3585
 
 
3586
    testWidget->setText(password);
 
3587
    testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
 
3588
    testWidget->setFocus();
 
3589
    testWidget->selectAll();
 
3590
    QApplication::setActiveWindow(testWidget);
 
3591
    QTRY_VERIFY(testWidget->hasFocus());
 
3592
 
 
3593
    QTest::keyPress(testWidget, Qt::Key_Enter);
 
3594
    QTRY_COMPARE(testWidget->text(), password);
 
3595
}
 
3596
 
 
3597
void tst_QLineEdit::taskQTBUG_4679_moveToStartEndOfBlock()
 
3598
{
 
3599
#ifdef Q_OS_MAC
 
3600
    const QString text("there are no blocks for lineEdit");
 
3601
    testWidget->setText(text);
 
3602
    testWidget->setCursorPosition(5);
 
3603
    QCOMPARE(testWidget->cursorPosition(), 5);
 
3604
    testWidget->setFocus();
 
3605
    QTest::keyPress(testWidget, Qt::Key_A, Qt::MetaModifier);
 
3606
    QCOMPARE(testWidget->cursorPosition(), 0);
 
3607
    QTest::keyPress(testWidget, Qt::Key_E, Qt::MetaModifier);
 
3608
    QCOMPARE(testWidget->cursorPosition(), text.size());
 
3609
#endif // Q_OS_MAC
 
3610
}
 
3611
 
 
3612
void tst_QLineEdit::taskQTBUG_4679_selectToStartEndOfBlock()
 
3613
{
 
3614
#ifdef Q_OS_MAC
 
3615
    const QString text("there are no blocks for lineEdit, select all");
 
3616
    testWidget->setText(text);
 
3617
    testWidget->setCursorPosition(5);
 
3618
    QCOMPARE(testWidget->cursorPosition(), 5);
 
3619
    testWidget->setFocus();
 
3620
    QTest::keyPress(testWidget, Qt::Key_A, Qt::MetaModifier | Qt::ShiftModifier);
 
3621
    QCOMPARE(testWidget->cursorPosition(), 0);
 
3622
    QVERIFY(testWidget->hasSelectedText());
 
3623
    QCOMPARE(testWidget->selectedText(), text.mid(0, 5));
 
3624
 
 
3625
    QTest::keyPress(testWidget, Qt::Key_E, Qt::MetaModifier | Qt::ShiftModifier);
 
3626
    QCOMPARE(testWidget->cursorPosition(), text.size());
 
3627
    QVERIFY(testWidget->hasSelectedText());
 
3628
    QCOMPARE(testWidget->selectedText(), text.mid(5));
 
3629
#endif // Q_OS_MAC
 
3630
}
 
3631
 
 
3632
#ifndef QT_NO_CONTEXTMENU
 
3633
void tst_QLineEdit::taskQTBUG_7902_contextMenuCrash()
 
3634
{
 
3635
    // Would pass before the associated commit, but left as a guard.
 
3636
    QLineEdit *w = new QLineEdit;
 
3637
    w->show();
 
3638
    QVERIFY(QTest::qWaitForWindowExposed(w));
 
3639
 
 
3640
    QTimer ti;
 
3641
    w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
 
3642
    ti.start(200);
 
3643
 
 
3644
    QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
 
3645
    qApp->postEvent(w, cme);
 
3646
 
 
3647
    QTest::qWait(300);
 
3648
    // No crash, it's allright.
 
3649
}
 
3650
#endif
 
3651
 
 
3652
void tst_QLineEdit::taskQTBUG_7395_readOnlyShortcut()
 
3653
{
 
3654
    //ReadOnly QLineEdit should not intercept shortcut.
 
3655
    QLineEdit le;
 
3656
    le.setReadOnly(true);
 
3657
 
 
3658
    QAction action(QString::fromLatin1("hello"), &le);
 
3659
    action.setShortcut(QString::fromLatin1("p"));
 
3660
    QSignalSpy spy(&action, SIGNAL(triggered()));
 
3661
    le.addAction(&action);
 
3662
 
 
3663
    le.show();
 
3664
    QVERIFY(QTest::qWaitForWindowExposed(&le));
 
3665
    QApplication::setActiveWindow(&le);
 
3666
    QVERIFY(QTest::qWaitForWindowActive(&le));
 
3667
    le.setFocus();
 
3668
    QTRY_VERIFY(le.hasFocus());
 
3669
 
 
3670
    QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_P);
 
3671
    QCOMPARE(spy.count(), 1);
 
3672
}
 
3673
 
 
3674
void tst_QLineEdit::QTBUG697_paletteCurrentColorGroup()
 
3675
{
 
3676
    if (m_keyboardScheme != QPlatformTheme::X11KeyboardScheme)
 
3677
        QSKIP("Only tested on X11");
 
3678
    QLineEdit le;
 
3679
    le.setText("               ");
 
3680
    QPalette p = le.palette();
 
3681
    p.setBrush(QPalette::Active, QPalette::Highlight, Qt::green);
 
3682
    p.setBrush(QPalette::Inactive, QPalette::Highlight, Qt::red);
 
3683
    le.setPalette(p);
 
3684
 
 
3685
    le.show();
 
3686
    QApplication::setActiveWindow(&le);
 
3687
    QVERIFY(QTest::qWaitForWindowActive(&le));
 
3688
    le.setFocus();
 
3689
    QTRY_VERIFY(le.hasFocus());
 
3690
    le.selectAll();
 
3691
 
 
3692
    QImage img(le.size(),QImage::Format_ARGB32 );
 
3693
    le.render(&img);
 
3694
    QCOMPARE(img.pixel(10, le.height()/2), QColor(Qt::green).rgb());
 
3695
    QApplication::setActiveWindow(0);
 
3696
    le.render(&img);
 
3697
    QCOMPARE(img.pixel(10, le.height()/2), QColor(Qt::red).rgb());
 
3698
}
 
3699
 
 
3700
void tst_QLineEdit::QTBUG13520_textNotVisible()
 
3701
{
 
3702
    LineEdit le;
 
3703
    le.setAlignment( Qt::AlignRight | Qt::AlignVCenter);
 
3704
    le.show();
 
3705
    QVERIFY(QTest::qWaitForWindowExposed(&le));
 
3706
    le.setText("01-ST16-01SIL-MPL001wfgsdfgsdgsdfgsdfgsdfgsdfgsdfg");
 
3707
    le.setCursorPosition(0);
 
3708
    QTest::qWait(100); //just make sure we get he lineedit correcly painted
 
3709
 
 
3710
    QVERIFY(le.cursorRect().center().x() < le.width() / 2);
 
3711
 
 
3712
 
 
3713
}
 
3714
 
 
3715
class UpdateRegionLineEdit : public QLineEdit
 
3716
{
 
3717
public:
 
3718
    QRegion updateRegion;
 
3719
protected:
 
3720
    void paintEvent(QPaintEvent *event)
 
3721
    {
 
3722
        updateRegion = event->region();
 
3723
    }
 
3724
};
 
3725
 
 
3726
void tst_QLineEdit::QTBUG7174_inputMaskCursorBlink()
 
3727
{
 
3728
    UpdateRegionLineEdit edit;
 
3729
    edit.setInputMask(QLatin1String("AAAA"));
 
3730
    edit.setFocus();
 
3731
    edit.setText(QLatin1String("AAAA"));
 
3732
    edit.show();
 
3733
    QRect cursorRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
 
3734
    QVERIFY(QTest::qWaitForWindowExposed(&edit));
 
3735
    edit.updateRegion = QRegion();
 
3736
    QTest::qWait(QApplication::cursorFlashTime());
 
3737
    QVERIFY(edit.updateRegion.contains(cursorRect));
 
3738
}
 
3739
 
 
3740
void tst_QLineEdit::QTBUG16850_setSelection()
 
3741
{
 
3742
    QLineEdit le;
 
3743
    le.setInputMask("00:0");
 
3744
    le.setText("  1");
 
3745
    le.setSelection(3, 1);
 
3746
    QCOMPARE(le.selectionStart(), 3);
 
3747
    QCOMPARE(le.selectedText(), QString("1"));
 
3748
}
 
3749
 
 
3750
void tst_QLineEdit::bidiVisualMovement_data()
 
3751
{
 
3752
    QTest::addColumn<QString>("logical");
 
3753
    QTest::addColumn<int>("basicDir");
 
3754
    QTest::addColumn<IntList>("positionList");
 
3755
 
 
3756
    QTest::newRow("Latin text")
 
3757
        << QString::fromUtf8("abc")
 
3758
        << (int) QChar::DirL
 
3759
        << (IntList() << 0 << 1 << 2 << 3);
 
3760
    QTest::newRow("Hebrew text, one item")
 
3761
        << QString::fromUtf8("\327\220\327\221\327\222")
 
3762
        << (int) QChar::DirR
 
3763
        << (QList<int>() << 0 << 1 << 2 << 3);
 
3764
    QTest::newRow("Hebrew text after Latin text")
 
3765
        << QString::fromUtf8("abc\327\220\327\221\327\222")
 
3766
        << (int) QChar::DirL
 
3767
        << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
 
3768
    QTest::newRow("Latin text after Hebrew text")
 
3769
        << QString::fromUtf8("\327\220\327\221\327\222abc")
 
3770
        << (int) QChar::DirR
 
3771
        << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
 
3772
    QTest::newRow("LTR, 3 items")
 
3773
        << QString::fromUtf8("abc\327\220\327\221\327\222abc")
 
3774
        << (int) QChar::DirL
 
3775
        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
 
3776
    QTest::newRow("RTL, 3 items")
 
3777
        << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222")
 
3778
        << (int) QChar::DirR
 
3779
        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
 
3780
    QTest::newRow("LTR, 4 items")
 
3781
        << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222")
 
3782
        << (int) QChar::DirL
 
3783
        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
 
3784
    QTest::newRow("RTL, 4 items")
 
3785
        << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc")
 
3786
        << (int) QChar::DirR
 
3787
        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
 
3788
}
 
3789
 
 
3790
void tst_QLineEdit::bidiVisualMovement()
 
3791
{
 
3792
    QFETCH(QString, logical);
 
3793
    QFETCH(int,     basicDir);
 
3794
    QFETCH(IntList, positionList);
 
3795
 
 
3796
    QLineEdit le;
 
3797
    le.setText(logical);
 
3798
 
 
3799
    le.setCursorMoveStyle(Qt::VisualMoveStyle);
 
3800
    le.setCursorPosition(0);
 
3801
 
 
3802
    bool moved;
 
3803
    int i = 0, oldPos, newPos = 0;
 
3804
 
 
3805
    do {
 
3806
        oldPos = newPos;
 
3807
        QVERIFY(oldPos == positionList[i]);
 
3808
        if (basicDir == QChar::DirL) {
 
3809
            QTest::keyClick(&le, Qt::Key_Right);
 
3810
        } else
 
3811
            QTest::keyClick(&le, Qt::Key_Left);
 
3812
        newPos = le.cursorPosition();
 
3813
        moved = (oldPos != newPos);
 
3814
        i++;
 
3815
    } while (moved);
 
3816
 
 
3817
    QVERIFY(i == positionList.size());
 
3818
 
 
3819
    do {
 
3820
        i--;
 
3821
        oldPos = newPos;
 
3822
        QVERIFY(oldPos == positionList[i]);
 
3823
        if (basicDir == QChar::DirL) {
 
3824
            QTest::keyClick(&le, Qt::Key_Left);
 
3825
        } else
 
3826
        {
 
3827
            QTest::keyClick(&le, Qt::Key_Right);
 
3828
        }
 
3829
        newPos = le.cursorPosition();
 
3830
        moved = (oldPos != newPos);
 
3831
    } while (moved && i >= 0);
 
3832
}
 
3833
 
 
3834
void tst_QLineEdit::bidiLogicalMovement_data()
 
3835
{
 
3836
    bidiVisualMovement_data();
 
3837
}
 
3838
 
 
3839
void tst_QLineEdit::bidiLogicalMovement()
 
3840
{
 
3841
    QFETCH(QString, logical);
 
3842
    QFETCH(int,     basicDir);
 
3843
 
 
3844
    QLineEdit le;
 
3845
    le.setText(logical);
 
3846
 
 
3847
    le.setCursorMoveStyle(Qt::LogicalMoveStyle);
 
3848
    le.setCursorPosition(0);
 
3849
 
 
3850
    bool moved;
 
3851
    int i = 0, oldPos, newPos = 0;
 
3852
 
 
3853
    do {
 
3854
        oldPos = newPos;
 
3855
        QVERIFY(oldPos == i);
 
3856
        if (basicDir == QChar::DirL) {
 
3857
            QTest::keyClick(&le, Qt::Key_Right);
 
3858
        } else
 
3859
            QTest::keyClick(&le, Qt::Key_Left);
 
3860
        newPos = le.cursorPosition();
 
3861
        moved = (oldPos != newPos);
 
3862
        i++;
 
3863
    } while (moved);
 
3864
 
 
3865
    do {
 
3866
        i--;
 
3867
        oldPos = newPos;
 
3868
        QVERIFY(oldPos == i);
 
3869
        if (basicDir == QChar::DirL) {
 
3870
            QTest::keyClick(&le, Qt::Key_Left);
 
3871
        } else
 
3872
        {
 
3873
            QTest::keyClick(&le, Qt::Key_Right);
 
3874
        }
 
3875
        newPos = le.cursorPosition();
 
3876
        moved = (oldPos != newPos);
 
3877
    } while (moved && i >= 0);
 
3878
}
 
3879
 
 
3880
void tst_QLineEdit::selectAndCursorPosition()
 
3881
{
 
3882
    testWidget->setText("This is a long piece of text");
 
3883
 
 
3884
    testWidget->setSelection(0, 5);
 
3885
    QCOMPARE(testWidget->cursorPosition(), 5);
 
3886
    testWidget->setSelection(5, -5);
 
3887
    QCOMPARE(testWidget->cursorPosition(), 0);
 
3888
}
 
3889
 
 
3890
void tst_QLineEdit::inputMethod()
 
3891
{
 
3892
    // widget accepts input
 
3893
    QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
 
3894
    QApplication::sendEvent(testWidget, &queryEvent);
 
3895
    QCOMPARE(queryEvent.value(Qt::ImEnabled).toBool(), true);
 
3896
 
 
3897
    testWidget->setEnabled(false);
 
3898
    QApplication::sendEvent(testWidget, &queryEvent);
 
3899
    QCOMPARE(queryEvent.value(Qt::ImEnabled).toBool(), false);
 
3900
    testWidget->setEnabled(true);
 
3901
 
 
3902
    // removing focus allows input method to commit preedit
 
3903
    testWidget->setText("");
 
3904
    testWidget->activateWindow();
 
3905
    QTRY_VERIFY(testWidget->hasFocus());
 
3906
    QTRY_COMPARE(qApp->focusObject(), testWidget);
 
3907
 
 
3908
    m_platformInputContext.setCommitString("text");
 
3909
    m_platformInputContext.m_commitCallCount = 0;
 
3910
    QList<QInputMethodEvent::Attribute> attributes;
 
3911
    QInputMethodEvent preeditEvent("preedit text", attributes);
 
3912
    QApplication::sendEvent(testWidget, &preeditEvent);
 
3913
 
 
3914
    testWidget->clearFocus();
 
3915
    QCOMPARE(m_platformInputContext.m_commitCallCount, 1);
 
3916
    QCOMPARE(testWidget->text(), QString("text"));
 
3917
}
 
3918
 
 
3919
void tst_QLineEdit::inputMethodSelection()
 
3920
{
 
3921
    testWidget->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
 
3922
    testWidget->setSelection(0,0);
 
3923
    QSignalSpy selectionSpy(testWidget, SIGNAL(selectionChanged()));
 
3924
 
 
3925
    QCOMPARE(selectionSpy.count(), 0);
 
3926
    QCOMPARE(testWidget->selectionStart(), -1);
 
3927
 
 
3928
    testWidget->setSelection(0,5);
 
3929
 
 
3930
    QCOMPARE(selectionSpy.count(), 1);
 
3931
    QCOMPARE(testWidget->selectionStart(), 0);
 
3932
 
 
3933
    // selection gained
 
3934
    {
 
3935
        QList<QInputMethodEvent::Attribute> attributes;
 
3936
        attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 12, 5, QVariant());
 
3937
        QInputMethodEvent event("", attributes);
 
3938
        QApplication::sendEvent(testWidget, &event);
 
3939
    }
 
3940
 
 
3941
    QCOMPARE(selectionSpy.count(), 2);
 
3942
    QCOMPARE(testWidget->selectionStart(), 12);
 
3943
 
 
3944
    // selection removed
 
3945
    {
 
3946
        QList<QInputMethodEvent::Attribute> attributes;
 
3947
        attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
 
3948
        QInputMethodEvent event("", attributes);
 
3949
        QApplication::sendEvent(testWidget, &event);
 
3950
    }
 
3951
 
 
3952
    QCOMPARE(selectionSpy.count(), 3);
 
3953
}
 
3954
 
 
3955
Q_DECLARE_METATYPE(Qt::InputMethodHints)
 
3956
void tst_QLineEdit::inputMethodQueryImHints_data()
 
3957
{
 
3958
    QTest::addColumn<Qt::InputMethodHints>("hints");
 
3959
 
 
3960
    QTest::newRow("None") << static_cast<Qt::InputMethodHints>(Qt::ImhNone);
 
3961
    QTest::newRow("Password") << static_cast<Qt::InputMethodHints>(Qt::ImhHiddenText);
 
3962
    QTest::newRow("Normal") << static_cast<Qt::InputMethodHints>(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData);
 
3963
}
 
3964
 
 
3965
void tst_QLineEdit::inputMethodQueryImHints()
 
3966
{
 
3967
    QFETCH(Qt::InputMethodHints, hints);
 
3968
    testWidget->setInputMethodHints(hints);
 
3969
 
 
3970
    QVariant value = testWidget->inputMethodQuery(Qt::ImHints);
 
3971
    QCOMPARE(static_cast<Qt::InputMethodHints>(value.toInt()), hints);
 
3972
}
 
3973
 
 
3974
void tst_QLineEdit::undoRedoAndEchoModes_data()
 
3975
{
 
3976
    QTest::addColumn<int>("echoMode");
 
3977
    QTest::addColumn<QStringList>("input");
 
3978
    QTest::addColumn<QStringList>("expected");
 
3979
 
 
3980
    QStringList input(QList<QString>() << "aaa" << "bbb" << "ccc");
 
3981
 
 
3982
    QTest::newRow("Normal")
 
3983
        << (int) QLineEdit::Normal
 
3984
        << input
 
3985
        << QStringList(QList<QString>() << "aaa" << "ccc" << "");
 
3986
 
 
3987
    QTest::newRow("NoEcho")
 
3988
        << (int) QLineEdit::NoEcho
 
3989
        << input
 
3990
        << QStringList(QList<QString>() << "" << "" << "");
 
3991
 
 
3992
    QTest::newRow("Password")
 
3993
        << (int) QLineEdit::Password
 
3994
        << input
 
3995
        << QStringList(QList<QString>() << "" << "" << "");
 
3996
 
 
3997
    QTest::newRow("PasswordEchoOnEdit")
 
3998
        << (int) QLineEdit::PasswordEchoOnEdit
 
3999
        << input
 
4000
        << QStringList(QList<QString>() << "" << "" << "");
 
4001
}
 
4002
 
 
4003
void tst_QLineEdit::undoRedoAndEchoModes()
 
4004
{
 
4005
    QFETCH(int, echoMode);
 
4006
    QFETCH(QStringList, input);
 
4007
    QFETCH(QStringList, expected);
 
4008
 
 
4009
    // create some history for the QLineEdit
 
4010
    testWidget->clear();
 
4011
    testWidget->setEchoMode(QLineEdit::EchoMode(echoMode));
 
4012
    testWidget->insert(input.at(0));
 
4013
    testWidget->selectAll();
 
4014
    testWidget->backspace();
 
4015
    testWidget->insert(input.at(1));
 
4016
 
 
4017
    // test undo
 
4018
    QVERIFY(testWidget->isUndoAvailable());
 
4019
    testWidget->undo();
 
4020
    QCOMPARE(testWidget->text(), expected.at(0));
 
4021
    testWidget->insert(input.at(2));
 
4022
    testWidget->selectAll();
 
4023
    testWidget->backspace();
 
4024
    QCOMPARE(testWidget->isUndoAvailable(), echoMode == QLineEdit::Normal);
 
4025
    testWidget->undo();
 
4026
    QCOMPARE(testWidget->text(), expected.at(1));
 
4027
 
 
4028
    // test redo
 
4029
    QCOMPARE(testWidget->isRedoAvailable(), echoMode == QLineEdit::Normal);
 
4030
    testWidget->redo();
 
4031
    QCOMPARE(testWidget->text(), expected.at(2));
 
4032
    QVERIFY(!testWidget->isRedoAvailable());
 
4033
    testWidget->redo();
 
4034
    QCOMPARE(testWidget->text(), expected.at(2));
 
4035
}
 
4036
 
 
4037
QTEST_MAIN(tst_QLineEdit)
 
4038
#include "tst_qlineedit.moc"