1
/****************************************************************************
2
**
3
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the test suite of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#include <iostream>
43
44
#include <QtTest/QtTest>
45
46
47
#include <q3header.h>
48
#include <q3listview.h>
49
#include <qapplication.h>
50
#include <qlineedit.h>
51
#include <qpointer.h>
52
#include <qvector.h>
53
54
Q_DECLARE_METATYPE(QPoint)
55
56
QT_BEGIN_NAMESPACE
57
template<> struct QMetaTypeId<Q3ListView::StringComparisonMode>
58
{ enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
59
QT_END_NAMESPACE
60
61
62
//TESTED_CLASS=
63
//TESTED_FILES=
64
65
class tst_Q3ListView : public QObject
66
{
67
Q_OBJECT
68
69
public:
70
    tst_Q3ListView();
71
    virtual ~tst_Q3ListView();
72
73
74
public slots:
75
    void selectionChanged() { changed++; }
76
    void selectionChanged( Q3ListViewItem* ) { changedItem++; }
77
    void spacePressed( Q3ListViewItem *item ) { pressCount++; pressedItem = item; }
78
    void itemRenamed(Q3ListViewItem *item, int column);
79
    void itemRenamed(Q3ListViewItem *item, int column, const QString &text);
80
    void contextMenu(Q3ListViewItem *item, const QPoint &pos, int col);
81
    void doubleClicked(Q3ListViewItem *item) { doubleClickCount++; pressedItem = item; }
82
83
public slots:
84
    void initTestCase();
85
    void cleanupTestCase();
86
    void init();
87
    void cleanup();
88
private slots:
89
    void getSetCheck();
90
    void sortchild();
91
    void sortchild2(); // item -> item -> 3 items
92
    void sortchild3(); // item -> 3 items
93
    void takeItem_data();
94
    void takeItem();
95
    void selections_mouseClick_data();
96
    void selections_mouseClick();
97
    void isVisible();
98
    void itemRenaming();
99
    void removeColumn();
100
    void contextMenuRequested_data();
101
    void contextMenuRequested();
102
    void itemActivate();
103
    void findItem_data();
104
    void findItem();
105
    void spacePress_data();
106
    void spacePress();
107
    void adjustColumn();
108
    void mouseClickEvents();
109
    void mouseClickEvents_data();
110
111
private:
112
    QPoint itemCenter( Q3ListView* view, Q3ListViewItem* item, int column = 0);
113
    QPoint itemBelow( Q3ListView* view, Q3ListViewItem* item );
114
    QString selectionName( int );
115
    QString buttonName( int );
116
    QString keyName( Qt::KeyboardModifiers );
117
    void resetVariables();
118
119
private:
120
    Q3ListView*testWidget;
121
    int changed, changedItem;
122
123
    int pressCount;
124
    int doubleClickCount;
125
    Q3ListViewItem *pressedItem;
126
127
    bool itemRenamedSignalOneReceived, itemRenamedSignalTwoReceived;
128
    Q3ListViewItem *itemRenamedOne, *itemRenamedTwo;
129
    int columnRenamedOne, columnRenamedTwo;
130
    QString textRenamed;
131
132
    bool contextMenuRequestedSignalReceived;
133
    Q3ListViewItem *contextMenuRequestedItem;
134
    QPoint contextMenuRequestedPos;
135
    int contextMenuRequestedCol;
136
137
};
138
139
// Testing get/set functions
140
void tst_Q3ListView::getSetCheck()
141
{
142
    Q3ListView obj1;
143
    // SelectionMode Q3ListView::selectionMode()
144
    // void Q3ListView::setSelectionMode(SelectionMode)
145
    obj1.setSelectionMode(Q3ListView::SelectionMode(0));
146
    QCOMPARE(Q3ListView::SelectionMode(0), obj1.selectionMode());
147
    obj1.setSelectionMode(Q3ListView::SelectionMode(1));
148
    QCOMPARE(Q3ListView::SelectionMode(1), obj1.selectionMode());
149
150
    // int Q3ListView::sortColumn()
151
    // void Q3ListView::setSortColumn(int)
152
    obj1.setSortColumn(0);
153
    QCOMPARE(0, obj1.sortColumn());
154
    obj1.setSortColumn(INT_MIN);
155
    QCOMPARE(INT_MIN, obj1.sortColumn());
156
    obj1.setSortColumn(INT_MAX);
157
    QCOMPARE(INT_MAX, obj1.sortColumn());
158
159
    Q3CheckListItem obj2(&obj1, "Item1", Q3CheckListItem::CheckBox);
160
    obj2.setTristate(true);
161
    // ToggleState Q3CheckListItem::state()
162
    // void Q3CheckListItem::setState(ToggleState)
163
    obj2.setState(Q3CheckListItem::ToggleState(Q3CheckListItem::Off));
164
    QCOMPARE(Q3CheckListItem::ToggleState(Q3CheckListItem::Off), obj2.state());
165
    obj2.setState(Q3CheckListItem::ToggleState(Q3CheckListItem::NoChange));
166
    QCOMPARE(Q3CheckListItem::ToggleState(Q3CheckListItem::NoChange), obj2.state());
167
    obj2.setState(Q3CheckListItem::ToggleState(Q3CheckListItem::On));
168
    QCOMPARE(Q3CheckListItem::ToggleState(Q3CheckListItem::On), obj2.state());
169
}
170
171
typedef QList<int> IntList;
172
Q_DECLARE_METATYPE(IntList)
173
174
typedef QList<void*> ItemList;
175
Q_DECLARE_METATYPE(ItemList)
176
177
Q_DECLARE_METATYPE(Q3ListView::SelectionMode)
178
179
tst_Q3ListView::tst_Q3ListView()
180
{
181
}
182
183
tst_Q3ListView::~tst_Q3ListView()
184
{
185
186
}
187
188
void tst_Q3ListView::initTestCase()
189
{
190
    // Create the test class
191
}
192
193
void tst_Q3ListView::cleanupTestCase()
194
{
195
}
196
197
void tst_Q3ListView::init()
198
{
199
    testWidget = new Q3ListView(0,"testObject");
200
    testWidget->resize(200,200);
201
    testWidget->show();
202
    pressCount = 0;
203
    pressedItem = 0;
204
    connect( testWidget, SIGNAL( spacePressed( Q3ListViewItem* ) ),
205
	     this, SLOT( spacePressed( Q3ListViewItem* ) ) );
206
    itemRenamedSignalOneReceived = FALSE;
207
    itemRenamedSignalTwoReceived = FALSE;
208
    itemRenamedOne = 0;
209
    itemRenamedTwo = 0;
210
    columnRenamedOne = -1;
211
    columnRenamedTwo = -1;
212
    textRenamed = QString();
213
214
    contextMenuRequestedSignalReceived = FALSE;
215
    contextMenuRequestedItem = 0;
216
    contextMenuRequestedPos = QPoint();
217
    contextMenuRequestedCol = -1;
218
}
219
220
void tst_Q3ListView::cleanup()
221
{
222
    delete testWidget;
223
    testWidget = 0;
224
}
225
226
void tst_Q3ListView::sortchild()
227
{
228
    Q3ListView* listview = new Q3ListView( 0 );
229
230
    listview->addColumn( "" );
231
232
    Q3ListViewItem* item1 = new Q3ListViewItem( listview, "zzz" );
233
    Q3ListViewItem* item2 = new Q3ListViewItem( listview, "hhh" );
234
    Q3ListViewItem* item3 = new Q3ListViewItem( listview, "bbb" );
235
    Q3ListViewItem* item4 = new Q3ListViewItem( listview, "jjj" );
236
    Q3ListViewItem* item5 = new Q3ListViewItem( listview, "ddd" );
237
    Q3ListViewItem* item6 = new Q3ListViewItem( listview, "lll" );
238
239
    Q3ListViewItem* item3b = new Q3ListViewItem( item3, "234" );
240
    Q3ListViewItem* item3c = new Q3ListViewItem( item3, "345" );
241
    Q3ListViewItem* item3a = new Q3ListViewItem( item3, "123" );
242
243
    listview->setOpen( item3, TRUE );
244
245
    listview->setSorting( 0, TRUE );
246
    listview->show();
247
248
    Q3ListViewItem *item = listview->firstChild();
249
    QVERIFY( item == item3 );
250
    item = item->itemBelow();
251
    QVERIFY( item == item3a );
252
    item = item->itemBelow();
253
    QVERIFY( item == item3b );
254
    item = item->itemBelow();
255
    QVERIFY( item == item3c );
256
    item = item->itemBelow();
257
    QVERIFY( item == item5 );
258
    item = item->itemBelow();
259
    QVERIFY( item == item2 );
260
    item = item->itemBelow();
261
    QVERIFY( item == item4 );
262
    item = item->itemBelow();
263
    QVERIFY( item == item6 );
264
    item = item->itemBelow();
265
    QVERIFY( item == item1 );
266
267
    listview->setSorting( 0, FALSE );
268
    
269
    item = listview->firstChild();
270
    QVERIFY( item == item1 );
271
    item = item->itemBelow();
272
    QVERIFY( item == item6 );
273
    item = item->itemBelow();
274
    QVERIFY( item == item4 );
275
    item = item->itemBelow();
276
    QVERIFY( item == item2 );
277
    item = item->itemBelow();
278
    QVERIFY( item == item5 );
279
    item = item->itemBelow();
280
    QVERIFY( item == item3 );
281
    item = item->itemBelow();
282
    QVERIFY( item == item3c );
283
    item = item->itemBelow();
284
    QVERIFY( item == item3b );
285
    item = item->itemBelow();
286
    QVERIFY( item == item3a );
287
288
    item = listview->firstChild();
289
    item->moveItem( item->itemBelow() );
290
291
    listview->setSorting( 0, FALSE );
292
    QVERIFY( item == listview->firstChild() );
293
294
    delete listview;
295
}
296
297
void tst_Q3ListView::sortchild2()
298
{
299
    Q3ListView* listview = new Q3ListView( 0 );
300
301
    listview->addColumn( "" );
302
303
    Q3ListViewItem* item1 = new Q3ListViewItem( listview, "zzz" );
304
    Q3ListViewItem* item2 = new Q3ListViewItem( listview, "hhh" );
305
    Q3ListViewItem* item3 = new Q3ListViewItem( listview, "bbb" );
306
    Q3ListViewItem* item4 = new Q3ListViewItem( listview, "jjj" );
307
    Q3ListViewItem* item5 = new Q3ListViewItem( listview, "ddd" );
308
    Q3ListViewItem* item6 = new Q3ListViewItem( listview, "lll" );
309
310
    Q3ListViewItem* item31 = new Q3ListViewItem( item3, "bbb-level2" );
311
312
    Q3ListViewItem* item31b = new Q3ListViewItem( item31, "234" );
313
    Q3ListViewItem* item31c = new Q3ListViewItem( item31, "345" );
314
    Q3ListViewItem* item31a = new Q3ListViewItem( item31, "123" );
315
316
    listview->setOpen( item3, TRUE );
317
    listview->setOpen( item31, TRUE );
318
319
    listview->setSorting( 0, TRUE );
320
    listview->show();
321
322
    Q3ListViewItem *item = listview->firstChild();
323
    QVERIFY( item == item3 );
324
    item = item->itemBelow();
325
    QVERIFY( item == item31 );
326
    item = item->itemBelow();
327
    QVERIFY( item == item31a );
328
    item = item->itemBelow();
329
    QVERIFY( item == item31b );
330
    item = item->itemBelow();
331
    QVERIFY( item == item31c );
332
    item = item->itemBelow();
333
    QVERIFY( item == item5 );
334
    item = item->itemBelow();
335
    QVERIFY( item == item2 );
336
    item = item->itemBelow();
337
    QVERIFY( item == item4 );
338
    item = item->itemBelow();
339
    QVERIFY( item == item6 );
340
    item = item->itemBelow();
341
    QVERIFY( item == item1 );
342
343
    listview->setSorting( 0, FALSE );
344
345
    item = listview->firstChild();
346
    QVERIFY( item == item1 );
347
    item = item->itemBelow();
348
    QVERIFY( item == item6 );
349
    item = item->itemBelow();
350
    QVERIFY( item == item4 );
351
    item = item->itemBelow();
352
    QVERIFY( item == item2 );
353
    item = item->itemBelow();
354
    QVERIFY( item == item5 );
355
    item = item->itemBelow();
356
    QVERIFY( item == item3 );
357
    item = item->itemBelow();
358
    QVERIFY( item == item31 );
359
    item = item->itemBelow();
360
    QVERIFY( item == item31c );
361
    item = item->itemBelow();
362
    QVERIFY( item == item31b );
363
    item = item->itemBelow();
364
    QVERIFY( item == item31a );
365
366
    item = listview->firstChild();
367
    item->moveItem( item->itemBelow() );
368
369
    listview->setSorting( 0, FALSE );
370
    QVERIFY( item == listview->firstChild() );
371
372
    delete listview;
373
}
374
375
void tst_Q3ListView::sortchild3()
376
{
377
    Q3ListView* listview = new Q3ListView( 0 );
378
379
    listview->addColumn( "" );
380
381
    Q3ListViewItem* item3 = new Q3ListViewItem( listview, "bbb" );
382
383
384
    Q3ListViewItem* item31b = new Q3ListViewItem( item3, "234" );
385
    Q3ListViewItem* item31c = new Q3ListViewItem( item3, "345" );
386
    Q3ListViewItem* item31a = new Q3ListViewItem( item3, "123" );
387
388
    listview->setOpen( item3, TRUE );
389
390
    listview->setSorting( 0, TRUE );
391
    listview->show();
392
393
    Q3ListViewItem *item = listview->firstChild();
394
    QVERIFY( item == item3 );
395
    item = item->itemBelow();
396
    QVERIFY( item == item31a );
397
    item = item->itemBelow();
398
    QVERIFY( item == item31b );
399
    item = item->itemBelow();
400
    QVERIFY( item == item31c );
401
    item = item->itemBelow();
402
403
    listview->setSorting( 0, FALSE );
404
405
    item = listview->firstChild();
406
    QVERIFY( item == item3 );
407
    item = item->itemBelow();
408
    QVERIFY( item == item31c );
409
    item = item->itemBelow();
410
    QVERIFY( item == item31b );
411
    item = item->itemBelow();
412
    QVERIFY( item == item31a );
413
414
    delete listview;
415
}
416
417
418
void tst_Q3ListView::takeItem_data()
419
{
420
    QTest::addColumn<Q3ListView::SelectionMode>("selectionMode");
421
    QTest::addColumn<int>("selectItem");
422
    QTest::addColumn<int>("selectItemAfterTake");
423
424
    QTest::newRow( "SelectionMode::Single, item0 selected" ) << Q3ListView::Single
425
							  << 0
426
							  << -1;
427
    QTest::newRow( "SelectionMode::Single, item1 selected" ) << Q3ListView::Single
428
							  << 1
429
							  << -1;
430
    QTest::newRow( "SelectionMode::Single, item2 selected" ) << Q3ListView::Single
431
							  << 2
432
							  << 2;
433
434
    QTest::newRow( "SelectionMode::Multi, item0 selected" ) << Q3ListView::Multi
435
							  << 0
436
							  << -1;
437
    QTest::newRow( "SelectionMode::Multi, item1 selected" ) << Q3ListView::Multi
438
							  << 1
439
							  << -1;
440
    QTest::newRow( "SelectionMode::Multi, item2 selected" ) << Q3ListView::Multi
441
							  << 2
442
							  << 2;
443
444
    QTest::newRow( "SelectionMode::Extended, item0 selected" ) << Q3ListView::Extended
445
							  << 0
446
							  << -1;
447
    QTest::newRow( "SelectionMode::Extended, item1 selected" ) << Q3ListView::Extended
448
							  << 1
449
							  << -1;
450
    QTest::newRow( "SelectionMode::Extended, item2 selected" ) << Q3ListView::Extended
451
							  << 2
452
							  << 2;
453
}
454
455
void tst_Q3ListView::takeItem()
456
{
457
    testWidget->clear();
458
459
    QFETCH( Q3ListView::SelectionMode, selectionMode );
460
    QFETCH( int, selectItem );
461
    QFETCH( int, selectItemAfterTake );
462
463
    QVector<Q3ListViewItem*> items(3);
464
465
    // tree:
466
    // Item0
467
    //     Item1
468
    // Item2
469
    for ( int i=0; i<3; i++ ) {
470
	if ( i == 1 ) {
471
	    items.insert( i, new Q3ListViewItem( items.at( 0 ), QString("Item: %1").arg( i ) ) );
472
	} else
473
	    items.insert( i, new Q3ListViewItem( testWidget, QString("Item: %1").arg( i ) ) );
474
    }
475
476
    testWidget->setSelectionMode( selectionMode );
477
    testWidget->setSelected( items.at( selectItem ), TRUE );
478
479
    changed = 0;
480
    changedItem = 0;
481
    connect( testWidget, SIGNAL( selectionChanged() ),
482
	     this, SLOT( selectionChanged() ) );
483
    connect( testWidget, SIGNAL( selectionChanged( Q3ListViewItem* ) ),
484
	     this, SLOT( selectionChanged( Q3ListViewItem* ) ) );
485
486
    testWidget->takeItem( items.at( 0 ) );
487
488
    if ( selectionMode == Q3ListView::Single ) {
489
	Q3ListViewItem *item = selectItemAfterTake == -1 ? 0 : items.at( selectItemAfterTake );
490
	// verify that selectedItem have been properly updated after take
491
	QVERIFY( testWidget->selectedItem() == item );
492
	if ( selectItemAfterTake == -1 ) {
493
	    // verify that the selected taken item is unselected as well
494
	    QVERIFY( items.at( selectItem )->isSelected() == FALSE );
495
	    // verify that that taking the selectedItem (or parent of it) emits selectionChanged (but not selectionChanged( item )
496
	    QVERIFY( changed == 1 );
497
	    QVERIFY( changedItem == 0 );
498
	} else {
499
	    // verify that if we still have selection, no selectionChanged was emitted
500
	    QVERIFY( changed == 0 );
501
	    QVERIFY( changedItem == 0 );
502
	}
503
    } else {
504
	// verify for Multi and Extended that no selectionChanged is emitted
505
	QVERIFY( changed == 0 );
506
	QVERIFY( changedItem == 0 );
507
    }
508
509
    disconnect( testWidget, 0, this, 0 );
510
511
    delete items[0];
512
    delete items[2];
513
}
514
515
Qt::KeyboardModifiers intToKey( int stateKey )
516
{
517
    switch( stateKey )
518
    {
519
    case 0: return Qt::NoModifier;
520
    case 1: return Qt::ShiftModifier;
521
    case 2: return Qt::ControlModifier;
522
    case 3: return Qt::AltModifier;
523
    }
524
    return Qt::NoModifier;
525
}
526
527
void tst_Q3ListView::selections_mouseClick_data()
528
{
529
    QTest::addColumn<IntList>("selectedItems");
530
    QTest::addColumn<IntList>("clickItems");
531
    QTest::addColumn<IntList>("buttonList");
532
    QTest::addColumn<IntList>("keyList");
533
    QTest::addColumn<Q3ListView::SelectionMode>("selectionMode");
534
535
536
537
    for (int mode = Q3ListView::Single; mode <= Q3ListView::NoSelection; mode++ ) {
538
	for ( int button = Qt::LeftButton; button <= Qt::RightButton; button++ ) {
539
	    for ( int s = 0; s < 4; s++ ) {
540
                Qt::KeyboardModifiers key = intToKey( s );
541
		if ( key != Qt::AltModifier ) {
542
		    /* tests clicking on item0 with all different selection modes, buttons and statekeys (except Alt) */
543
		    IntList selectedItems;
544
		    IntList clickItems;
545
		    IntList buttonList;
546
		    IntList keyList;
547
548
		    if ( mode == Q3ListView::NoSelection ||
549
			 (button == Qt::RightButton && key == Qt::ControlModifier ) );
550
		    // don't expect any selections here
551
		    else
552
			selectedItems << 0;
553
		    clickItems << 0;
554
		    buttonList << button;
555
		    keyList << key;
556
		    QTest::newRow( "Clicking " + buttonName( button ) + " on item0 with "
557
				+ keyName( key ) + " in " + selectionName( mode ) )
558
				    << selectedItems
559
				    << clickItems
560
				    << buttonList
561
				    << keyList
562
				    << (Q3ListView::SelectionMode) mode;
563
		}
564
		if ( mode != Q3ListView::NoSelection && key == Qt::NoModifier ) {
565
		    /* tests selecting item0 and item1, then clicking outside the items to clear the selections */
566
		    IntList selectedItems;
567
		    IntList clickItems;
568
		    IntList buttonList;
569
		    IntList keyList;
570
571
		    clickItems << 0 << 1 << -1;
572
		    buttonList << Qt::LeftButton << Qt::LeftButton << button;
573
		    keyList << Qt::NoModifier << Qt::NoModifier <<  key;
574
575
                    QTest::newRow( "Selecting item0 and item1, then clicking "
576
				+ buttonName( button ) + " right of item0 with "
577
				+ keyName( key ) + " in " + selectionName( mode ) )
578
				    << selectedItems
579
				    << clickItems
580
				    << buttonList
581
				    << keyList
582
				    << (Q3ListView::SelectionMode) mode;
583
		}
584
		if ( mode != Q3ListView::NoSelection &&
585
		     button == Qt::RightButton &&
586
		     key == Qt::ControlModifier ) {
587
		    /* tests selecting item0, then selects item1 with RightButton+ControlKey, selection should stay the same */
588
		    IntList selectedItems;
589
		    IntList clickItems;
590
		    IntList buttonList;
591
		    IntList keyList;
592
593
		    selectedItems << 0;
594
		    clickItems << 0 << 1;
595
		    buttonList << Qt::LeftButton << button;
596
		    keyList << Qt::NoModifier << key;
597
598
                    QTest::newRow( "Selecting item0, then clicking "
599
				+ buttonName( button ) + " on item1 with "
600
				+ keyName( key ) + " in " + selectionName( mode ) )
601
				    << selectedItems
602
				    << clickItems
603
				    << buttonList
604
				    << keyList
605
				    << (Q3ListView::SelectionMode) mode;
606
		}
607
		if ( mode != Q3ListView::NoSelection &&
608
		     button == Qt::RightButton &&
609
		     key == Qt::ControlModifier ) {
610
		    /* tests selecting item0, then click right of item0 with RightButton+ControlKey, selection should stay the same */
611
		    IntList selectedItems;
612
		    IntList clickItems;
613
		    IntList buttonList;
614
		    IntList keyList;
615
616
		    selectedItems << 0;
617
		    clickItems << 0 << -1;
618
		    buttonList << Qt::LeftButton << button;
619
		    keyList << Qt::NoModifier << key;
620
621
                    QTest::newRow( "Selecting item0, then clicking "
622
				+ buttonName( button ) + " right of item0 with "
623
				+ keyName( key ) + " in " + selectionName( mode ) )
624
				    << selectedItems
625
				    << clickItems
626
				    << buttonList
627
				    << keyList
628
				    << (Q3ListView::SelectionMode) mode;
629
		}
630
	    }
631
	}
632
    }
633
}
634
635
void tst_Q3ListView::selections_mouseClick()
636
{
637
638
    QFETCH( IntList, selectedItems );
639
    QFETCH( IntList, clickItems );
640
    QFETCH( IntList, buttonList );
641
    QFETCH( IntList, keyList );
642
    QFETCH( Q3ListView::SelectionMode, selectionMode );
643
644
    QVERIFY( clickItems.count() == buttonList.count() &&
645
	    buttonList.count() == keyList.count() );
646
647
    Q3ListView listView( 0 );
648
649
    listView.setSelectionMode( selectionMode );
650
    listView.addColumn( "First" );
651
    listView.addColumn( "Second" );
652
653
    // tree:
654
    // Item0
655
    // Item1
656
    // Item2
657
    QVector<Q3ListViewItem*> items;
658
    int i;
659
    for (i = 0; i < 3; ++i) {
660
	items.append(new Q3ListViewItem( &listView, QString("Item: %1").arg( i ) ));
661
    }
662
    listView.setSorting( 0, TRUE );
663
    listView.show();
664
665
    for ( i=0; i<(int)clickItems.count(); i++ ) {
666
	// find point to click, -1 means outside any item
667
	QPoint clickPoint = (clickItems[ i ] == -1) ?
668
			    itemBelow( &listView, items[ 2 ] ) :
669
			    itemCenter( &listView, items[ clickItems[i] ] );
670
	// send the mouse click event
671
	QTest::mouseClick( listView.viewport(), (Qt::MouseButton)buttonList.at(i),
672
		    (Qt::KeyboardModifier) keyList.at(i),
673
		    clickPoint );
674
    }
675
676
//     while ( listView.isVisible() )
677
//	qApp->processEvents();
678
679
    for (i = 0; i < items.count(); ++i) {
680
	Q3ListViewItem *item = items.at(i);
681
        Q_ASSERT(item);
682
	if ( item->isSelected() ) {
683
	    QVERIFY( selectedItems.contains( i ) );
684
	} else {
685
	    QVERIFY( !selectedItems.contains( i ) );
686
	}
687
    }
688
}
689
690
QPoint tst_Q3ListView::itemCenter( Q3ListView* view, Q3ListViewItem* item, int )
691
{
692
    if ( view && item )
693
	return QPoint( view->itemRect( item ).x() + 10, view->itemRect( item ).center().y() );
694
    return QPoint();
695
}
696
697
QPoint tst_Q3ListView::itemBelow( Q3ListView* view, Q3ListViewItem* item )
698
{
699
    if ( view && item ) {
700
	QRect i = view->itemRect( item );
701
	return QPoint( i.center().x(), i.bottom()+10 );
702
    }
703
    return QPoint();
704
}
705
706
707
QString tst_Q3ListView::selectionName( int selectionMode )
708
{
709
    switch ( selectionMode ) {
710
    case Q3ListView::Single:
711
	return "Single";
712
    case Q3ListView::Multi:
713
	return "Multi";
714
    case Q3ListView::Extended:
715
	return "Extended";
716
    case Q3ListView::NoSelection:
717
	return "NoSelection";
718
    default:
719
	return "Unknown SelectionMode";
720
    }
721
}
722
723
QString tst_Q3ListView::buttonName( int mouseButton )
724
{
725
    switch ( mouseButton ) {
726
    case Qt::LeftButton:
727
	return "LeftButton";
728
    case Qt::MidButton:
729
	return "MidButton";
730
    case Qt::RightButton:
731
	return "RightButton";
732
    default:
733
	return "Unknown button";
734
    }
735
}
736
737
QString tst_Q3ListView::keyName( Qt::KeyboardModifiers stateKey )
738
{
739
    switch ( stateKey ) {
740
    case Qt::NoModifier:
741
	return "NoKey";
742
    case Qt::ShiftModifier:
743
	return "ShiftKey";
744
    case Qt::ControlModifier:
745
	return "ControlKey";
746
    case Qt::AltModifier:
747
	return "AltKey";
748
    default:
749
	return "Unknown key";
750
    }
751
}
752
753
void tst_Q3ListView::isVisible()
754
{
755
    Q3ListView listview( 0 );
756
    Q3ListViewItem* tlOne = new Q3ListViewItem( &listview, "Item One" );
757
    Q3ListViewItem* tlTwo = new Q3ListViewItem( &listview, "Item Two" );
758
    Q3ListViewItem* tlThree = new Q3ListViewItem( &listview, "Item Three" );
759
760
    Q3ListViewItem* tlTwoCOne = new Q3ListViewItem( tlTwo, "Child One of Item Two" );
761
    Q3ListViewItem* tlTwoCTwo = new Q3ListViewItem( tlTwo, "Child Two of Item Two" );
762
    Q3ListViewItem* tlTwoCThree = new Q3ListViewItem( tlTwo, "Child Three of Item Two" );
763
764
    Q3ListViewItem* tlTwoCTwoCOne = new Q3ListViewItem( tlTwoCTwo, "Child One of Child Two of Item Two" );
765
    Q3ListViewItem* tlTwoCTwoCTwo = new Q3ListViewItem( tlTwoCTwo, "Child Two of Child Two of Item Two" );
766
    Q3ListViewItem* tlTwoCTwoCThree = new Q3ListViewItem( tlTwoCTwo, "Child Three of Child Two of Item Two" );
767
    Q_UNUSED(tlTwoCTwoCThree);
768
    Q_UNUSED(tlTwoCTwoCOne);
769
    Q_UNUSED(tlTwoCThree);
770
    Q_UNUSED(tlThree);
771
772
    listview.show();
773
    tlOne->setVisible( FALSE );
774
775
    QVERIFY( !tlOne->isVisible() );
776
    QVERIFY( tlTwo->isVisible() );
777
    QVERIFY( tlTwoCOne->isVisible() );
778
    QVERIFY( tlTwoCTwoCTwo->isVisible() );
779
780
    tlTwo->setVisible( FALSE );
781
    QVERIFY( !tlTwo->isVisible() );
782
    QVERIFY( !tlTwoCOne->isVisible() );
783
    QVERIFY( !tlTwoCTwoCTwo->isVisible() );
784
785
    tlTwoCTwoCTwo->setVisible( TRUE );
786
    QVERIFY( !tlTwo->isVisible() );
787
    QVERIFY( !tlTwoCOne->isVisible() );
788
    QVERIFY( !tlTwoCTwoCTwo->isVisible() );
789
790
    tlTwo->setVisible( TRUE );
791
    QVERIFY( tlTwo->isVisible() );
792
    QVERIFY( tlTwoCOne->isVisible() );
793
    QVERIFY( tlTwoCTwoCTwo->isVisible() );
794
}
795
796
void tst_Q3ListView::itemRenamed(Q3ListViewItem *item, int column, const QString &text)
797
{
798
    itemRenamedOne = item;
799
    columnRenamedOne = column;
800
    textRenamed = text;
801
    itemRenamedSignalOneReceived = TRUE;
802
}
803
804
void tst_Q3ListView::itemRenamed(Q3ListViewItem *item, int column)
805
{
806
    itemRenamedTwo = item;
807
    columnRenamedTwo = column;
808
    itemRenamedSignalTwoReceived = TRUE;
809
}
810
811
void tst_Q3ListView::resetVariables()
812
{
813
    itemRenamedSignalOneReceived = FALSE;
814
    itemRenamedSignalTwoReceived = FALSE;
815
    itemRenamedOne = 0;
816
    itemRenamedTwo = 0;
817
    columnRenamedOne = -1;
818
    columnRenamedTwo = -1;
819
    textRenamed = QString();
820
}
821
822
void tst_Q3ListView::itemRenaming()
823
{
824
    int a;
825
826
    testWidget->clear();
827
    connect(testWidget, SIGNAL(itemRenamed(Q3ListViewItem *, int, const QString &)),
828
	    this, SLOT(itemRenamed(Q3ListViewItem *, int, const QString &)));
829
    connect(testWidget, SIGNAL(itemRenamed(Q3ListViewItem *, int)),
830
	    this, SLOT(itemRenamed(Q3ListViewItem *, int)));
831
832
    Q3ListViewItem *itemOne = new Q3ListViewItem(testWidget, "A - Rename Me One", "Rename Me One Col One");
833
    Q3ListViewItem *itemTwo = new Q3ListViewItem(testWidget, "B - Rename Me Two", "Rename Me Two Col One");
834
    Q3ListViewItem *itemThree = new Q3ListViewItem(testWidget, "C - Rename Me Three", "Rename Me Three Col One");
835
836
    QVERIFY(!itemOne->renameEnabled(0));
837
    QVERIFY(!itemOne->renameEnabled(1));
838
    for (a = 0;a < 2;a++) {
839
	itemOne->setRenameEnabled(a,TRUE);
840
	itemTwo->setRenameEnabled(a,TRUE);
841
	itemThree->setRenameEnabled(a,TRUE);
842
    }
843
    QVERIFY(itemOne->renameEnabled(0));
844
    QVERIFY(itemOne->renameEnabled(1));
845
846
    // Check if programatic renaming works
847
848
    itemOne->startRename(0);
849
    QLineEdit *renameBox = qFindChild<QLineEdit*>(testWidget->viewport(), "qt_renamebox");
850
    QVERIFY(renameBox);
851
    QVERIFY(renameBox->isVisible());
852
    QTest::keyClick(renameBox, Qt::Key_R);
853
    QTest::keyClick(renameBox, Qt::Key_E);
854
    QTest::keyClick(renameBox, Qt::Key_N);
855
    QTest::keyClick(renameBox, Qt::Key_A);
856
    QTest::keyClick(renameBox, Qt::Key_M);
857
    QTest::keyClick(renameBox, Qt::Key_E);
858
    QTest::keyClick(renameBox, Qt::Key_D);
859
    QTest::keyPress(renameBox, Qt::Key_Return);
860
861
    QVERIFY(itemRenamedSignalOneReceived);
862
    QVERIFY(itemRenamedOne == itemOne );
863
    QVERIFY(columnRenamedOne == 0);
864
    QVERIFY(textRenamed == "renamed");
865
    QVERIFY(itemRenamedSignalTwoReceived);
866
    QVERIFY(itemRenamedTwo == itemOne);
867
    QVERIFY(columnRenamedTwo == 0);
868
869
    QCOMPARE(itemOne->text(0), QString("renamed"));
870
    QCOMPARE(itemOne->text(1), QString("Rename Me One Col One"));
871
872
    resetVariables();
873
874
    itemOne->startRename(1);
875
    renameBox = (QLineEdit *)testWidget->viewport()->child("qt_renamebox", "QLineEdit");
876
    QVERIFY(renameBox);
877
    QVERIFY(renameBox->isVisible());
878
    QTest::keyClick(renameBox, Qt::Key_R);
879
    QTest::keyClick(renameBox, Qt::Key_E);
880
    QTest::keyClick(renameBox, Qt::Key_N);
881
    QTest::keyClick(renameBox, Qt::Key_A);
882
    QTest::keyClick(renameBox, Qt::Key_M);
883
    QTest::keyClick(renameBox, Qt::Key_E);
884
    QTest::keyClick(renameBox, Qt::Key_D);
885
    QTest::keyClick(renameBox, Qt::Key_Space);
886
    QTest::keyClick(renameBox, Qt::Key_C);
887
    QTest::keyClick(renameBox, Qt::Key_O);
888
    QTest::keyClick(renameBox, Qt::Key_L);
889
    QTest::keyClick(renameBox, Qt::Key_1);
890
    QTest::keyPress(renameBox, Qt::Key_Return);
891
    QCOMPARE(itemOne->text(0), QString("renamed"));
892
    QCOMPARE(itemOne->text(1), QString("renamed col1"));
893
894
    QVERIFY(itemRenamedSignalOneReceived);
895
    QVERIFY(itemRenamedOne == itemOne );
896
    QVERIFY(columnRenamedOne == 1);
897
    QVERIFY(textRenamed == "renamed col1");
898
    QVERIFY(itemRenamedSignalTwoReceived);
899
    QVERIFY(itemRenamedTwo == itemOne);
900
    QVERIFY(columnRenamedTwo == 1);
901
902
    // Check if renaming via keyboard works
903
    resetVariables();
904
905
    QTest::keyClick(testWidget->viewport(), Qt::Key_Space);
906
    QTest::keyClick(testWidget->viewport(), Qt::Key_Down);
907
    QVERIFY(testWidget->currentItem() == itemTwo);
908
    QTest::keyClick(testWidget->viewport(), Qt::Key_F2);
909
    renameBox = (QLineEdit *)testWidget->viewport()->child("qt_renamebox", "QLineEdit");
910
    QVERIFY(renameBox);
911
    QVERIFY(renameBox->isVisible());
912
    QTest::keyClick(renameBox, Qt::Key_R);
913
    QTest::keyClick(renameBox, Qt::Key_E);
914
    QTest::keyClick(renameBox, Qt::Key_N);
915
    QTest::keyClick(renameBox, Qt::Key_A);
916
    QTest::keyClick(renameBox, Qt::Key_M);
917
    QTest::keyClick(renameBox, Qt::Key_E);
918
    QTest::keyClick(renameBox, Qt::Key_D);
919
    QTest::keyClick(renameBox, Qt::Key_2);
920
    QTest::keyPress(renameBox, Qt::Key_Return);
921
922
    QVERIFY(itemRenamedSignalOneReceived);
923
    QVERIFY(itemRenamedOne == itemTwo);
924
    QVERIFY(columnRenamedOne == 0);
925
    QVERIFY(textRenamed == "renamed2");
926
    QVERIFY(itemRenamedSignalTwoReceived);
927
    QVERIFY(itemRenamedTwo == itemTwo);
928
    QVERIFY(columnRenamedTwo == 0);
929
930
    QCOMPARE(itemTwo->text(0), QString("renamed2"));
931
    QCOMPARE(itemTwo->text(1), QString("Rename Me Two Col One"));
932
933
    resetVariables();
934
#if 0
935
    // Check if renaming via mouse works
936
    QPoint itemPos;
937
    itemPos.setX(testWidget->header()->sectionPos(0) + 5);
938
    itemPos.setY(itemThree->itemPos() + 5);
939
    qDebug("%d-%d",itemPos.x(),itemPos.y());
940
    QTest::mousePress(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier, itemPos);
941
942
    // Should be enough to wait for a release
943
    for (a = 0;a < 100; a++)
944
	qApp->processEvents();
945
946
    QTest::mouseRelease(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier, itemPos);
947
948
    renameBox = (QLineEdit *)testWidget->viewport()->child("qt_renamebox", "QLineEdit");
949
    QVERIFY(renameBox);
950
    QVERIFY(renameBox->isVisible());
951
    QTest::keyClick(renameBox, Qt::Key_R);
952
    QTest::keyClick(renameBox, Qt::Key_E);
953
    QTest::keyClick(renameBox, Qt::Key_N);
954
    QTest::keyClick(renameBox, Qt::Key_A);
955
    QTest::keyClick(renameBox, Qt::Key_M);
956
    QTest::keyClick(renameBox, Qt::Key_E);
957
    QTest::keyClick(renameBox, Qt::Key_D);
958
    QTest::keyClick(renameBox, Qt::Key_3);
959
    QTest::keyClick(renameBox, Qt::Key_Return);
960
961
    QVERIFY(itemRenamedSignalOneReceived);
962
    QVERIFY(itemRenamedOne == itemThree);
963
    QVERIFY(columnRenamedOne == 0);
964
    QVERIFY(textRenamed == "renamed3");
965
    QVERIFY(itemRenamedSignalTwoReceived);
966
    QVERIFY(itemRenamedTwo == itemThree);
967
    QVERIFY(columnRenamedTwo == 0);
968
969
    QCOMPARE(itemOne->text(0), QString("renamed3"));
970
    QCOMPARE(itemOne->text(1), QString("Rename Me Three Col One"));
971
972
    resetVariables();
973
974
    itemPos.setX(testWidget->header()->sectionPos(1) + 5);
975
    itemPos.setY(itemThree->itemPos() + 5);
976
    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier, itemPos);
977
978
    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier, itemPos);
979
    renameBox = (QLineEdit *)testWidget->viewport()->child("qt_renamebox", "QLineEdit");
980
    QVERIFY(renameBox);
981
    QVERIFY(renameBox->isVisible());
982
    QTest::keyClick(renameBox, Qt::Key_R);
983
    QTest::keyClick(renameBox, Qt::Key_E);
984
    QTest::keyClick(renameBox, Qt::Key_N);
985
    QTest::keyClick(renameBox, Qt::Key_A);
986
    QTest::keyClick(renameBox, Qt::Key_M);
987
    QTest::keyClick(renameBox, Qt::Key_E);
988
    QTest::keyClick(renameBox, Qt::Key_D);
989
    QTest::keyClick(renameBox, Qt::Key_3);
990
    QTest::keyClick(renameBox, Qt::Key_Space);
991
    QTest::keyClick(renameBox, Qt::Key_C);
992
    QTest::keyClick(renameBox, Qt::Key_O);
993
    QTest::keyClick(renameBox, Qt::Key_L);
994
    QTest::keyClick(renameBox, Qt::Key_1);
995
    QTest::keyClick(renameBox, Qt::Key_Return);
996
    QCOMPARE(itemThree->text(0), QString("renamed3"));
997
    QCOMPARE(itemThree->text(1), QString("renamed3 col1"));
998
999
    QVERIFY(itemRenamedSignalOneReceived);
1000
    QVERIFY(itemRenamedOne == itemThree);
1001
    QVERIFY(columnRenamedOne == 1);
1002
    QVERIFY(textRenamed == "renamed3 col1");
1003
    QVERIFY(itemRenamedSignalTwoReceived);
1004
    QVERIFY(itemRenamedTwo == itemThree);
1005
    QVERIFY(columnRenamedTwo == 1);
1006
#endif
1007
}
1008
1009
void tst_Q3ListView::removeColumn()
1010
{
1011
    // clear all items and columns
1012
    while ( testWidget->columns() )
1013
	testWidget->removeColumn( 0 );
1014
    testWidget->clear();
1015
    QVERIFY( !testWidget->firstChild() );
1016
    QVERIFY( !testWidget->columns() );
1017
1018
    // add one column
1019
    // test columns() and header()->count()
1020
    testWidget->addColumn( "One" );
1021
    QCOMPARE( testWidget->columns(), 1 );
1022
    QCOMPARE( testWidget->header() ? testWidget->header()->count() : -1,
1023
	     testWidget->columns() );
1024
    // add a second column
1025
    testWidget->addColumn( "Two" );
1026
    QCOMPARE( testWidget->columns(), 2 );
1027
    QCOMPARE( testWidget->header() ? testWidget->header()->count() : -1,
1028
	     testWidget->columns() );
1029
    // add a third column
1030
    testWidget->addColumn( "Three" );
1031
    QCOMPARE( testWidget->columns(), 3 );
1032
    QCOMPARE( testWidget->header() ? testWidget->header()->count() : -1,
1033
	     testWidget->columns() );
1034
1035
    // actually remove
1036
    while ( testWidget->columns() ) {
1037
	testWidget->removeColumn( 0 );
1038
	// make sure header and q3listview always are in sync
1039
	QCOMPARE( testWidget->header() ? testWidget->header()->count() : -1,
1040
		 testWidget->columns() );
1041
    }
1042
1043
    // check that there are no columns
1044
    QVERIFY( !testWidget->columns() );
1045
    // check that there are no sections in the header
1046
    QVERIFY( testWidget->header() ? !testWidget->header()->count() : FALSE );
1047
}
1048
1049
void tst_Q3ListView::contextMenu(Q3ListViewItem *item, const QPoint &pos, int col)
1050
{
1051
    // Slot to gather information from the contextMenuRequested signal
1052
    contextMenuRequestedItem = item;
1053
    contextMenuRequestedPos = pos;
1054
    contextMenuRequestedCol = col;
1055
    contextMenuRequestedSignalReceived = TRUE;
1056
}
1057
1058
void tst_Q3ListView::contextMenuRequested_data()
1059
{
1060
    QTest::addColumn<bool>("mouse");
1061
    QTest::addColumn<QPoint>("clickPos");
1062
    QTest::addColumn<QString>("textOfListViewItem");
1063
    // QTest::addColumn<QPoint>("menuPos"); -- Need a way to reliably test this
1064
    QTest::addColumn<int>("column");
1065
1066
    QTest::newRow("mouseClickTopItemFirstColumn") << TRUE << QPoint(22, 5) /* << QPoint()*/ << QString("Item One") << 0;
1067
    QTest::newRow("keyClickTopItemFirstColumn") << FALSE << QPoint(22, 5) /* << QPoint()*/  << QString("Item One") << -1;
1068
    QTest::newRow("mouseClick2ndItemSecondColumn") << TRUE << QPoint(40, 20) /* << QPoint()*/  << QString("Item Two") << 0;
1069
    QTest::newRow("keyClick2ndItemSecondColumn") << FALSE << QPoint(40, 20) /* << QPoint()*/  << QString("Item One") << -1;
1070
    QTest::newRow("noItemClicked") << TRUE << QPoint(100, 100) /* << QPoint()*/  << QString() << -1;
1071
}
1072
1073
void tst_Q3ListView::contextMenuRequested()
1074
{
1075
    QFETCH(bool, mouse);
1076
    QFETCH(QPoint, clickPos);
1077
    QFETCH(QString, textOfListViewItem);
1078
    //QFETCH(QPoint, menuPos);
1079
    QFETCH(int, column);
1080
1081
    QSKIP("Does not work with qtestlib's mouse/keyboard handling.", SkipAll);
1082
1083
    testWidget->clear();
1084
    testWidget->addColumn("Column 1");
1085
    testWidget->addColumn("Column 2");
1086
    testWidget->connect(testWidget, SIGNAL(contextMenuRequested(Q3ListViewItem *, const QPoint &, int)),
1087
			this, SLOT(contextMenu(Q3ListViewItem *, const QPoint &, int)));
1088
1089
    testWidget->setColumnWidth(0, 35);
1090
    testWidget->setColumnWidth(1, 35);
1091
    Q3ListViewItem *itemOne = new Q3ListViewItem(testWidget, "Item One", "Item One 2");
1092
    Q3ListViewItem *itemTwo = new Q3ListViewItem(testWidget, itemOne, "Item Two", "Item Two 2");
1093
    Q_UNUSED(itemOne);
1094
    Q_UNUSED(itemTwo);
1095
1096
1097
    if (mouse) {
1098
	QTest::mouseClick(testWidget->viewport(), Qt::RightButton, Qt::NoModifier, clickPos);
1099
    } else {
1100
	// Then it's a keypress
1101
        QTest::mouseMove(testWidget->viewport(), clickPos);
1102
	QTest::keyClick(testWidget->viewport(), Qt::Key_Menu);
1103
    }
1104
1105
    QVERIFY(contextMenuRequestedSignalReceived);
1106
    if (textOfListViewItem.isNull()) {
1107
	QVERIFY(!contextMenuRequestedItem);
1108
    } else {
1109
	QCOMPARE(contextMenuRequestedItem->text(0), textOfListViewItem);
1110
    }
1111
    //QCOMPARE(contextMenuRequestedPos, menuPos);
1112
    QCOMPARE(contextMenuRequestedCol, column);
1113
}
1114
1115
// Exists solely for testing the activate() function
1116
class ActivateListViewItem : public Q3ListViewItem
1117
{
1118
public:
1119
    ActivateListViewItem(Q3ListView *parent) : Q3ListViewItem(parent),
1120
	activated(false) {}
1121
    bool activated;
1122
protected:
1123
    void activate()
1124
    {
1125
 	activated = true;
1126
    }
1127
};
1128
1129
void tst_Q3ListView::itemActivate()
1130
{
1131
    testWidget->addColumn("Test 1");
1132
    ActivateListViewItem *alvi = new ActivateListViewItem(testWidget);
1133
    alvi->setText(0, "Test");
1134
    new Q3ListViewItem(alvi, "Testing");
1135
    testWidget->setCurrentItem(alvi);
1136
    QTest::keyPress(testWidget->viewport(), Qt::Key_Space);
1137
    QVERIFY(alvi->activated);
1138
    QTest::keyRelease(testWidget->viewport(), Qt::Key_Space);
1139
1140
    alvi->activated = false;
1141
    QTest::mousePress(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5,alvi->itemPos()));
1142
    QVERIFY(alvi->activated);
1143
    QTest::mouseRelease(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5,alvi->itemPos()));
1144
    QVERIFY(alvi->activated);
1145
}
1146
1147
/*
1148
Qt::CaseSensitive - The strings must match case sensitively.
1149
Q3ListView::ExactMatch - The target and search strings must match exactly.
1150
Q3ListView::BeginsWith - The target string begins with the search string.
1151
Q3ListView::EndsWith - The target string ends with the search string.
1152
Q3ListView::Contains - The target string contains the search string.
1153
1154
the search criteria be applied in the following order: ExactMatch, BeginsWith, EndsWith, Contains
1155
*/
1156
1157
void tst_Q3ListView::findItem_data()
1158
{
1159
    QTest::addColumn<int>("indexOfCurrentItem");
1160
    QTest::addColumn<QString>("text");
1161
    QTest::addColumn<int>("column");
1162
    QTest::addColumn<int>("comparisonFlags");
1163
    QTest::addColumn<bool>("itemFound");
1164
    QTest::addColumn<QString>("textOfItemFound");
1165
1166
    QTest::newRow("noCurrentItem") << -1 << "item one" << 0 << 0 << TRUE << "Item One";
1167
    QTest::newRow("noCurrentItem-bogusColumn") << -1 << "item one" << 99 << 0 << FALSE << QString();
1168
    QTest::newRow("noCurrentItem-invalidItem") << -1 << "blah" << 0 << 0 << FALSE << QString();
1169
    QTest::newRow("noCurrentItem-caseSensitive-invalidItem") << -1 << "item one" << 0 << Q3ListView::CaseSensitive << FALSE << QString();
1170
    QTest::newRow("noCurrentItem-caseSensitive") << -1 << "Item One" << 0 << Q3ListView::CaseSensitive << TRUE << "Item One";
1171
    QTest::newRow("noCurrentItem-exactMatch-invalidItem") << -1 << "blah" << 0 << Q3ListView::ExactMatch << FALSE << QString();
1172
    QTest::newRow("noCurrentItem-exactMatch") << -1 << "Item One" << 0 << Q3ListView::ExactMatch << TRUE << "Item One";
1173
    QTest::newRow("noCurrentItem-beginsWith-invalidItem") << -1 << "blah" << 0 << Q3ListView::BeginsWith << FALSE << QString();
1174
    QTest::newRow("noCurrentItem-beginsWith") << -1 << "Item One" << 0 << Q3ListView::BeginsWith << TRUE << "Item One";
1175
    QTest::newRow("noCurrentItem-endsWith-invalidItem") << -1 << "blah" << 0 << Q3ListView::EndsWith << FALSE << QString();
1176
    QTest::newRow("noCurrentItem-endsWith") << -1 << "Item One" << 0 << Q3ListView::EndsWith << TRUE << "Item One";
1177
    QTest::newRow("noCurrentItem-contains-invalidItem") << -1 << "blah" << 0 << Q3ListView::Contains << FALSE << QString();
1178
    QTest::newRow("noCurrentItem-contains") << -1 << "Item One" << 0 << Q3ListView::Contains << TRUE << "Item One";
1179
1180
    // Now check that case sensitivity has no effect unless specified
1181
    QTest::newRow("noCurrentItem-exactMatch-nocs") << -1 << "ITEM ONE" << 0 << Q3ListView::ExactMatch << TRUE << "Item One";
1182
    QTest::newRow("noCurrentItem-beginsWith-nocs") << -1 << "ITEM ONE" << 0 << Q3ListView::BeginsWith << TRUE << "Item One";
1183
    QTest::newRow("noCurrentItem-endsWith-nocs") << -1 << "ITEM ONE" << 0 << Q3ListView::EndsWith << TRUE << "Item One";
1184
    QTest::newRow("noCurrentItem-contains-nocs") << -1 << "ITEM ONE" << 0 << Q3ListView::Contains << TRUE << "Item One";
1185
    QTest::newRow("noCurrentItem-exactMatch-cs") << -1 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::ExactMatch) << FALSE << QString();
1186
    QTest::newRow("noCurrentItem-beginsWith-cs") << -1 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::BeginsWith) << FALSE << QString();
1187
    QTest::newRow("noCurrentItem-endsWith-cs") << -1 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::EndsWith) << FALSE << QString();
1188
    QTest::newRow("noCurrentItem-contains-cs") << -1 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::Contains) << FALSE << QString();
1189
1190
    // Now check that the search criteria order is adhered to
1191
    QTest::newRow("noCurrentItem-exactMatch-beginswith-nocs") << -1 << "Item One" << 0 << (Q3ListView::ExactMatch | Q3ListView::BeginsWith) << TRUE << "Item One";
1192
    QTest::newRow("noCurrentItem-exactMatch-endswith-nocs") << -1 << "Item One" << 0 << (Q3ListView::ExactMatch | Q3ListView::EndsWith) << TRUE << "Item One";
1193
    QTest::newRow("noCurrentItem-exactMatch-contains-nocs") << -1 << "Item One" << 0 << (Q3ListView::ExactMatch | Q3ListView::Contains) << TRUE << "Item One";
1194
    QTest::newRow("noCurrentItem-beginswith-endswith-nocs") << -1 << "Item One" << 0 << (Q3ListView::BeginsWith | Q3ListView::EndsWith) << TRUE << "Item One";
1195
    QTest::newRow("noCurrentItem-beginswith-contains-nocs") << -1 << "Item One" << 0 << (Q3ListView::BeginsWith | Q3ListView::Contains) << TRUE << "Item One";
1196
    QTest::newRow("noCurrentItem-endswith-contains-nocs") << -1 << "Item One" << 0 << (Q3ListView::EndsWith | Q3ListView::Contains) << TRUE << "Item One";
1197
1198
    // Now check that the current item set has the effect of searching from that item
1199
    QTest::newRow("currentItemIsTwo") << 2 << "item one" << 0 << 0 << TRUE << "Item One";
1200
    QTest::newRow("currentItemIsTwo-bogusColumn") << 2 << "item one" << 99 << 0 << FALSE << QString();
1201
    QTest::newRow("currentItemIsTwo-invalidItem") << 2 << "blah" << 0 << 0 << FALSE << QString();
1202
    QTest::newRow("currentItemIsTwo-caseSensitive-invalidItem") << 2 << "item one" << 0 << Q3ListView::CaseSensitive << FALSE << QString();
1203
    QTest::newRow("currentItemIsTwo-caseSensitive") << 2 << "Item One" << 0 << Q3ListView::CaseSensitive << TRUE << "Item One";
1204
    QTest::newRow("currentItemIsTwo-exactMatch-invalidItem") << 2 << "blah" << 0 << Q3ListView::ExactMatch << FALSE << QString();
1205
    QTest::newRow("currentItemIsTwo-exactMatch") << 2 << "Item One" << 0 << Q3ListView::ExactMatch << TRUE << "Item One";
1206
    QTest::newRow("currentItemIsTwo-beginsWith-invalidItem") << 2 << "blah" << 0 << Q3ListView::BeginsWith << FALSE << QString();
1207
    QTest::newRow("currentItemIsTwo-beginsWith") << 2 << "Item One" << 0 << Q3ListView::BeginsWith << TRUE << "Item One Two Three";
1208
    QTest::newRow("currentItemIsTwo-endsWith-invalidItem") << 2 << "blah" << 0 << Q3ListView::EndsWith << FALSE << QString();
1209
    QTest::newRow("currentItemIsTwo-endsWith") << 2 << "Item One" << 0 << Q3ListView::EndsWith << TRUE << "Item One Item One";
1210
    QTest::newRow("currentItemIsTwo-contains-invalidItem") << 2 << "blah" << 0 << Q3ListView::Contains << FALSE << QString();
1211
    QTest::newRow("currentItemIsTwo-contains") << 2 << "Item One" << 0 << Q3ListView::Contains << TRUE << "Item One Two Three";
1212
    QTest::newRow("currentItemIsTwo-exactMatch-nocs") << 2 << "ITEM ONE" << 0 << Q3ListView::ExactMatch << TRUE << "Item One";
1213
    QTest::newRow("currentItemIsTwo-beginsWith-nocs") << 2 << "ITEM ONE" << 0 << Q3ListView::BeginsWith << TRUE << "Item One Two Three";
1214
    QTest::newRow("currentItemIsTwo-endsWith-nocs") << 2 << "ITEM ONE" << 0 << Q3ListView::EndsWith << TRUE << "Item One Item One";
1215
    QTest::newRow("currentItemIsTwo-contains-nocs") << 2 << "ITEM ONE" << 0 << Q3ListView::Contains << TRUE << "Item One Two Three";
1216
    QTest::newRow("currentItemIsTwo-exactMatch-cs") << 2 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::ExactMatch) << FALSE << QString();
1217
    QTest::newRow("currentItemIsTwo-beginsWith-cs") << 2 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::BeginsWith) << FALSE << QString();
1218
    QTest::newRow("currentItemIsTwo-endsWith-cs") << 2 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::EndsWith) << FALSE << QString();
1219
    QTest::newRow("currentItemIsTwo-contains-cs") << 2 << "ITEM ONE" << 0 << (Q3ListView::CaseSensitive | Q3ListView::Contains) << FALSE << QString();
1220
    QTest::newRow("currentItemIsTwo-exactMatch-beginswith-nocs") << 2 << "Item One" << 0 << (Q3ListView::ExactMatch | Q3ListView::BeginsWith) << TRUE << "Item One";
1221
    QTest::newRow("currentItemIsTwo-exactMatch-endswith-nocs") << 2 << "Item One" << 0 << (Q3ListView::ExactMatch | Q3ListView::EndsWith) << TRUE << "Item One";
1222
    QTest::newRow("currentItemIsTwo-exactMatch-contains-nocs") << 2 << "Item One" << 0 << (Q3ListView::ExactMatch | Q3ListView::Contains) << TRUE << "Item One";
1223
    QTest::newRow("currentItemIsTwo-beginswith-endswith-nocs") << 2 << "Item One" << 0 << (Q3ListView::BeginsWith | Q3ListView::EndsWith) << TRUE << "Item One Two Three";
1224
    QTest::newRow("currentItemIsTwo-beginswith-contains-nocs") << 2 << "Item One" << 0 << (Q3ListView::BeginsWith | Q3ListView::Contains) << TRUE << "Item One Two Three";
1225
    QTest::newRow("currentItemIsTwo-endswith-contains-nocs") << 2 << "Item One" << 0 << (Q3ListView::EndsWith | Q3ListView::Contains) << TRUE << "Item One Item One";
1226
    QTest::newRow("itemWithEmptyText") << 2 << "" << 0 << (Q3ListView::ExactMatch | Q3ListView::CaseSensitive) << TRUE << "";
1227
    QTest::newRow("itemWithEmptyText-2") << 2 << "" << 0 << (Q3ListView::BeginsWith | Q3ListView::Contains) << FALSE << "";
1228
}
1229
1230
void tst_Q3ListView::findItem()
1231
{
1232
    // ### This test is not complete, any results are still valid though
1233
1234
    QFETCH(int, indexOfCurrentItem);
1235
    QFETCH(QString, text);
1236
    QFETCH(int, column);
1237
    QFETCH(int, comparisonFlags);
1238
    QFETCH(bool, itemFound);
1239
    QFETCH(QString, textOfItemFound);
1240
1241
    testWidget->addColumn("Test");
1242
    testWidget->setSorting(-1);
1243
    Q3ListViewItem *itemOne = new Q3ListViewItem(testWidget, "Item One");
1244
    Q3ListViewItem *itemTwo = new Q3ListViewItem(testWidget, itemOne, "Item One Two");
1245
    Q3ListViewItem *itemThree = new Q3ListViewItem(testWidget, itemTwo, "Item One Two Three");
1246
    new Q3ListViewItem(testWidget, itemThree, "Item One Item One");
1247
    new Q3ListViewItem(testWidget, ""); // For the empty item test
1248
1249
    // We need some way of mapping items to indices
1250
    // and also a way to force no current item
1251
    // currently we assume item two is the current in the test
1252
    if (indexOfCurrentItem != -1)
1253
	testWidget->setCurrentItem(itemThree);
1254
1255
    Q3ListViewItem *foundItem = testWidget->findItem(text, column, QFlag(comparisonFlags));
1256
    if (itemFound) {
1257
	QVERIFY(foundItem);
1258
	QCOMPARE(textOfItemFound, foundItem->text(column));
1259
    } else {
1260
	QVERIFY(!foundItem);
1261
    }
1262
}
1263
1264
1265
void tst_Q3ListView::spacePress_data()
1266
{
1267
    QTest::addColumn<Q3ListView::SelectionMode>("selectionMode");
1268
    QTest::addColumn<int>("itemCount");
1269
    QTest::addColumn<int>("disabledItem");
1270
    QTest::addColumn<QTestEventList>("keys");
1271
    QTest::addColumn<int>("expectedCount");
1272
    QTest::addColumn<int>("expectedCurrentSelected");
1273
1274
    // testing space pressed on enabled/disabled item
1275
    for (int mode = Q3ListView::Single; mode <= Q3ListView::NoSelection; mode++ ) {
1276
	for (int k=0; k<4; ++k ) {
1277
            Qt::KeyboardModifiers key = intToKey( k );
1278
	    if ( key == Qt::NoModifier || key == Qt::ControlModifier ) {
1279
		for ( int enabled=0; enabled<2; ++enabled ) {
1280
		    QString testName = QString( "Space on %1 item. Selection mode: %2 Button: %3" )
1281
				       .arg( enabled ? "enabled" : "disabled" )
1282
				       .arg( selectionName( mode ))
1283
				       .arg( keyName( key ) );
1284
		    QTestEventList keys;
1285
		    // going to first item and pressing space
1286
		    keys.addKeyClick( Qt::Key_Home );
1287
		    keys.addKeyClick( Qt::Key_Space, key );
1288
		    QTest::newRow( testName ) << (Q3ListView::SelectionMode)mode << 9
1289
                                              << (enabled ? -1 : 0 ) << keys << 1
1290
                                              << ((mode == Q3ListView::Single) ||
1291
                                                  (mode == Q3ListView::Multi && !enabled) ? 1 : -1);
1292
		}
1293
	    }
1294
	}
1295
    }
1296
1297
    {
1298
	QTestEventList keys;
1299
	keys.addKeyClick( Qt::Key_Home );
1300
	keys.addKeyClick( Qt::Key_Down );
1301
	keys.addKeyClick( Qt::Key_Up );
1302
	keys.addKeyClick( Qt::Key_Space );
1303
	keys.addKeyClick( Qt::Key_Space, Qt::ControlModifier );
1304
	QTest::newRow( "Space then Ctrl-Space to unselect in Extended" )
1305
	    << Q3ListView::Extended << 9 << -1 << keys << 2 << 0;
1306
    }
1307
}
1308
1309
void tst_Q3ListView::spacePress()
1310
{
1311
    QFETCH( Q3ListView::SelectionMode, selectionMode );
1312
    QFETCH( int, itemCount );
1313
    QFETCH( int, disabledItem );
1314
    QFETCH( QTestEventList, keys );
1315
    QFETCH( int, expectedCount );
1316
    QFETCH( int, expectedCurrentSelected );
1317
1318
    testWidget->setSorting( 0, TRUE );
1319
    testWidget->addColumn( "Items" );
1320
    testWidget->setSelectionMode( selectionMode );
1321
    for ( int i=0; i<itemCount; ++i) {
1322
	Q3ListViewItem *item = new Q3ListViewItem( testWidget, QString( "Child %1" ).arg( i ) );
1323
	if ( i == disabledItem )
1324
	    item->setEnabled( FALSE );
1325
	if ( i == 0 )
1326
	    testWidget->setSelected( item, TRUE );
1327
    }
1328
1329
    // naviagate to keys and press space
1330
    pressCount = 0;
1331
    keys.simulate( testWidget );
1332
    // verify that spacePressed has been called the correct amount of times
1333
    QCOMPARE( pressCount, expectedCount );
1334
    if ( testWidget->currentItem() && expectedCurrentSelected > -1 )
1335
	QCOMPARE( testWidget->currentItem()->isSelected(), (bool)expectedCurrentSelected );
1336
}
1337
1338
void tst_Q3ListView::adjustColumn()
1339
{
1340
    testWidget->adjustColumn(-1);
1341
    testWidget->adjustColumn(100);
1342
    testWidget->adjustColumn(0);
1343
    QVERIFY(true); // Just to check it did not crash
1344
}
1345
1346
typedef QPair<QByteArray, QVariant> PropertyItem;
1347
typedef QList<PropertyItem> PropertyItemList;
1348
Q_DECLARE_METATYPE(PropertyItemList)
1349
1350
void tst_Q3ListView::mouseClickEvents_data()
1351
{
1352
    QTest::addColumn<QStringList>("itemstrings");
1353
    QTest::addColumn<int>("expectedDoubleClickCount");
1354
    QTest::addColumn<PropertyItemList>("properties");
1355
1356
    QTest::newRow("doubleclick") << (QStringList() << "item 1" << "item 2")
1357
                                 << 2 << PropertyItemList();
1358
    QTest::newRow("doubleclick") << (QStringList() << "item 1" << "item 2")
1359
                                 << 0 << (PropertyItemList() << PropertyItem("enabled", false));
1360
1361
}
1362
1363
void tst_Q3ListView::mouseClickEvents()
1364
{
1365
    QFETCH(QStringList, itemstrings);
1366
    QFETCH(int, expectedDoubleClickCount);
1367
    QFETCH(PropertyItemList, properties);
1368
    
1369
    int i;
1370
    for (i = 0; i < properties.count(); ++i) {
1371
        testWidget->setProperty(properties.at(i).first.constData(), properties.at(i).second);
1372
    }
1373
1374
    doubleClickCount = 0;
1375
    pressedItem = 0;
1376
    connect( testWidget, SIGNAL( doubleClicked( Q3ListViewItem* ) ),
1377
	     this, SLOT( doubleClicked( Q3ListViewItem* ) ) );
1378
    testWidget->addColumn("Items");
1379
    QVector<Q3ListViewItem*> items;
1380
    for ( i=0; i<itemstrings.count(); ++i) {
1381
	Q3ListViewItem *item = new Q3ListViewItem( testWidget, itemstrings.at(i) );
1382
        items.append(item);
1383
    }
1384
    for ( i = 0; i < items.count(); ++i) {
1385
        int prevCount = doubleClickCount;
1386
        QTest::mouseDClick(testWidget->viewport(), Qt::LeftButton, 0, itemCenter(testWidget, items.at(i)));
1387
        if (doubleClickCount > prevCount) {
1388
            QCOMPARE(pressedItem, items.at(i));
1389
        } else {
1390
            QCOMPARE(pressedItem, (Q3ListViewItem*)0);
1391
        }
1392
    }
1393
    QCOMPARE(doubleClickCount, expectedDoubleClickCount);
1394
    disconnect( testWidget, SIGNAL( doubleClicked( Q3ListViewItem* ) ),
1395
	     this, SLOT( doubleClicked( Q3ListViewItem* ) ) );
1396
}
1397
1398
QTEST_MAIN(tst_Q3ListView)
1399
#include "tst_q3listview.moc"